admin
2019-10-26 a56bd9db6b5c989fb2eaecd3a854ac6782b55f95
fanli/src/main/java/com/yeshi/fanli/service/impl/money/extract/ExtractServiceImpl.java
@@ -3,6 +3,8 @@
import java.io.IOException;
import java.io.InputStream;
import java.math.BigDecimal;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.Iterator;
@@ -17,7 +19,9 @@
import org.dom4j.Element;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.yeshi.utils.DateUtil;
import org.yeshi.utils.entity.wx.RedPackParams;
import org.yeshi.utils.entity.wx.RedPackRecord;
import org.yeshi.utils.wx.WXPayUtil;
import com.alipay.api.AlipayApiException;
@@ -950,12 +954,271 @@
   }
   
   
   public void downAutoOpenIdFile() {
   @Override
   public List<UserInfo> preAutoUser() throws Exception {
      int page = 0;
      int pageSize = 100;
      int maxSize = 300;
      Date nowDate = new Date();
      // 一、自动提现针对的用户群: 前提条件:用户在距今60天到90天内未活跃过的用户
      String beganDate = DateUtil.reduceDayTostring(90, nowDate);
      String endDate = DateUtil.reduceDayTostring(60, nowDate);
      // 条件3:距离上一次成功领取微信红包已经超过了30天时间,可在第31天再次下发;
      String receivedDate = DateUtil.reduceDayTostring(30, nowDate);
      // 条件4:距离上一次未成功领取微信红包已经超过了15天时间,可在第16天再次下发;
      String refundDate = DateUtil.reduceDayTostring(15, nowDate);
      
      // 余额最低限制
      BigDecimal minSurplus = BigDecimal.valueOf(Constant.AUTO_EXTRACT_MIN_SURPLUS);
      
      List<UserInfo> list = new ArrayList<UserInfo>();
      
      while (true) {
         // 查询满足条件 1、2 的uid
         List<UserInfo> listUser = userInfoService.getAutoExtractUser(page * pageSize, pageSize, minSurplus, beganDate, endDate);
         if (listUser == null || listUser.isEmpty())
            break;
         List<Long> listId = new ArrayList<Long>();
         for (UserInfo userInfo: listUser) {
            listId.add(userInfo.getId());
         }
         // 查询记录是否满足
         List<Long> listValid = extractWeiXinRecordService.getValidUsers(listId, receivedDate, refundDate);
         if (listValid == null || listValid.isEmpty()) {
            page ++;
            continue;
         }
         for (Long uid: listValid) {
            if (list.size() >= maxSize)
               break;
            for (UserInfo userInfo: listUser) {
               if (list.size() >= maxSize)
                  break;
               if (userInfo.getId().longValue() == uid.longValue()) {
                  list.add(userInfo);
                  break;
               }
            }
         }
         if (list.size() >= maxSize)
            break;
         page ++;
      }
      return list;
   }
   @Override
   public List<String> getAutoExtractOpenIds() throws Exception {
      int page = 0;
      int pageSize = 100;
      int maxSize = 301; // appId + 实际openid300个
      Date nowDate = new Date();
      // 一、自动提现针对的用户群: 前提条件:用户在距今60天到90天内未活跃过的用户
      String beganDate = DateUtil.reduceDayTostring(90, nowDate);
      String endDate = DateUtil.reduceDayTostring(60, nowDate);
      // 条件3:距离上一次成功领取微信红包已经超过了30天时间,可在第31天再次下发;
      String receivedDate = DateUtil.reduceDayTostring(30, nowDate);
      // 条件4:距离上一次未成功领取微信红包已经超过了15天时间,可在第16天再次下发;
      String refundDate = DateUtil.reduceDayTostring(15, nowDate);
      
      // 提现金额
      BigDecimal money = BigDecimal.valueOf(Constant.AUTO_EXTRACT_MONEY);
      // 余额最低限制
      BigDecimal minSurplus = BigDecimal.valueOf(Constant.AUTO_EXTRACT_MIN_SURPLUS);
      
      List<String> listOpendIDs = new ArrayList<String>();
      // 首行appID
      listOpendIDs.add(Constant.getWXAccount(null, null).getAppId());
      while (true) {
         // 查询满足条件 1、2 的uid
         List<UserInfo> listUser = userInfoService.getAutoExtractUser(page * pageSize, pageSize, minSurplus, beganDate, endDate);
         if (listUser == null || listUser.isEmpty())
            break;
         List<Long> listId = new ArrayList<Long>();
         for (UserInfo userInfo: listUser) {
            listId.add(userInfo.getId());
         }
         // 查询记录是否满足
         List<Long> listValid = extractWeiXinRecordService.getValidUsers(listId, receivedDate, refundDate);
         if (listValid == null || listValid.isEmpty()) {
            page ++;
            continue;
         }
         for (Long uid: listValid) {
            UserInfo userInfo = subHongBaoByUid(uid, money, minSurplus);
            if (userInfo != null) {
               listOpendIDs.add(userInfo.getWxOpenId());
               if (listOpendIDs.size() >= maxSize)
                  break;
            }
         }
         if (listOpendIDs.size() >= maxSize)
            break;
         page ++;
      }
      return listOpendIDs;
   }
   @Transactional(rollbackFor = Exception.class)
   private UserInfo subHongBaoByUid(Long uid, BigDecimal money, BigDecimal minSurplus) {
      UserInfo userInfo = userInfoMapper.selectByPrimaryKeyForUpdate(uid);
      if (userInfo != null && !StringUtil.isNullOrEmpty(userInfo.getWxOpenId())
            && !StringUtil.isNullOrEmpty(userInfo.getWxUnionId()) && userInfo.getMyHongBao().compareTo(minSurplus) >= 0) {
         // 微信提现记录
         ExtractWeiXinRecord extractRecord = new ExtractWeiXinRecord();
         extractRecord.setUid(uid);
         extractRecord.setOpenId(userInfo.getWxOpenId());
         extractRecord.setUnionId(userInfo.getWxUnionId());
         extractRecord.setMoney(money);
         extractRecord.setStatus(ExtractWeiXinRecord.SENDING);
         extractRecord.setType(ExtractWeiXinRecord.TYPE_MANUAL);
         extractRecord.setCreateTime(new Date());
         extractRecord.setUpdateTime(new Date());
         extractWeiXinRecordService.insertSelective(extractRecord);
         // 记录id
         Long recordId = extractRecord.getId();
         // 资金明细
         UserMoneyDetail detail = new UserMoneyDetail();
         detail.setCreateTime(new Date());
         detail.setIdentifyCode(StringUtil.Md5(UserMoneyDetailTypeEnum.extractAutoWX.name() + ":" + recordId));
         detail.setMoney(new BigDecimal("-"+ money.toString()));
         detail.setTitle(UserMoneyDetailTypeEnum.extractAutoWX.getDesc());
         detail.setType(UserMoneyDetailTypeEnum.extractAutoWX);
         detail.setUpdateTime(new Date());
         detail.setUserInfo(userInfo);
         // 资金计算
         userMoneyService.subUserMoney(userInfo.getId(), money, detail);
         // 4、发送消息通知
         String desc = "为保障你的账户余额安全,自动提现金额将不会高于5元";
         String beizu = "账户中剩余余额请在本App内完成提现";
         userMoneyMsgNotificationService.extractAuto(extractRecord, "未领取-提现中", desc, beizu);
         // 满足条件返回信息
         return userInfo;
      }
      return null;
   }
   @Override
   public void updateManualExtractRecord(List<RedPackRecord> list) throws ExtractException{
      if (list == null || list.isEmpty())
         throw new ExtractException(1, "红包记录信息为空");
      for (RedPackRecord redPackRecord: list) {
         updateWeiXinRecord(redPackRecord);
      }
   }
   @Transactional(rollbackFor = Exception.class)
   private void updateWeiXinRecord(RedPackRecord redPackRecord){
      if (StringUtil.isNullOrEmpty(redPackRecord.getOpenId()))
         return;
      ExtractWeiXinRecord record  = extractWeiXinRecordService.getByOpenIdAndType(redPackRecord.getOpenId(), ExtractWeiXinRecord.TYPE_MANUAL);
      if (record == null)
         return;
      // 状态过滤
      String statusOld = record.getStatus();
      if (StringUtil.isNullOrEmpty(statusOld) || ExtractWeiXinRecord.REFUND.equals(statusOld)
            || ExtractWeiXinRecord.RECEIVED.equals(statusOld))
         return;
      ExtractWeiXinRecord updeteRecord = new ExtractWeiXinRecord();
      updeteRecord.setId(record.getId());
      updeteRecord.setUpdateTime(new Date());
      String billno = redPackRecord.getBillno();
      if (!StringUtil.isNullOrEmpty(billno)) {
         updeteRecord.setBillno(billno.replace("`", ""));
      }
      String detailno = redPackRecord.getDetailno();
      if (!StringUtil.isNullOrEmpty(detailno)) {
         updeteRecord.setDetailno(detailno.replace("`", ""));
      }
      SimpleDateFormat sdf = new SimpleDateFormat("yyyy/MM/dd HH:mm");
      String rcvTime = redPackRecord.getRcvTime();
      if (!StringUtil.isNullOrEmpty(rcvTime)) {
         try {
            updeteRecord.setRcvTime(sdf.parse(rcvTime));
         } catch (ParseException e) {
            e.printStackTrace();
         }
      }
      String sendTime = redPackRecord.getSendTime();
      if (!StringUtil.isNullOrEmpty(sendTime)) {
         try {
            updeteRecord.setSendTime(sdf.parse(sendTime));
         } catch (ParseException e) {
            e.printStackTrace();
         }
      }
      String status = redPackRecord.getStatus();
      if (!StringUtil.isNullOrEmpty(status)) {
         switch (status) {
            case "已发放待领取":
               status = ExtractWeiXinRecord.SENT;
               break;
            case "过期未领退款":
               status = ExtractWeiXinRecord.REFUND;
               break;
            case "已领取":
               status = ExtractWeiXinRecord.RECEIVED;
               break;
            default:
               status = null;
               break;
         }
      }
      updeteRecord.setStatus(status);
      extractWeiXinRecordService.updateByPrimaryKeySelective(updeteRecord);
      if (ExtractWeiXinRecord.RECEIVED.equals(status)) {
         // 发送消息通知
         userMoneyMsgNotificationService.extractAuto(record, "已领取-已提现", null, null);
      } else if (ExtractWeiXinRecord.REFUND.equals(status)) {
         // 资金明细
         UserMoneyDetail detail = new UserMoneyDetail();
         detail.setCreateTime(new Date());
         detail.setIdentifyCode(StringUtil.Md5(UserMoneyDetailTypeEnum.extractAutoWXRefund.name() + ":" + record.getId()));
         detail.setMoney(record.getMoney());
         detail.setTitle(UserMoneyDetailTypeEnum.extractAutoWXRefund.getDesc());
         detail.setType(UserMoneyDetailTypeEnum.extractAutoWXRefund);
         detail.setUpdateTime(new Date());
         detail.setUserInfo(new UserInfo(record.getUid()));
         // 资金计算
         userMoneyService.addUserMoney(record.getUid(), record.getMoney(), detail);
         // 发送消息通知
         userMoneyMsgNotificationService.extractAuto(record, "已退回-余额中", null, null);
      }
   }
   
}