admin
2025-02-25 30d8e227e8d823b6c38c3b9c90ac2df03b63befe
fanli/src/main/java/com/yeshi/fanli/service/impl/user/UserInfoExtraServiceImpl.java
@@ -1,901 +1,900 @@
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;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;
import javax.annotation.Resource;
import com.yeshi.fanli.dao.user.UserGoodsChannelConfigDao;
import com.yeshi.fanli.entity.SystemEnum;
import com.yeshi.fanli.entity.goods.UserGoodsChannelConfig;
import com.yeshi.fanli.util.*;
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.entity.wx.WeiXinUser;
import org.yeshi.utils.tencentcloud.COSManager;
import com.aliyun.openservices.ons.api.Message;
import com.yeshi.fanli.dao.mybatis.user.UserInfoExtraMapper;
import com.yeshi.fanli.dao.mybatis.user.UserRankRecordMapper;
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.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.order.CommonOrderCountService;
import com.yeshi.fanli.service.inter.user.ForbiddenUserIdentifyCodeService;
import com.yeshi.fanli.service.inter.user.UserAccountService;
import com.yeshi.fanli.service.inter.user.UserInfoExtraService;
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.service.manger.msg.RocketMQManager;
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.vo.user.UserInfoExtraVO;
import net.coobird.thumbnailator.Thumbnails;
import org.yeshi.utils.wx.WXAppLoginUtil;
@Service
public class UserInfoExtraServiceImpl implements UserInfoExtraService {
    @Resource
    private UserInfoExtraMapper userInfoExtraMapper;
    @Resource
    private UserRankRecordMapper userRankRecordMapper;
    @Resource
    private UserRankService userRankService;
    @Resource
    private CommonOrderCountService commonOrderCountService;
    @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
    private RocketMQManager rocketMQManager;
    @Override
    public UserInfoExtraVO getRankInfo(Long uid) throws UserInfoExtraException, Exception {
        UserInfoExtraVO extraVO = userInfoExtraMapper.getInfoExtraVOByUid(uid);
        if (extraVO == null) {
            throw new UserInfoExtraException(1, "用户附加信息不存在");
        }
        SystemEnum system = userInfoService.getUserSystem(uid);
        // 等级对照表
        String contrast = configService.getValue(ConfigKeyEnum.userRankContrast.getKey(), system);
        extraVO.setRankContrast(contrast);
        // 特别提醒
        String rankTip = configService.getValue(ConfigKeyEnum.userRankTip.getKey(), system);
        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) {
                case Constant.TYPE_REBATE:
                    rankMsg = "返利订单";
                    break;
                case Constant.TYPE_SHAER:
                    rankMsg = "分享订单";
                    break;
                case Constant.TYPE_INVITE:
                    rankMsg = "邀请订单";
                    break;
                default:
                    break;
            }
            List<Object> listMsg = new ArrayList<Object>();
            if (rankMsg != null) {
                String color_red = "#E5005C";
                String color_black = "#333333";
                Map<String, String> map1 = new HashMap<String, String>();
                map1.put("content", "上月");
                map1.put("color", color_black);
                listMsg.add(map1);
                Map<String, String> map2 = new HashMap<String, String>();
                map2.put("content", rankMsg);
                map2.put("color", color_red);
                listMsg.add(map2);
                Map<String, String> map3 = new HashMap<String, String>();
                map3.put("content", "达到了");
                map3.put("color", color_black);
                listMsg.add(map3);
                Map<String, String> map4 = new HashMap<String, String>();
                map4.put("content", rankOrderNum + "");
                map4.put("color", color_red);
                listMsg.add(map4);
                Map<String, String> map5 = new HashMap<String, String>();
                map5.put("content", "单");
                map5.put("color", color_black);
                listMsg.add(map5);
                extraVO.setGalaMsg(listMsg);
            }
        }
        return extraVO;
    }
    @Override
    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) {
            // 判断当月是否已更新
            Date rankUpdateTime = userInfoExtra.getRankUpdateTime();
            if (rankUpdateTime != null) {
                SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM");
                if (sdf.format(rankUpdateTime).equals(sdf.format(new Date()))) {
                    isupdateRank = false;
                }
            }
            extra.setId(userInfoExtra.getId());
        } else {
            extra.setUserInfo(new UserInfo(uid));
        }
        // 更新等级
        if (isupdateRank) {
            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 {
        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 saveUserInfoExtra(UserInfoExtra userInfoExtra) throws UserInfoExtraException {
        if (userInfoExtra == null) {
            throw new UserInfoExtraException(1, "附加信息不能为空");
        }
        Long extraId = userInfoExtra.getId();
        if (extraId != null) {
            userInfoExtra.setUpdateTime(new Date());
            userInfoExtraMapper.updateByPrimaryKeySelective(userInfoExtra);
        } else {
            UserInfo userInfo = userInfoExtra.getUserInfo();
            if (userInfo == null || userInfo.getId() == null) {
                throw new UserInfoExtraException(1, "用户不存在");
            }
            Long uid = userInfo.getId();
            UserInfoExtra extra = userInfoExtraMapper.getInfoExtraByUid(uid);
            if (extra != null && extra.getId() != null) {
                userInfoExtra.setId(extra.getId());
                userInfoExtra.setUpdateTime(new Date());
                userInfoExtraMapper.updateByPrimaryKeySelective(userInfoExtra);
            } else {
                userInfoExtra.setCreateTime(new Date());
                userInfoExtra.setUpdateTime(new Date());
                userInfoExtraMapper.insertSelective(userInfoExtra);
            }
        }
        return userInfoExtra;
    }
    @Override
    @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)
            throw new UserInfoExtraException(1, "用户不存在");
        // 额外信息
        UserInfoExtra extra = userInfoExtraMapper.getInfoExtraByUid(uid);
        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, "上级邀请码不存在");
        // 生成邀请关系
        return inviteCodeActive(uid, boss.getId());
    }
    @Override
    @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)
            throw new UserInfoExtraException(1, "用户不存在");
        // 额外信息
        UserInfoExtra extra = userInfoExtraMapper.getInfoExtraByUid(uid);
        if (extra != null && !StringUtil.isNullOrEmpty(extra.getInviteCode()))
            throw new UserInfoExtraException(1, "已经激活, 无需再次激活");
        // 获取微信信息
        WeiXinUser weiXinUser = WXAppLoginUtil.getWeiXinUser(code, wxAccount.getAppId(), wxAccount.getAppSecret());
        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(), invitee.getSystem());
            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, "绑定微信与激活微信不一致");
        }
        // 是否存在邀请人
        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(), invitee.getSystem());
            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);
        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());
    }
    /**
     * 邀请关系生成激活码
     *
     * @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.bindInviteRelationship(uid, bossId);
        } catch (ThreeSaleException e) {
            try {
                LogHelper.errorDetailInfo(e);
            } catch (Exception e1) {
                e1.printStackTrace();
            }
            throw new UserInfoExtraException(1, "关系绑定时失败");
        }
        // 生成邀请码
        String inviteCode = createInviteCode(uid);
        if (StringUtil.isNullOrEmpty(inviteCode))
            throw new UserInfoExtraException(1, "激活码生成失败");
        UserInfoExtra userInfoExtra = new UserInfoExtra();
        userInfoExtra.setUserInfo(new UserInfo(uid));
        userInfoExtra.setInviteCode(inviteCode);
        userInfoExtra.setUpdateTime(new Date());
        if (extra != null) {
            userInfoExtra.setId(extra.getId());
            userInfoExtraMapper.updateByPrimaryKeySelective(userInfoExtra);
        } else {
            userInfoExtra.setCreateTime(new Date());
            userInfoExtraMapper.insertSelective(userInfoExtra);
        }
        userActivedRecordService.add(new UserActivedRecord(uid));
        if (!Constant.IS_TEST) { // 发送激活成功消息
            Message message = MQMsgBodyFactory.create(MQTopicName.TOPIC_USER, UserTopicTagEnum.inviteCodeActive,
                    new InviteCodeActiveMQMsg(uid, new Date()));
            rocketMQManager.sendNormalMsg(message, null);
        }
        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 {
                int day = DateUtil.daysBetween(extra.getFirstLoginTime(), new Date());
                if (day <= 15) {
                    isNew = true;
                }
            } catch (ParseException e) {
                e.printStackTrace();
            }
        }
        return isNew;
    }
    @Override
    public UserRank gerUserRank(Long uid) {
        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))
            throw new UserInfoExtraException(1, "邀请码不能为空");
        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 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) {
            String inviteCodeHas = extra.getInviteCode();
            if (inviteCodeHas != null && inviteCodeHas.trim().length() > 0) {
                throw new UserInfoExtraException(1, "已经激活, 无需再次激活");
            }
        }
        // 验证数据
        String wxUnionIdExist = invitee.getWxUnionId();
        if (StringUtil.isNullOrEmpty(wxUnionIdExist)) {
            UserInfo newUser = userInfoService.getEffectiveUserInfoByWXUnionId(wxUnionId, invitee.getSystem());
            if (newUser != null) {
                throw new UserInfoExtraException(1, "此微信已被其他帐号绑定");
            }
        } 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()));
            rocketMQManager.sendNormalMsg(message, null);
        }
        // 消息
        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);
        }
    }
    @Resource
    private UserGoodsChannelConfigDao userGoodsChannelConfigDao;
    @Override
    public String getPddFanliCustomerParams(Long uid) {
        UserGoodsChannelConfig config = userGoodsChannelConfigDao.get(uid);
        if (config == null || StringUtil.isNullOrEmpty(config.getPddFanliCustomerParams())) {
            return uid + "";
        }
        return config.getPddFanliCustomerParams();
    }
}
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;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;
import javax.annotation.Resource;
import com.yeshi.fanli.dao.user.UserGoodsChannelConfigDao;
import com.yeshi.fanli.entity.SystemEnum;
import com.yeshi.fanli.entity.config.SystemConfigKeyEnum;
import com.yeshi.fanli.entity.goods.UserGoodsChannelConfig;
import com.yeshi.fanli.service.inter.config.SystemConfigService;
import com.yeshi.fanli.util.*;
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.entity.wx.WeiXinUser;
import org.yeshi.utils.tencentcloud.COSManager;
import com.aliyun.openservices.ons.api.Message;
import com.yeshi.fanli.dao.mybatis.user.UserInfoExtraMapper;
import com.yeshi.fanli.dao.mybatis.user.UserRankRecordMapper;
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.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.order.CommonOrderCountService;
import com.yeshi.fanli.service.inter.user.ForbiddenUserIdentifyCodeService;
import com.yeshi.fanli.service.inter.user.UserAccountService;
import com.yeshi.fanli.service.inter.user.UserInfoExtraService;
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.service.manger.msg.RocketMQManager;
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.vo.user.UserInfoExtraVO;
import net.coobird.thumbnailator.Thumbnails;
import org.yeshi.utils.wx.WXAppLoginUtil;
@Service
public class UserInfoExtraServiceImpl implements UserInfoExtraService {
    @Resource
    private UserInfoExtraMapper userInfoExtraMapper;
    @Resource
    private UserRankRecordMapper userRankRecordMapper;
    @Resource
    private UserRankService userRankService;
    @Resource
    private CommonOrderCountService commonOrderCountService;
    @Resource
    private ConfigService configService;
    @Resource
    private ThreeSaleSerivce threeSaleSerivce;
    @Resource
    private UserInfoService userInfoService;
    @Resource
    private UserInviteRecordService userInviteRecordService;
    @Resource
    @Lazy
    private UserActivedRecordService userActivedRecordService;
    @Resource
    private UserAccountMsgNotificationService userAccountMsgNotificationService;
    @Resource
    private RocketMQManager rocketMQManager;
    @Resource
    private SystemConfigService systemConfigService;
    @Override
    public UserInfoExtraVO getRankInfo(Long uid) throws UserInfoExtraException, Exception {
        UserInfoExtraVO extraVO = userInfoExtraMapper.getInfoExtraVOByUid(uid);
        if (extraVO == null) {
            throw new UserInfoExtraException(1, "用户附加信息不存在");
        }
        SystemEnum system = userInfoService.getUserSystem(uid);
        // 等级对照表
        String contrast = configService.getValue(ConfigKeyEnum.userRankContrast.getKey(), system);
        extraVO.setRankContrast(contrast);
        // 特别提醒
        String rankTip = configService.getValue(ConfigKeyEnum.userRankTip.getKey(), system);
        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) {
                case Constant.TYPE_REBATE:
                    rankMsg = "返利订单";
                    break;
                case Constant.TYPE_SHAER:
                    rankMsg = "分享订单";
                    break;
                case Constant.TYPE_INVITE:
                    rankMsg = "邀请订单";
                    break;
                default:
                    break;
            }
            List<Object> listMsg = new ArrayList<Object>();
            if (rankMsg != null) {
                String color_red = "#E5005C";
                String color_black = "#333333";
                Map<String, String> map1 = new HashMap<String, String>();
                map1.put("content", "上月");
                map1.put("color", color_black);
                listMsg.add(map1);
                Map<String, String> map2 = new HashMap<String, String>();
                map2.put("content", rankMsg);
                map2.put("color", color_red);
                listMsg.add(map2);
                Map<String, String> map3 = new HashMap<String, String>();
                map3.put("content", "达到了");
                map3.put("color", color_black);
                listMsg.add(map3);
                Map<String, String> map4 = new HashMap<String, String>();
                map4.put("content", rankOrderNum + "");
                map4.put("color", color_red);
                listMsg.add(map4);
                Map<String, String> map5 = new HashMap<String, String>();
                map5.put("content", "单");
                map5.put("color", color_black);
                listMsg.add(map5);
                extraVO.setGalaMsg(listMsg);
            }
        }
        return extraVO;
    }
    @Override
    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) {
            // 判断当月是否已更新
            Date rankUpdateTime = userInfoExtra.getRankUpdateTime();
            if (rankUpdateTime != null) {
                SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM");
                if (sdf.format(rankUpdateTime).equals(sdf.format(new Date()))) {
                    isupdateRank = false;
                }
            }
            extra.setId(userInfoExtra.getId());
        } else {
            extra.setUserInfo(new UserInfo(uid));
        }
        // 更新等级
        if (isupdateRank) {
            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 {
        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 saveUserInfoExtra(UserInfoExtra userInfoExtra) throws UserInfoExtraException {
        if (userInfoExtra == null) {
            throw new UserInfoExtraException(1, "附加信息不能为空");
        }
        Long extraId = userInfoExtra.getId();
        if (extraId != null) {
            userInfoExtra.setUpdateTime(new Date());
            userInfoExtraMapper.updateByPrimaryKeySelective(userInfoExtra);
        } else {
            UserInfo userInfo = userInfoExtra.getUserInfo();
            if (userInfo == null || userInfo.getId() == null) {
                throw new UserInfoExtraException(1, "用户不存在");
            }
            Long uid = userInfo.getId();
            UserInfoExtra extra = userInfoExtraMapper.getInfoExtraByUid(uid);
            if (extra != null && extra.getId() != null) {
                userInfoExtra.setId(extra.getId());
                userInfoExtra.setUpdateTime(new Date());
                userInfoExtraMapper.updateByPrimaryKeySelective(userInfoExtra);
            } else {
                userInfoExtra.setCreateTime(new Date());
                userInfoExtra.setUpdateTime(new Date());
                userInfoExtraMapper.insertSelective(userInfoExtra);
            }
        }
        return userInfoExtra;
    }
    @Override
    @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)
            throw new UserInfoExtraException(1, "用户不存在");
        // 额外信息
        UserInfoExtra extra = userInfoExtraMapper.getInfoExtraByUid(uid);
        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, "上级邀请码不存在");
        // 生成邀请关系
        return inviteCodeActive(uid, boss.getId());
    }
    @Override
    @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)
            throw new UserInfoExtraException(1, "用户不存在");
        // 额外信息
        UserInfoExtra extra = userInfoExtraMapper.getInfoExtraByUid(uid);
        if (extra != null && !StringUtil.isNullOrEmpty(extra.getInviteCode()))
            throw new UserInfoExtraException(1, "已经激活, 无需再次激活");
        // 获取微信信息
        WeiXinUser weiXinUser = WXAppLoginUtil.getWeiXinUser(code, wxAccount.getAppId(), wxAccount.getAppSecret());
        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(), invitee.getSystem());
            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 = systemConfigService.getValueCache(SystemConfigKeyEnum.defaultNickNamePrefix, invitee.getSystem());
            if (!StringUtil.isNullOrEmpty(defaultNickName) && !StringUtil.isNullOrEmpty(weiXinUser.getNickname())) {
                defaultNickName = defaultNickName + uid;
                if ((defaultNickName.equals(invitee.getNickName()) || "返利券".equals(invitee.getNickName())
                        || invitee.getNickName().startsWith(defaultNickName))) {
                    updateUserInfo.setNickName(weiXinUser.getNickname());
                }
            }
            // 将默认头像替换成微信头像
            String defaultPortrait = systemConfigService.getValueCache(SystemConfigKeyEnum.defaultPortrait, invitee.getSystem());
            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, "绑定微信与激活微信不一致");
        }
        // 是否存在邀请人
        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(), invitee.getSystem());
            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 = systemConfigService.getValueCache(SystemConfigKeyEnum.defaultNickNamePrefix, invitee.getSystem());
            if (!StringUtil.isNullOrEmpty(defaultNickName) && !StringUtil.isNullOrEmpty(weiXinUser.getNickname())) {
                defaultNickName = defaultNickName + uid;
                if ((defaultNickName.equals(invitee.getNickName()) || "返利券".equals(invitee.getNickName())
                        || invitee.getNickName().startsWith(defaultNickName))) {
                    updateUserInfo.setNickName(weiXinUser.getNickname());
                }
            }
            // 将默认头像替换成微信头像
            String defaultPortrait = systemConfigService.getValueCache(SystemConfigKeyEnum.defaultPortrait, invitee.getSystem());
            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);
        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());
    }
    /**
     * 邀请关系生成激活码
     *
     * @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.bindInviteRelationship(uid, bossId);
        } catch (ThreeSaleException e) {
            try {
                LogHelper.errorDetailInfo(e);
            } catch (Exception e1) {
                e1.printStackTrace();
            }
            throw new UserInfoExtraException(1, "关系绑定时失败");
        }
        // 生成邀请码
        String inviteCode = createInviteCode(uid);
        if (StringUtil.isNullOrEmpty(inviteCode))
            throw new UserInfoExtraException(1, "激活码生成失败");
        UserInfoExtra userInfoExtra = new UserInfoExtra();
        userInfoExtra.setUserInfo(new UserInfo(uid));
        userInfoExtra.setInviteCode(inviteCode);
        userInfoExtra.setUpdateTime(new Date());
        if (extra != null) {
            userInfoExtra.setId(extra.getId());
            userInfoExtraMapper.updateByPrimaryKeySelective(userInfoExtra);
        } else {
            userInfoExtra.setCreateTime(new Date());
            userInfoExtraMapper.insertSelective(userInfoExtra);
        }
        userActivedRecordService.add(new UserActivedRecord(uid));
        if (!Constant.IS_TEST) { // 发送激活成功消息
            Message message = MQMsgBodyFactory.create(MQTopicName.TOPIC_USER, UserTopicTagEnum.inviteCodeActive,
                    new InviteCodeActiveMQMsg(uid, new Date()));
            rocketMQManager.sendNormalMsg(message, null);
        }
        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 {
                int day = DateUtil.daysBetween(extra.getFirstLoginTime(), new Date());
                if (day <= 15) {
                    isNew = true;
                }
            } catch (ParseException e) {
                e.printStackTrace();
            }
        }
        return isNew;
    }
    @Override
    public UserRank gerUserRank(Long uid) {
        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))
            throw new UserInfoExtraException(1, "邀请码不能为空");
        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 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) {
            String inviteCodeHas = extra.getInviteCode();
            if (inviteCodeHas != null && inviteCodeHas.trim().length() > 0) {
                throw new UserInfoExtraException(1, "已经激活, 无需再次激活");
            }
        }
        // 验证数据
        String wxUnionIdExist = invitee.getWxUnionId();
        if (StringUtil.isNullOrEmpty(wxUnionIdExist)) {
            UserInfo newUser = userInfoService.getEffectiveUserInfoByWXUnionId(wxUnionId, invitee.getSystem());
            if (newUser != null) {
                throw new UserInfoExtraException(1, "此微信已被其他帐号绑定");
            }
        } 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()));
            rocketMQManager.sendNormalMsg(message, null);
        }
        // 消息
        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);
        }
    }
    @Resource
    private UserGoodsChannelConfigDao userGoodsChannelConfigDao;
    @Override
    public String getPddFanliCustomerParams(Long uid) {
        UserGoodsChannelConfig config = userGoodsChannelConfigDao.get(uid);
        if (config == null || StringUtil.isNullOrEmpty(config.getPddFanliCustomerParams())) {
            return uid + "";
        }
        return config.getPddFanliCustomerParams();
    }
}