admin
2019-07-30 573c491b4a1ba60e12a5678a01c1546c0077c1ee
fanli/src/main/java/com/yeshi/fanli/service/impl/user/UserAccountServiceImpl.java
@@ -4,6 +4,7 @@
import java.io.FileWriter;
import java.io.IOException;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
@@ -13,96 +14,100 @@
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.yeshi.utils.JsonUtil;
import org.yeshi.utils.tencentcloud.COSManager;
import com.google.gson.Gson;
import com.qcloud.cos.model.COSObjectSummary;
import com.qcloud.cos.model.ObjectListing;
import com.yeshi.fanli.dao.mybatis.AccountDetailsMapper;
import com.yeshi.fanli.dao.mybatis.AccountMessageMapper;
import com.yeshi.fanli.dao.mybatis.BindingAccountMapper;
import com.yeshi.fanli.dao.mybatis.MoneyRecordMapper;
import com.yeshi.fanli.dao.mybatis.PidOrderMapper;
import com.yeshi.fanli.dao.mybatis.ThreeSaleMapper;
import com.yeshi.fanli.dao.mybatis.UserConnectHistoryMapper;
import com.yeshi.fanli.dao.mybatis.UserInfoMapper;
import com.yeshi.fanli.dao.mybatis.hongbao.HongBaoMapper;
import com.yeshi.fanli.dao.mybatis.order.OrderItemMapper;
import com.yeshi.fanli.dao.mybatis.order.OrderMapper;
import com.yeshi.fanli.entity.bus.user.AccountDetails;
import com.yeshi.fanli.entity.bus.user.AccountMessage;
import com.yeshi.fanli.entity.bus.user.BindingAccount;
import com.yeshi.fanli.entity.bus.user.HongBao;
import com.yeshi.fanli.entity.bus.user.ForbiddenUserIdentifyCode;
import com.yeshi.fanli.entity.bus.user.ForbiddenUserIdentifyCode.ForbiddenUserIdentifyCodeTypeEnum;
import com.yeshi.fanli.entity.bus.user.LoginResult;
import com.yeshi.fanli.entity.bus.user.MoneyRecord;
import com.yeshi.fanli.entity.bus.user.Order;
import com.yeshi.fanli.entity.bus.user.OrderItem;
import com.yeshi.fanli.entity.bus.user.SMSHistory;
import com.yeshi.fanli.entity.bus.user.ThreeSale;
import com.yeshi.fanli.entity.bus.user.UserAccountBindingHistory;
import com.yeshi.fanli.entity.bus.user.UserConnectHistory;
import com.yeshi.fanli.entity.bus.user.UserExtraTaoBaoInfo;
import com.yeshi.fanli.entity.bus.user.UserInfo;
import com.yeshi.fanli.entity.bus.user.WeiXinUser;
import com.yeshi.fanli.entity.taobao.PidOrder;
import com.yeshi.fanli.exception.UserAccountException;
import com.yeshi.fanli.exception.user.ForbiddenUserIdentifyCodeException;
import com.yeshi.fanli.log.LogHelper;
import com.yeshi.fanli.service.inter.hongbao.HongBaoService;
import com.yeshi.fanli.service.inter.hongbao.ThreeSaleSerivce;
import com.yeshi.fanli.service.inter.msg.UserAccountMsgNotificationService;
import com.yeshi.fanli.service.inter.user.BindingAccountService;
import com.yeshi.fanli.service.inter.user.ForbiddenUserIdentifyCodeService;
import com.yeshi.fanli.service.inter.user.SpreadUserImgService;
import com.yeshi.fanli.service.inter.user.UserAccountBindingHistoryService;
import com.yeshi.fanli.service.inter.user.UserAccountService;
import com.yeshi.fanli.service.inter.user.UserExtraTaoBaoInfoService;
import com.yeshi.fanli.service.inter.user.UserInfoDeleteRecordService;
import com.yeshi.fanli.service.inter.user.UserInfoExtraService;
import com.yeshi.fanli.service.inter.user.UserInfoService;
import com.yeshi.fanli.util.Constant;
import com.yeshi.fanli.util.FileUtil;
import com.yeshi.fanli.util.RedisManager;
import com.yeshi.fanli.util.StringUtil;
import com.yeshi.fanli.util.TimeUtil;
import com.yeshi.fanli.util.factory.AccountDetailsFactory;
import com.yeshi.fanli.util.factory.msg.MsgAccountDetailFactory;
import com.yeshi.fanli.util.wx.WXLoginUtil;
import net.sf.json.JSONObject;
import org.yeshi.utils.JsonUtil;
import org.yeshi.utils.tencentcloud.COSManager;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.Transaction;
@Service
public class UserAccountServiceImpl implements UserAccountService {
   @Resource
   private RedisManager redisManager;
   @Resource
   private UserInfoMapper userInfoMapper;
   @Resource
   private BindingAccountMapper bindingAccountMapper;
   private UserInfoService userInfoService;
   @Resource
   private BindingAccountService bindingAccountService;
   @Resource
   private UserConnectHistoryMapper userConnectHistoryMapper;
   @Resource
   private AccountDetailsMapper accountDetailsMapper;
   @Resource
   private HongBaoMapper hongBaoMapper;
   @Resource
   private OrderMapper orderMapper;
   @Resource
   private OrderItemMapper orderItemMapper;
   @Resource
   private ThreeSaleMapper threeSaleMapper;
   @Resource
   private PidOrderMapper pidOrderMapper;
   @Resource
   private HongBaoService hongBaoService;
   private ThreeSaleSerivce threeSaleSerivce;
   @Resource
   private AccountMessageMapper accountMessageMapper;
   @Resource
   private MoneyRecordMapper moneyRecordMapper;
   @Resource
   private SpreadUserImgService spreadUserImgService;
   @Resource
   private UserAccountMsgNotificationService userAccountMsgNotificationService;
   @Resource
   private UserExtraTaoBaoInfoService userExtraTaoBaoInfoService;
   @Resource
   private ForbiddenUserIdentifyCodeService forbiddenUserIdentifyCodeService;
   @Resource
   private UserInfoExtraService userInfoExtraService;
   @Resource
   private UserAccountBindingHistoryService userAccountBindingHistoryService;
   @Resource
   private UserInfoDeleteRecordService userInfoDeleteRecordService;
   @Resource
   private JedisPool jedisPool;
   @Transactional
   @Override
@@ -128,7 +133,20 @@
         WeiXinUser weiXinUser = null;
         switch (loginType) {
         case 1:// 淘宝
               // 判断淘宝是否被封禁
            if (!StringUtil.isNullOrEmpty(tbUserInfo.getTaoBaoUid())) {
               ForbiddenUserIdentifyCode identifyCode = forbiddenUserIdentifyCodeService.listByTypeAndIdentifyCode(
                     ForbiddenUserIdentifyCodeTypeEnum.taobaoUid, tbUserInfo.getTaoBaoUid());
               if (identifyCode != null && identifyCode.getEffective() != null && identifyCode.getEffective())
                  throw new UserAccountException(Constant.CODE_FORBIDDEN_USER,
                        Constant.FORBIDDEN_USER_REASON_DESC);
            }
            userInfo = getUserInfoByTaoBaoOpenId(appId, tbUserInfo.getOpenid());
            // 判断用户是否被删除
            if (userInfo != null && userInfo.getState() != null
                  && (userInfo.getState() == UserInfo.STATE_DELETE_OUT_OF_DATE
                        || userInfo.getState() == UserInfo.STATE_DELETE))
               userInfo = null;
            if (userInfo == null) {// 原先的账号不存在
               userInfo = new UserInfo();
               userInfo.setAppId(appId);
@@ -160,12 +178,23 @@
            if (weiXinUser == null)
               throw new UserAccountException(1001, "无法获取到微信个人信息");
            LogHelper.test("微信授权用户信息:" + new Gson().toJson(weiXinUser));
            // 判断微信unionid是否被封禁
            ForbiddenUserIdentifyCode identifyCode = forbiddenUserIdentifyCodeService.listByTypeAndIdentifyCode(
                  ForbiddenUserIdentifyCodeTypeEnum.wxUnionId, weiXinUser.getUnionid());
            if (identifyCode != null && identifyCode.getEffective() != null && identifyCode.getEffective())
               throw new UserAccountException(Constant.CODE_FORBIDDEN_USER, Constant.FORBIDDEN_USER_REASON_DESC);
            userInfo = getUserInfoByWXUnionId(appId, weiXinUser.getUnionid());
            // 判断用户是否被删除
            if (userInfo != null && userInfo.getState() != null
                  && (userInfo.getState() == UserInfo.STATE_DELETE_OUT_OF_DATE
                        || userInfo.getState() == UserInfo.STATE_DELETE))
               userInfo = null;
            // 直接用的微信登录
            if (lastUser == null) {
               if (userInfo != null) {
                  // 使分销关系生效
                  threeSaleMapper.effectThreeSale(userInfo.getId());
                  threeSaleSerivce.effective(userInfo);
                  // 更新头像与昵称
                  UserInfo updateUserInfo = new UserInfo(userInfo.getId());
                  updateUserInfo.setNickName(weiXinUser.getNickname());
@@ -241,7 +270,7 @@
                     session.removeAttribute("LAST_LOGIN_USER");
                     // 使分销关系生效
                     threeSaleMapper.effectThreeSale(userInfo.getId());
                     threeSaleSerivce.effective(userInfo);
                     return new LoginResult(LoginResult.TYPE_NORMAL, userInfo);
                  } else {// 两个账号拥有不同的UID
@@ -255,7 +284,7 @@
                     result.setLessUser(lastUser);
                     // 使分销关系生效
                     threeSaleMapper.effectThreeSale(userInfo.getId());
                     threeSaleSerivce.effective(userInfo);
                     return result;
                  }
@@ -286,7 +315,19 @@
               }
            }
         case 3:// 手机号码
               // 判断手机号码是否被封禁
            ForbiddenUserIdentifyCode identifyCode1 = forbiddenUserIdentifyCodeService
                  .listByTypeAndIdentifyCode(ForbiddenUserIdentifyCodeTypeEnum.phone, phone);
            if (identifyCode1 != null && identifyCode1.getEffective() != null && identifyCode1.getEffective())
               throw new UserAccountException(Constant.CODE_FORBIDDEN_USER, Constant.FORBIDDEN_USER_REASON_DESC);
            userInfo = getUserInfoByPhone(appId, phone);
            // 判断用户是否被删除
            if (userInfo != null && userInfo.getState() != null
                  && (userInfo.getState() == UserInfo.STATE_DELETE_OUT_OF_DATE
                        || userInfo.getState() == UserInfo.STATE_DELETE))
               userInfo = null;
            if (userInfo == null) {// 原先的账号不存在
               userInfo = new UserInfo();
               userInfo.setAppId(appId);
@@ -338,6 +379,12 @@
      WeiXinUser weiXinUser = null;
      switch (loginType) {
      case 1:// 淘宝
         if (!StringUtil.isNullOrEmpty(tbUserInfo.getTaoBaoUid())) {
            ForbiddenUserIdentifyCode identifyCode = forbiddenUserIdentifyCodeService.listByTypeAndIdentifyCode(
                  ForbiddenUserIdentifyCodeTypeEnum.taobaoUid, tbUserInfo.getTaoBaoUid());
            if (identifyCode != null && identifyCode.getEffective() != null && identifyCode.getEffective())
               throw new UserAccountException(Constant.CODE_FORBIDDEN_USER, Constant.FORBIDDEN_USER_REASON_DESC);
         }
         userInfo = getUserInfoByTaoBaoOpenId(appId, tbUserInfo.getOpenid());
         break;
      case 2:// 微信
@@ -345,12 +392,29 @@
         weiXinUser = WXLoginUtil.getWeiXinUserWithSavePortrait(code);
         if (weiXinUser == null)
            throw new UserAccountException(1001, "无法获取到微信个人信息");
         // 判断是否被封禁
         ForbiddenUserIdentifyCode identifyCode = forbiddenUserIdentifyCodeService
               .listByTypeAndIdentifyCode(ForbiddenUserIdentifyCodeTypeEnum.phone, phone);
         if (identifyCode != null && identifyCode.getEffective() != null && identifyCode.getEffective())
            throw new UserAccountException(Constant.CODE_FORBIDDEN_USER, Constant.FORBIDDEN_USER_REASON_DESC);
         userInfo = getUserInfoByWXUnionId(appId, weiXinUser.getUnionid());
         break;
      case 3:// 手机号码
            // 判断是否被封禁
         ForbiddenUserIdentifyCode identifyCode1 = forbiddenUserIdentifyCodeService
               .listByTypeAndIdentifyCode(ForbiddenUserIdentifyCodeTypeEnum.phone, phone);
         if (identifyCode1 != null && identifyCode1.getEffective() != null && identifyCode1.getEffective())
            throw new UserAccountException(Constant.CODE_FORBIDDEN_USER, Constant.FORBIDDEN_USER_REASON_DESC);
         userInfo = getUserInfoByPhone(appId, phone);
         break;
      }
      // 判断用户是否被删除
      if (userInfo != null && userInfo.getState() != null && (userInfo.getState() == UserInfo.STATE_DELETE_OUT_OF_DATE
            || userInfo.getState() == UserInfo.STATE_DELETE))
         userInfo = null;
      if (userInfo != null) {
         UserInfo updateUserInfo = new UserInfo(userInfo.getId());
@@ -431,32 +495,21 @@
      if (!StringUtil.isNullOrEmpty(mainUser.getPhone()) && !StringUtil.isNullOrEmpty(lessUser.getPhone()))
         throw new UserAccountException(9, "两个账号都绑定了手机号码,请解绑其中一个");
      if (lessUser.getMyHongBao().compareTo(new BigDecimal("20")) >= 0
            && mainUser.getMyHongBao().compareTo(new BigDecimal("20")) > 0)
         throw new UserAccountException(10, String.format("账户ID:%s 的资金超过20元,为保证资金安全请联系客服打通", lessUser.getId() + ""));
      if (lessUser.getMyHongBao().compareTo(new BigDecimal("10")) >= 0
            && mainUser.getMyHongBao().compareTo(new BigDecimal("10")) > 0)
         throw new UserAccountException(10, String.format("账户ID:%s 的资金超过10元,为保证资金安全请联系客服打通", lessUser.getId() + ""));
      // 判定是否绑定了同一支付宝
      List<BindingAccount> mainUserAccountList = bindingAccountMapper.selectByUid(mainUser.getId());
      if (mainUserAccountList != null)
         for (int i = 0; i < mainUserAccountList.size(); i++) {
            if (mainUserAccountList.get(i).getType() == BindingAccount.TYPE_WXPAY) {
               mainUserAccountList.remove(i);
               i--;
            }
         }
      List<BindingAccount> lessUserAccountList = bindingAccountMapper.selectByUid(lessUser.getId());
      if (lessUserAccountList != null)
         for (int i = 0; i < lessUserAccountList.size(); i++) {
            if (lessUserAccountList.get(i).getType() == BindingAccount.TYPE_WXPAY) {
               lessUserAccountList.remove(i);
               i--;
            }
         }
      BindingAccount mainUserAccount = bindingAccountService.getBindingAccountByUidAndType(mainUser.getId(),
            BindingAccount.TYPE_ALIPAY);
      BindingAccount lessUserAccount = bindingAccountService.getBindingAccountByUidAndType(lessUser.getId(),
            BindingAccount.TYPE_ALIPAY);
      // 有不同的支付宝账号
      boolean hasDiffrentAlipayAccount = false;
      if (mainUserAccountList != null && mainUserAccountList.size() > 0 && lessUserAccountList != null
            && lessUserAccountList.size() > 0) {
         if (!mainUserAccountList.get(0).getAccount().equalsIgnoreCase(lessUserAccountList.get(0).getAccount()))
      if (mainUserAccount != null && lessUserAccount != null) {
         if (!mainUserAccount.getAccount().equalsIgnoreCase(lessUserAccount.getAccount()))
            hasDiffrentAlipayAccount = true;
      }
@@ -496,52 +549,12 @@
      userInfoMapper.connectUser(mainUser.getId(), lessUser.getId());
      // 查询是否有多余的新人红包
      List<HongBao> list = hongBaoMapper.selectByUidAndType(mainUser.getId(), HongBao.TYPE_XINREN);
      int subCount = 0;
      int addCount = 0;
      for (HongBao hb : list) {
         if (hb.getMoney().compareTo(new BigDecimal(0)) > 0)
            addCount++;
         if (hb.getMoney().compareTo(new BigDecimal(0)) < 0)
            subCount++;
      }
      // 有2个或者2个以上的新人红包
      if (addCount - subCount > 1) {
         // 扣除一个新人红包
         AccountDetails accountDetails = new AccountDetails();
         accountDetails.setCreateTime(TimeUtil.getGernalTime(System.currentTimeMillis(), "yyyy-MM-dd HH:mm:ss"));
         accountDetails.setExtract(null);
         accountDetails.setMoney("-" + list.get(1).getMoney().toString());
         accountDetails.setOrderItem(null);
         accountDetails.setTitle(" 账号合并扣除重复新人红包");
         accountDetails.setType(AccountDetailsFactory.TUIKUAN);
         accountDetails.setUserInfo(mainUser);
         accountDetailsMapper.insertSelective(accountDetails);
         AccountMessage accountMessage = new AccountMessage();
         accountMessage.setContent(" 账号合并扣除重复新人红包" + list.get(1).getMoney().toString() + "元");
         accountMessage.setCreateTime(System.currentTimeMillis());
         accountMessage.setIsOpen(false);
         accountMessage.setSystemMsgId(0);
         accountMessage.setTitle(" 账号合并扣除重复新人红包");
         accountMessage.setUserInfo(mainUser);
         accountMessageMapper.insertSelective(accountMessage);
         userInfoMapper.subHongBaoByUid(mainUser.getId(), list.get(1).getMoney());
         HongBao hongBao = new HongBao(mainUser, new BigDecimal(0).subtract(list.get(1).getMoney()), null,
               HongBao.TYPE_XINREN, HongBao.STATE_YILINGQU, System.currentTimeMillis(), System.currentTimeMillis(),
               System.currentTimeMillis(), null, "账号合并扣除");
         hongBaoMapper.insertSelective(hongBao);
         MoneyRecord moneyRecord = new MoneyRecord(mainUser, hongBao, list.get(1).getMoney(), "账号合并扣除重复新人红包", "账号合并",
               System.currentTimeMillis(), 2);
         moneyRecordMapper.insertSelective(moneyRecord);
      }
      userAccountMsgNotificationService.connectSuccess(mainUser.getId(), lessUser.getId());
      userInfoDeleteRecordService.addDeleteRecord(lessUser.getId(), UserInfo.STATE_DELETE, "删除:账号被打通删除");
   }
   /**
@@ -551,13 +564,26 @@
    * @param unionId
    * @return
    */
   @Override
   public UserInfo getUserInfoByWXUnionId(String appId, String unionId) throws UserAccountException {
      if (StringUtil.isNullOrEmpty(appId))
         throw new UserAccountException(1, "appId为空");
      if (StringUtil.isNullOrEmpty(unionId))
         throw new UserAccountException(2, "unionId为空");
      return userInfoMapper.getUserInfoByAppIdAndWXUnionId(appId, unionId);
      List<UserInfo> list = userInfoMapper.listByAppIdAndWXUnionId(appId, unionId);
      // 剔除被删除掉的用户
      for (int i = 0; i < list.size(); i++) {
         if (list.get(i).getState() == UserInfo.STATE_DELETE
               || list.get(i).getState() == UserInfo.STATE_DELETE_OUT_OF_DATE) {
            list.remove(i);
            i--;
         }
      }
      if (list.size() > 0)
         return list.get(list.size() - 1);
      else
         return null;
   }
   /**
@@ -572,7 +598,21 @@
         throw new UserAccountException(1, "appId为空");
      if (StringUtil.isNullOrEmpty(openId))
         throw new UserAccountException(2, "openId为空");
      return userInfoMapper.getUserInfoByAppIdAndTaoBaoOpenId(appId, openId);
      List<UserInfo> list = userInfoMapper.listByAppIdAndTaoBaoOpenId(appId, openId);
      // 剔除被删除掉的用户
      for (int i = 0; i < list.size(); i++) {
         if (list.get(i).getState() == UserInfo.STATE_DELETE
               || list.get(i).getState() == UserInfo.STATE_DELETE_OUT_OF_DATE) {
            list.remove(i);
            i--;
         }
      }
      if (list.size() > 0)
         return list.get(list.size() - 1);
      else
         return null;
   }
   /**
@@ -587,7 +627,21 @@
         throw new UserAccountException(1, "appId为空");
      if (StringUtil.isNullOrEmpty(phone))
         throw new UserAccountException(2, "phone为空");
      return userInfoMapper.getUserInfoByAppIdAndPhone(appId, phone);
      List<UserInfo> list = userInfoMapper.listByAppIdAndPhone(appId, phone);
      // 剔除被删除掉的用户
      for (int i = 0; i < list.size(); i++) {
         if (list.get(i).getState() == UserInfo.STATE_DELETE
               || list.get(i).getState() == UserInfo.STATE_DELETE_OUT_OF_DATE) {
            list.remove(i);
            i--;
         }
      }
      if (list.size() > 0)
         return list.get(list.size() - 1);
      else
         return null;
   }
   private void updateLatestLoginTime(Long uid) {
@@ -621,6 +675,7 @@
   @Override
   public void addUser(UserInfo user) {
      Long maxUid = userInfoMapper.getMaxUid();
      if (maxUid == null)
         maxUid = 100000L;
@@ -642,8 +697,12 @@
         userInfoMapper.updateByPrimaryKeySelective(updateUserInfo);
      }
      // 添加新人红包
      hongBaoService.setNewUserHongBaoMyBatis(user, 1);
      try {
         // 第一次登录时创建用户额外信息
         userInfoExtraService.createUserInfoExtra(user.getId());
      } catch (Exception e) {
         e.printStackTrace();
      }
   }
   @Override
@@ -701,7 +760,7 @@
      if (!StringUtil.isNullOrEmpty(user.getOpenid()) && !user.getOpenid().equalsIgnoreCase(tbOpenId))
         throw new UserAccountException(5, "当前账号已经绑定了淘宝,请先解绑");
      //绑定同一个淘宝号
      // 绑定同一个淘宝号
      if (!StringUtil.isNullOrEmpty(user.getOpenid()) && user.getOpenid().equalsIgnoreCase(tbOpenId))
         return;
@@ -744,6 +803,8 @@
      }
      userInfoMapper.updateByPrimaryKeySelective(update);
      userExtraTaoBaoInfoService.unBindUid(uid);
      userAccountMsgNotificationService.unBindingSuccess(uid, MsgAccountDetailFactory.TYPE_TB);
   }
@@ -791,19 +852,10 @@
      // 备份用户信息
      UserInfo user = userInfoMapper.selectByPrimaryKey(uid);
      // 备份资金明细
      List<AccountDetails> accountDetailsList = accountDetailsMapper.selectByUid(uid);
      // 备份红包信息
      List<HongBao> hongBaoList = hongBaoMapper.selectByUid(uid);
      // 备份订单,子订单信息
      List<Order> orderList = orderMapper.selectByUid(uid);
      List<OrderItem> orderItemList = orderItemMapper.selectByUid(uid);
      // TODO 备份资金明细
      // 备份邀请关系
      List<ThreeSale> threeSaleList = threeSaleMapper.selectByUid(uid);
      // 备份分享赚
      List<PidOrder> pidOrderList = pidOrderMapper.selectByUid(uid);
      List<ThreeSale> threeSaleList = new ArrayList<>();
      FileWriter fw = null;
      try {
@@ -813,23 +865,8 @@
         fw.write("#UserInfo" + "\r\n");
         fw.write(JsonUtil.getSimpleGsonWithDate().toJson(user) + "\r\n");
         fw.write("#AccountDetails" + "\r\n");
         fw.write(JsonUtil.getSimpleGsonWithDate().toJson(accountDetailsList) + "\r\n");
         fw.write("#HongBao" + "\r\n");
         fw.write(JsonUtil.getSimpleGsonWithDate().toJson(hongBaoList) + "\r\n");
         fw.write("#Order" + "\r\n");
         fw.write(JsonUtil.getSimpleGsonWithDate().toJson(orderList) + "\r\n");
         fw.write("#OrderItem" + "\r\n");
         fw.write(JsonUtil.getSimpleGsonWithDate().toJson(orderItemList) + "\r\n");
         fw.write("#ThreeSale" + "\r\n");
         fw.write(JsonUtil.getSimpleGsonWithDate().toJson(threeSaleList) + "\r\n");
         fw.write("#PidOrder" + "\r\n");
         fw.write(JsonUtil.getSimpleGsonWithDate().toJson(pidOrderList) + "\r\n");
         fw.close();
@@ -894,4 +931,429 @@
      return user.getPortrait();
   }
   @Transactional
   @Override
   public UserInfo loginPhone(HttpServletRequest request, int loginType, String vcode, String phone, String appId)
         throws UserAccountException {
      // 空额清理
      if (phone == null || phone.trim().length() == 0) {
         throw new UserAccountException(1, "请输入手机号码");
      }
      phone = phone.replaceAll(" ", "");
      // 苹果应用商店上线测试号码
      if ("17316780233".equalsIgnoreCase(phone) && "2581".equalsIgnoreCase(vcode)) {
         ;
      } else {
         if (StringUtil.isNullOrEmpty(vcode)) {
            throw new UserAccountException(1, "请输入验证码");
         }
         String oldVcode = redisManager.getSMSVCode(phone, SMSHistory.TYPE_LOGIN);
         LogHelper.test("----------------------登录验证码: " + oldVcode);
         if (!Constant.IS_TEST)
            if (StringUtil.isNullOrEmpty(oldVcode) || !oldVcode.equalsIgnoreCase(vcode)) {
               throw new UserAccountException(1, "验证码错误,重新输入");
            } else {// 验证码输入正确
               redisManager.clearSMSVCode(phone, SMSHistory.TYPE_LOGIN);
            }
      }
      JSONObject logInfo = new JSONObject();
      logInfo.put("appId", appId);
      logInfo.put("phone", phone);
      logInfo.put("loginType", loginType);
      LogHelper.lgoinInfo(logInfo.toString());
      // 判断手机号码是否被封禁
      ForbiddenUserIdentifyCode identifyCode1 = forbiddenUserIdentifyCodeService
            .listByTypeAndIdentifyCode(ForbiddenUserIdentifyCodeTypeEnum.phone, phone);
      if (identifyCode1 != null && identifyCode1.getEffective() != null && identifyCode1.getEffective()) {
         throw new UserAccountException(Constant.CODE_FORBIDDEN_USER, Constant.FORBIDDEN_USER_REASON_DESC);
      }
      // 清空限制
      redisManager.clearSMSFrequencyLimit(phone, SMSHistory.TYPE_LOGIN);
      // 清理次数
      redisManager.removeCommonString("sendMSNLoginCount" + phone);
      // 采用redis事务防止一个手机号多次注册问题
      String watchKey = StringUtil.Md5("REGISTER:" + phone);
      Jedis jedis = jedisPool.getResource();
      try {
         jedis.watch(watchKey);
         if (jedis.get(watchKey) != null && Integer.parseInt(jedis.get(watchKey)) > 1)
            throw new UserAccountException(10, "请稍后再试");
         Transaction tran = jedis.multi();
         tran.incr(watchKey);
         List<Object> exec = tran.exec();
         if (exec == null || exec.size() == 0) {
            throw new UserAccountException(10, "请稍后再试");
         } else {
            // 查询是否存在该电话历史用户
            UserInfo userInfo = userInfoMapper.getEffectiveUserInfoByPhone(phone);
            if (userInfo != null) {
               // 更新账户登录信息
               updateLonginInfo(userInfo, loginType, request);
            } else {
               userInfo = new UserInfo();
               userInfo.setAppId(appId);
               userInfo.setNickName(Constant.systemCommonConfig.getDefaultNickName());
               userInfo.setPortrait(Constant.systemCommonConfig.getDefaultPortrait());
               userInfo.setPhone(phone);
               userInfo.setLoginType(loginType);
               userInfo.setState(UserInfo.STATE_NORMAL);
               // 创建用户
               addUser(userInfo);
               try {
                  // 第一次登录时创建用户额外信息
                  userInfoExtraService.createUserInfoExtra(userInfo.getId());
               } catch (Exception e) {
                  e.printStackTrace();
               }
            }
            return userInfo;
         }
      } catch (Exception e) {
         e.printStackTrace();
      } finally {
         jedis.del(watchKey);
         jedis.unwatch();
         jedisPool.returnResource(jedis);
      }
      throw new UserAccountException(10, "请稍后再试");
   }
   @Transactional
   @Override
   public UserInfo loginWinXin(HttpServletRequest request, int loginType, String code, String appId)
         throws UserAccountException {
      // 日志信息
      JSONObject logInfo = new JSONObject();
      logInfo.put("appId", appId);
      logInfo.put("code", code);
      logInfo.put("loginType", loginType);
      LogHelper.lgoinInfo(logInfo.toString());
      // 通过Code换取信息
      WeiXinUser weiXinUser = WXLoginUtil.getWeiXinUserWithSavePortrait(code);
      if (weiXinUser == null) {
         throw new UserAccountException(1, "微信帐号授权失败");
      }
      LogHelper.test("微信授权用户信息:" + new Gson().toJson(weiXinUser));
      // 判断微信unionid是否被封禁
      ForbiddenUserIdentifyCode identifyCode = forbiddenUserIdentifyCodeService
            .listByTypeAndIdentifyCode(ForbiddenUserIdentifyCodeTypeEnum.wxUnionId, weiXinUser.getUnionid());
      if (identifyCode != null && identifyCode.getEffective() != null && identifyCode.getEffective()) {
         throw new UserAccountException(Constant.CODE_FORBIDDEN_USER, Constant.FORBIDDEN_USER_REASON_DESC);
      }
      // 采用redis事务防止一个微信号多次注册问题
      String watchKey = StringUtil.Md5("REGISTER:" + weiXinUser.getUnionid());
      Jedis jedis = jedisPool.getResource();
      try {
         jedis.watch(watchKey);
         if (jedis.get(watchKey) != null && Integer.parseInt(jedis.get(watchKey)) > 1)
            throw new UserAccountException(10, "请稍后再试");
         Transaction tran = jedis.multi();
         tran.incr(watchKey);
         List<Object> exec = tran.exec();
         if (exec == null || exec.size() == 0) {
            throw new UserAccountException(10, "请稍后再试");
         } else {
            UserInfo userInfo = userInfoMapper.getEffectiveUserInfoByWXUnionId(weiXinUser.getUnionid());
            // 直接用的微信登录
            if (userInfo != null) {
               LogHelper.test("微信unionID存在:" + weiXinUser.getUnionid());
               // 更新账户登录信息
               updateLonginInfo(userInfo, loginType, request);
               // 删除邀请分享图
               spreadUserImgService.deleteImgUrl(userInfo.getId());
            } else {
               LogHelper.test("微信unionID不存在:" + weiXinUser.getUnionid());
               // 创建新账户
               userInfo = new UserInfo();
               userInfo.setPortrait(weiXinUser.getHeadimgurl());
               userInfo.setAppId(appId);
               userInfo.setNickName(weiXinUser.getNickname());
               userInfo.setWxName(weiXinUser.getNickname());
               userInfo.setWxOpenId(weiXinUser.getOpenid());
               userInfo.setWxUnionId(weiXinUser.getUnionid());
               userInfo.setWxPic(weiXinUser.getHeadimgurl());
               userInfo.setLastLoginTime(System.currentTimeMillis());
               userInfo.setLoginType(loginType);
               userInfo.setLastLoginIp(request.getRemoteHost());
               userInfo.setState(UserInfo.STATE_NORMAL);
               addUser(userInfo);
               try {
                  // 第一次登录时创建用户额外信息
                  userInfoExtraService.createUserInfoExtra(userInfo.getId());
               } catch (Exception e) {
                  e.printStackTrace();
               }
            }
            return userInfo;
         }
      } catch (Exception e) {
         e.printStackTrace();
      } finally {
         jedis.del(watchKey);
         jedis.unwatch();
         jedisPool.returnResource(jedis);
      }
      throw new UserAccountException(10, "请稍后再试");
   }
   /**
    * 更新账户登录信息
    *
    * @param userInfo
    * @param loginType
    * @param request
    */
   public void updateLonginInfo(UserInfo userInfo, int loginType, HttpServletRequest request) {
      // 设置登录时间与登录类型
      UserInfo updateUserInfo = new UserInfo(userInfo.getId());
      updateUserInfo.setLastLoginTime(System.currentTimeMillis());
      updateUserInfo.setLoginType(loginType);
      updateUserInfo.setLastLoginIp(request.getRemoteHost());
      userInfoMapper.updateByPrimaryKeySelective(updateUserInfo);
   }
   @Override
   public void bindPhoneNew(Long uid, String phone) throws UserAccountException {
      UserInfo user = userInfoMapper.selectByPrimaryKey(uid);
      if (user == null) {
         throw new UserAccountException(1, "用户不存在");
      }
      String hasPhone = user.getPhone();
      if (!StringUtil.isNullOrEmpty(hasPhone) && hasPhone.equals(phone)) {
         throw new UserAccountException(2, "您已经绑定了该电话号码");
      }
      UserInfo phoneUser = userInfoMapper.getEffectiveUserInfoByPhone(phone);
      if (phoneUser != null) {
         throw new UserAccountException(2, "号码已经被占用");
      }
      // 更新电话号码
      UserInfo update = new UserInfo(user.getId());
      update.setPhone(phone);
      userInfoMapper.updateByPrimaryKeySelective(update);
      // 加入绑定记录
      UserAccountBindingHistory history = new UserAccountBindingHistory();
      history.setContent(phone);
      history.setType(UserAccountBindingHistory.TYPE_PHONE);
      history.setUid(uid);
      // 之前已经绑定电话号码
      if (!StringUtil.isNullOrEmpty(user.getPhone()))
         history.setFirst(false);
      else
         history.setFirst(true);
      userAccountBindingHistoryService.addUserAccountBindingHistory(history);
      // 发送消息
      userAccountMsgNotificationService.bindingSuccess(uid, MsgAccountDetailFactory.TYPE_PHONE);
   }
   @Override
   public void bindWeiXin(Long uid, String code) throws UserAccountException {
      UserInfo user = userInfoMapper.selectByPrimaryKey(uid);
      if (user == null) {
         throw new UserAccountException(1, "用户不存在");
      }
      WeiXinUser weiXinUser = WXLoginUtil.getWeiXinUserWithSavePortrait(code);
      if (weiXinUser == null) {
         throw new UserAccountException(2, "微信帐号授权失败");
      }
      String wxUnionId = weiXinUser.getUnionid();
      if (StringUtil.isNullOrEmpty(wxUnionId)) {
         throw new UserAccountException(2, "微信帐号授权失败");
      }
      String wxUnionIdExist = user.getWxUnionId();
      if (StringUtil.isNullOrEmpty(wxUnionIdExist)) {
         UserInfo newUser = userInfoMapper.getEffectiveUserInfoByWXUnionId(wxUnionId);
         if (newUser != null) {
            throw new UserAccountException(4, "该微信号已被其他帐号绑定");
         }
      } else if (wxUnionId.equals(wxUnionIdExist)) {
         throw new UserAccountException(3, "微信帐号一致无需更换");
      }
      if (StringUtil.isNullOrEmpty(user.getPhone())) {
         throw new UserAccountException(5, "该帐号没有绑定手机号码,需绑定手机号码才能完成微信更换");
      }
      UserInfo updateUserInfo = new UserInfo(uid);
      updateUserInfo.setWxName(weiXinUser.getNickname());
      updateUserInfo.setWxOpenId(weiXinUser.getOpenid());
      updateUserInfo.setWxPic(weiXinUser.getHeadimgurl());
      updateUserInfo.setWxUnionId(weiXinUser.getUnionid());
      // 将默认昵称替换成微信昵称
      String defaultNickName = Constant.systemCommonConfig.getDefaultNickName();
      if (!StringUtil.isNullOrEmpty(weiXinUser.getNickname()) && !StringUtil.isNullOrEmpty(defaultNickName)
            && defaultNickName.equals(user.getNickName())) {
         updateUserInfo.setNickName(weiXinUser.getNickname());
      }
      // 将默认头像替换成微信头像
      String defaultPortrait = Constant.systemCommonConfig.getDefaultPortrait();
      if (!StringUtil.isNullOrEmpty(weiXinUser.getHeadimgurl()) && !StringUtil.isNullOrEmpty(defaultPortrait)
            && defaultPortrait.equals(user.getPortrait())) {
         updateUserInfo.setPortrait(weiXinUser.getHeadimgurl());
      }
      userInfoMapper.updateByPrimaryKeySelective(updateUserInfo);
      // 加入绑定记录
      UserAccountBindingHistory history = new UserAccountBindingHistory();
      history.setContent(weiXinUser.getUnionid());
      history.setType(UserAccountBindingHistory.TYPE_WX);
      history.setUid(uid);
      // 之前已经绑定电话号码
      if (!StringUtil.isNullOrEmpty(user.getWxUnionId()))
         history.setFirst(false);
      else
         history.setFirst(true);
      userAccountBindingHistoryService.addUserAccountBindingHistory(history);
      userAccountMsgNotificationService.bindingSuccess(uid, MsgAccountDetailFactory.TYPE_WX);
   }
   @Override
   public void forbiddenUserAll(Long uid, String reason) {
      UserInfo currentInfo = userInfoService.selectByPKey(uid);
      if (currentInfo == null) {
         return;
      }
      if (currentInfo.getState() != UserInfo.STATE_NORMAL) {
         return;
      }
      currentInfo.setState(UserInfo.STATE_FORBIDDEN);
      currentInfo.setStateDesc(reason);
      userInfoService.updateByPrimaryKeySelective(currentInfo);
      // 插入记录
      userInfoDeleteRecordService.addDeleteRecord(uid, UserInfo.STATE_FORBIDDEN, reason);
      // 加入封禁的账号列表
      ForbiddenUserIdentifyCode forbiddenUserIdentifyCode = new ForbiddenUserIdentifyCode();
      forbiddenUserIdentifyCode.setType(ForbiddenUserIdentifyCodeTypeEnum.wxUnionId);
      forbiddenUserIdentifyCode.setIdentifyCode(currentInfo.getWxUnionId());
      forbiddenUserIdentifyCode.setBeiZhu(currentInfo.getWxName());
      try {
         forbiddenUserIdentifyCodeService.forbiddenIdentifyCode(forbiddenUserIdentifyCode);
      } catch (ForbiddenUserIdentifyCodeException e) {
         e.printStackTrace();
      }
      // 电话号码
      forbiddenUserIdentifyCode = new ForbiddenUserIdentifyCode();
      forbiddenUserIdentifyCode.setType(ForbiddenUserIdentifyCodeTypeEnum.phone);
      forbiddenUserIdentifyCode.setIdentifyCode(currentInfo.getPhone());
      try {
         forbiddenUserIdentifyCodeService.forbiddenIdentifyCode(forbiddenUserIdentifyCode);
      } catch (ForbiddenUserIdentifyCodeException e) {
         e.printStackTrace();
      }
      // 淘宝
      UserExtraTaoBaoInfo taoBao = userExtraTaoBaoInfoService.getByUid(uid);
      if (taoBao != null && !StringUtil.isNullOrEmpty(taoBao.getTaoBaoUid())) {
         forbiddenUserIdentifyCode = new ForbiddenUserIdentifyCode();
         forbiddenUserIdentifyCode.setType(ForbiddenUserIdentifyCodeTypeEnum.taobaoUid);
         forbiddenUserIdentifyCode.setIdentifyCode(taoBao.getTaoBaoUid());
         try {
            forbiddenUserIdentifyCodeService.forbiddenIdentifyCode(forbiddenUserIdentifyCode);
         } catch (ForbiddenUserIdentifyCodeException e) {
            e.printStackTrace();
         }
      }
      // 查询支付宝绑定
      List<BindingAccount> list = bindingAccountService.getBindingAccountByUid(uid);
      if (list != null) {
         for (BindingAccount ba : list) {
            forbiddenUserIdentifyCode = new ForbiddenUserIdentifyCode();
            forbiddenUserIdentifyCode.setType(ForbiddenUserIdentifyCodeTypeEnum.alipayAccount);
            forbiddenUserIdentifyCode.setIdentifyCode(ba.getAccount());
            forbiddenUserIdentifyCode.setBeiZhu(ba.getName());
            try {
               forbiddenUserIdentifyCodeService.forbiddenIdentifyCode(forbiddenUserIdentifyCode);
            } catch (ForbiddenUserIdentifyCodeException e) {
               e.printStackTrace();
            }
         }
      }
   }
   @Override
   public void forbiddenUser(Long uid, String reason) {
      UserInfo currentInfo = userInfoService.selectByPKey(uid);
      if (currentInfo == null) {
         return;
      }
      if (currentInfo.getState() != UserInfo.STATE_NORMAL) {
         return;
      }
      currentInfo.setState(UserInfo.STATE_FORBIDDEN);
      currentInfo.setStateDesc(reason);
      userInfoService.updateByPrimaryKeySelective(currentInfo);
      // 插入记录
      userInfoDeleteRecordService.addDeleteRecord(uid, UserInfo.STATE_FORBIDDEN, reason);
   }
   @Override
   public void DeleteUser(Long uid, String reason) {
      UserInfo currentInfo = userInfoService.selectByPKey(uid);
      if (currentInfo == null) {
         return;
      }
      if (currentInfo.getState() != UserInfo.STATE_NORMAL) {
         return;
      }
      currentInfo.setState(UserInfo.STATE_DELETE);
      currentInfo.setStateDesc(reason);
      userInfoService.updateByPrimaryKeySelective(currentInfo);
      // 插入记录
      userInfoDeleteRecordService.addDeleteRecord(uid, UserInfo.STATE_DELETE, reason);
   }
   @Override
   public void DeleteUserOutOfDate(Long uid, String reason) {
      UserInfo currentInfo = userInfoService.selectByPKey(uid);
      if (currentInfo == null) {
         return;
      }
      if (currentInfo.getState() != UserInfo.STATE_NORMAL) {
         return;
      }
      currentInfo.setState(UserInfo.STATE_DELETE_OUT_OF_DATE);
      currentInfo.setStateDesc(reason);
      userInfoService.updateByPrimaryKeySelective(currentInfo);
      // 插入记录
      userInfoDeleteRecordService.addDeleteRecord(uid, UserInfo.STATE_DELETE_OUT_OF_DATE, reason);
   }
}