package com.huiju.estateagents.third.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.github.binarywang.wxpay.bean.request.WxPaySendRedpackRequest;
import com.github.binarywang.wxpay.bean.result.WxPaySendRedpackResult;
import com.github.binarywang.wxpay.config.WxPayConfig;
import com.github.binarywang.wxpay.exception.WxPayException;
import com.github.binarywang.wxpay.service.WxPayService;
import com.github.binarywang.wxpay.service.impl.WxPayServiceImpl;
import com.huiju.estateagents.base.ResponseBean;
import com.huiju.estateagents.common.CommConstant;
import com.huiju.estateagents.common.CommonUtils;
import com.huiju.estateagents.common.JWTUtils;
import com.huiju.estateagents.common.MD5Utils;
import com.huiju.estateagents.drainage.entity.TaDrainage;
import com.huiju.estateagents.drainage.mapper.TaDrainageMapper;
import com.huiju.estateagents.entity.TaPerson;
import com.huiju.estateagents.entity.TaWxPayConfig;
import com.huiju.estateagents.mapper.TaPersonMapper;
import com.huiju.estateagents.mapper.TaWxPayConfigMapper;
import com.huiju.estateagents.redpack.entity.*;
import com.huiju.estateagents.redpack.mapper.*;
import com.huiju.estateagents.third.entity.TaThirdPartyMiniappConfig;
import com.huiju.estateagents.third.mapper.TaThirdPartyMiniappConfigMapper;
import com.huiju.estateagents.third.service.ITaThirdPartyMiniappConfigService;
import me.chanjar.weixin.mp.bean.result.WxMpOAuth2AccessToken;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.net.InetAddress;
import java.time.LocalDateTime;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Random;
import java.util.stream.Collectors;

/**
 * <p>
 * 服务实现类
 * </p>
 *
 * @author jobob
 * @since 2019-10-17
 */
@Service
public class TaThirdPartyMiniappConfigServiceImpl extends ServiceImpl<TaThirdPartyMiniappConfigMapper, TaThirdPartyMiniappConfig> implements ITaThirdPartyMiniappConfigService {

    private Logger logger = LoggerFactory.getLogger(TaThirdPartyMiniappConfigServiceImpl.class);

    @Autowired
    private TaThirdPartyMiniappConfigMapper taThirdPartyMiniappConfigMapper;

    @Autowired
    private TaMpPersonMapper taMpPersonMapper;

    @Autowired
    private TaMpMiniappMapper taMpMiniappMapper;

    @Autowired
    private TaDrainageMapper taDrainageMapper;

    @Autowired
    private TaRedPacketMapper taRedPacketMapper;

    @Autowired
    private TaRedPacketPersonMapper taRedPacketPersonMapper;

    @Autowired
    private TaRedPacketHelpMapper taRedPacketHelpMapper;

    @Autowired
    private TaRedPacketHistoryMapper taRedPacketHistoryMapper;

    @Autowired
    private TaRedPacketMoneyMapper taRedPacketmonetMapper;

    @Autowired
    private TaWxPayConfigMapper taWxPayConfigMapper;

    @Autowired
    private TaRedPacketClientMapper taRedPacketClientMapper;

    @Autowired
    private TaOrgAccountMapper taOrgAccountMapper;

    @Autowired
    private TaOrgOrderMapper taOrgOrderMapper;

    @Autowired
    private TaOrgOrderDetailMapper taOrgOrderDetailMapper;

    @Autowired
    private TaOrgAccountDetailedListMapper taOrgAccountDetailedListMapper;

    @Autowired
    private TaPersonMapper taPersonMapper;

    @Autowired
    private TaH5ImagesMapper taH5ImagesMapper;

    /**
     * 校验是否合法第三方接口调用
     *
     * @param tokenHeader
     * @param appidHeader
     * @param nowHeader
     * @return
     */
    @Override
    public String checkToken(String tokenHeader, String appidHeader, String nowHeader) {
        //秘钥是否过期
        QueryWrapper<TaThirdPartyMiniappConfig> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("appid", appidHeader);
        TaThirdPartyMiniappConfig taThirdPartyMiniappConfig = taThirdPartyMiniappConfigMapper.selectOne(queryWrapper);
//		if (LocalDateTime.now().isAfter(taThirdPartyMiniappConfig.getExpirationDate())){
//			return "秘钥已过期，请重新申请";
//		}

        //判断nowHeader是十五分钟之内(15 * 60 * 1000)
        if (System.currentTimeMillis() - Long.valueOf(nowHeader) > (15 * 60 * 1000)) {
            return "密钥超时，请在十五分钟内请求";
        }

        //重新加密对比
        StringBuilder stringBuilder = new StringBuilder();
        stringBuilder.append(taThirdPartyMiniappConfig.getAppid()).append(taThirdPartyMiniappConfig.getAppSecret()).append(nowHeader);
        String token = MD5Utils.md5(MD5Utils.md5(stringBuilder.toString()));
        if (!tokenHeader.equals(token)) {
            return "秘钥出错请重新生成";
        }

        return "success";
    }

    /**
     * 创建公众号人员并关联上小程序人员
     *
     * @param accessToken
     * @param drainageId
     * @param sponsorPersonId
     * @param personId
     */
    @Override
    public Map<String, Object> newMpPerson(WxMpOAuth2AccessToken accessToken, String mpAppid, String drainageId, String sponsorPersonId, String personId) {
        Map<String, Object> map = new HashMap<>();
        //查询这个人员是否存在
        TaMpPerson mpPerson = taMpPersonMapper.selectOne(new QueryWrapper<TaMpPerson>().eq("mp_openid", accessToken.getOpenId()));
        //不存在就新建
        if (null == mpPerson) {
            //新增入公众号人员表
            TaMpPerson taMpPerson = new TaMpPerson();
            taMpPerson.setAppid(mpAppid);
            taMpPerson.setCreateDate(LocalDateTime.now());
            taMpPerson.setMpOpenid(accessToken.getOpenId());
            taMpPerson.setStatus(CommConstant.STATUS_NORMAL);
            taMpPersonMapper.insert(taMpPerson);
            mpPerson = taMpPerson;
        }

        //查看这个人是否绑定了小程序用户
        TaMpMiniapp taMpMiniapp = taMpMiniappMapper.selectOne(new QueryWrapper<TaMpMiniapp>().eq("mp_person_id", mpPerson.getMpPersonId()).eq("miniapp_person_id", personId));
        if (null == taMpMiniapp) {
            taMpMiniapp = new TaMpMiniapp();
            taMpMiniapp.setMpPersonId(mpPerson.getMpPersonId());
            taMpMiniapp.setMiniappPersonId(personId);
            taMpMiniappMapper.insert(taMpMiniapp);
        }

        //我的小程序信息
        TaPerson minePerson = taPersonMapper.selectById(personId);
        map.put("minePerson", minePerson);

        //我要助力的人的小程序信息
        if (StringUtils.isNotEmpty(sponsorPersonId)) {
            TaPerson parentPerson = taPersonMapper.selectById(sponsorPersonId);
            map.put("parentPerson", parentPerson);
        }

        //第一步根据drainggeid查询出红包表对应的记录
        TaDrainage taDrainage = taDrainageMapper.selectById(drainageId);
        //第二步查询出这个H5对应的活动
        TaRedPacket taRedPacket = taRedPacketMapper.selectById(taDrainage.getActivityId());
        // 查询红包配置图片信息
        QueryWrapper<TaH5Images> h5ImagesQueryWrapper = new QueryWrapper<>();
        h5ImagesQueryWrapper.eq("activity_id", taDrainage.getActivityId());
        List<TaH5Images> h5ImagesList = taH5ImagesMapper.selectList(h5ImagesQueryWrapper);
        mapH5Image2RedPackage(h5ImagesList, taRedPacket);

        //活动信息
        map.put("taRedPacket", taRedPacket);
        map.put("taDrainage", taDrainage);

        //是否我的红包助力报名信息
        QueryWrapper<TaRedPacketPerson> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("activity_id", taRedPacket.getActivityId());
        queryWrapper.eq("org_id", taRedPacket.getOrgId());
        queryWrapper.eq("mp_person_id", taMpMiniapp.getMpPersonId());
        queryWrapper.eq("miniapp_person_id", taMpMiniapp.getMiniappPersonId());
        TaRedPacketPerson mineRedPacketPerson = taRedPacketPersonMapper.selectOne(queryWrapper);
        map.put("mineRedPacketPerson", mineRedPacketPerson);

        //查看我的爆红助力列表
        QueryWrapper<TaRedPacketHistory> historyQueryWrapper = new QueryWrapper<>();
        historyQueryWrapper.eq("activity_id", taRedPacket.getActivityId());
        historyQueryWrapper.eq("org_id", taRedPacket.getOrgId());
        historyQueryWrapper.eq("target_mp_person", taMpMiniapp.getMpPersonId());
        historyQueryWrapper.eq("target_miniapp_person", taMpMiniapp.getMiniappPersonId());
        List<TaRedPacketHistory> taRedPacketHistories = taRedPacketHistoryMapper.selectList(historyQueryWrapper);
        map.put("taRedPacketHistories", taRedPacketHistories);

        //根据活动id查询这个活动的助力规则
        TaRedPacketHelp taRedPacketHelp = taRedPacketHelpMapper.selectById(taDrainage.getActivityId());
        map.put("taRedPacketHelp", taRedPacketHelp);

        //token
        Map<Object, Object> tokenMap = new HashMap<>();
        tokenMap.put("openId", accessToken.getOpenId());
        tokenMap.put("orgId", taRedPacket.getOrgId());
        tokenMap.put("personId", taMpMiniapp.getMiniappPersonId());//小程序的personid
        map.put("token", JWTUtils.newTokenByMap(tokenMap));

        return map;
    }

    /**
     * 参加活动生成参与记录等
     *
     * @param mpAppid    公众号appid
     * @param personId   小程序人员id
     * @param drainageId H5活动id
     */
    @Override
    public ResponseBean participateActivity(String mpAppid, String personId, String drainageId) {
        //第一步根据drainggeid查询出红包表对应的记录
        TaDrainage taDrainage = taDrainageMapper.selectById(drainageId);
        //第二步查询出这个H5对应的活动
        TaRedPacket taRedPacket = taRedPacketMapper.selectById(taDrainage.getActivityId());
        //判断这个活动的过期时间
        if (LocalDateTime.now().isAfter(taRedPacket.getEndDate())) {
            return ResponseBean.error(taRedPacket.getActivityEndTip(), ResponseBean.ERROR_ILLEGAL_PARAMS);
        }
        if (LocalDateTime.now().isBefore(taRedPacket.getStartDate())) {
            return ResponseBean.error("此活动未开始", ResponseBean.ERROR_ILLEGAL_PARAMS);
        }

        //参与活动
        TaRedPacketPerson taRedPacketPerson = saveRedPacketPerson(personId, taRedPacket, taDrainage.getOrgId());

        return ResponseBean.success(taRedPacketPerson);
    }

    /**
     * 参与活动方法--悲观锁
     *
     * @param personId
     * @param taRedPacket
     * @param orgId
     */
    private synchronized TaRedPacketPerson saveRedPacketPerson(String personId, TaRedPacket taRedPacket, Integer orgId) {
        //查看这个人绑定的小程序用户
        TaMpMiniapp taMpMiniapp = taMpMiniappMapper.selectOne(new QueryWrapper<TaMpMiniapp>().eq("miniapp_person_id", personId));

        //查看此人是否参加过活动如果参加过直接返回
        QueryWrapper<TaRedPacketPerson> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("activity_id", taRedPacket.getActivityId());
        queryWrapper.eq("org_id", orgId);
        queryWrapper.eq("mp_person_id", taMpMiniapp.getMpPersonId());
        queryWrapper.eq("miniapp_person_id", taMpMiniapp.getMiniappPersonId());
        TaRedPacketPerson redPacketPerson = taRedPacketPersonMapper.selectOne(queryWrapper);
        if (null != redPacketPerson) {
            return redPacketPerson;
        }

        //参与活动
        TaRedPacketPerson taRedPacketPerson = new TaRedPacketPerson();
        taRedPacketPerson.setActivityId(taRedPacket.getActivityId());
        taRedPacketPerson.setCreateDate(LocalDateTime.now());
        taRedPacketPerson.setIsSignedUp(true);
        taRedPacketPerson.setMiniappPersonId(taMpMiniapp.getMiniappPersonId());
        taRedPacketPerson.setMpPersonId(taMpMiniapp.getMpPersonId());
        taRedPacketPerson.setOrgId(orgId);
        taRedPacketPersonMapper.insert(taRedPacketPerson);
        return taRedPacketPerson;
    }

    /**
     * 助力活动接口
     *
     * @param mpAppid         公众号appid
     * @param personId        小程序personId
     * @param sponsorPersonId 公众号发起人id
     * @param drainageId      H5活动id
     * @return
     */
    @Override
    public ResponseBean helpActivity(String mpAppid, String personId, String sponsorPersonId, String drainageId) {
        logger.info("发起助力接收参数：mpAppid:{}，personId：{}，sponsorPersonId：{}，drainageId：{}", mpAppid, personId, sponsorPersonId, drainageId);
        //第一步根据drainggeid查询出红包表对应的记录
        TaDrainage taDrainage = taDrainageMapper.selectById(drainageId);
        //第二步查询出这个H5对应的活动
        TaRedPacket taRedPacket = taRedPacketMapper.selectById(taDrainage.getActivityId());
        //判断这个活动的过期时间
        if (LocalDateTime.now().isAfter(taRedPacket.getEndDate())) {
            return ResponseBean.error(taRedPacket.getActivityEndTip(), ResponseBean.ERROR_ILLEGAL_PARAMS);
        }
        if (LocalDateTime.now().isBefore(taRedPacket.getStartDate())) {
            return ResponseBean.error("此活动未开始", ResponseBean.ERROR_ILLEGAL_PARAMS);
        }

        //查看这个人绑定的小程序用户
        TaMpMiniapp taMpMiniapp = taMpMiniappMapper.selectOne(new QueryWrapper<TaMpMiniapp>().eq("miniapp_person_id", personId));

        //查询被助力者的绑定的小程序用户
        TaMpMiniapp parentMpMiniapp = taMpMiniappMapper.selectOne(new QueryWrapper<TaMpMiniapp>().eq("miniapp_person_id", sponsorPersonId));

        //根据活动id查询这个活动的助力规则
        TaRedPacketHelp taRedPacketHelp = taRedPacketHelpMapper.selectById(taDrainage.getActivityId());

        //助力
        String result = saveRedPacketHistory(taMpMiniapp, parentMpMiniapp, taRedPacketHelp, taDrainage.getOrgId(), mpAppid);
        if (!"success".equals(result)) {
            return ResponseBean.error(result, ResponseBean.ERROR_ILLEGAL_PARAMS);
        }

        return ResponseBean.success(taRedPacketHelp.getSuccessTip());
    }

    /**
     * 获取活动排行榜
     *
     * @param drainageId
     * @return
     */
    @Override
    public ResponseBean getRanking(String drainageId) {
        //第一步根据drainggeid查询出红包表对应的记录
        TaDrainage taDrainage = taDrainageMapper.selectById(drainageId);

        int top = 100;
        if(taDrainage.getActivityType()=="RedPacket"){
            TaRedPacket taRedPacket = taRedPacketMapper.selectById(taDrainage.getActivityId());
            top = taRedPacket.getTopLimitPersons();
        }

//                .selectById(taDrainage.getActivityId())
        //第二步查询出这个H5对应的活动
        List<TaRedPacketHistory> taRedPacketHistoryList = taRedPacketHistoryMapper.getRanking(taDrainage.getActivityId(), taDrainage.getOrgId(), top);
        return ResponseBean.success(taRedPacketHistoryList);
    }

    /**
     * 根据personiD获取相关信息
     *
     * @param mpAppid
     * @param drainageId
     * @param personId
     * @return
     */
    @Override
    public Map<String, Object> getPersonInfo(String mpAppid, String drainageId, String personId) {
        Map<String, Object> map = new HashMap<>();
        // 查看这个人是否绑定了小程序用户
        TaMpMiniapp taMpMiniapp = taMpMiniappMapper.selectOne(new QueryWrapper<TaMpMiniapp>().eq("miniapp_person_id", personId));

        // 我的小程序信息
        TaPerson minePerson = taPersonMapper.selectById(personId);
        map.put("minePerson", minePerson);

        // 第一步根据drainggeid查询出红包表对应的记录
        TaDrainage taDrainage = taDrainageMapper.selectById(drainageId);
        // 第二步查询出这个H5对应的活动
        TaRedPacket taRedPacket = taRedPacketMapper.selectById(taDrainage.getActivityId());

        // 查询红包配置图片信息
        QueryWrapper<TaH5Images> h5ImagesQueryWrapper = new QueryWrapper<>();
        h5ImagesQueryWrapper.eq("activity_id", taDrainage.getActivityId());
        List<TaH5Images> h5ImagesList = taH5ImagesMapper.selectList(h5ImagesQueryWrapper);
        mapH5Image2RedPackage(h5ImagesList, taRedPacket);

        // 活动信息
        map.put("taRedPacket", taRedPacket);

        // 是否我的红包助力报名信息
        QueryWrapper<TaRedPacketPerson> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("activity_id", taRedPacket.getActivityId());
        queryWrapper.eq("org_id", taRedPacket.getOrgId());
        queryWrapper.eq("mp_person_id", taMpMiniapp.getMpPersonId());
        queryWrapper.eq("miniapp_person_id", taMpMiniapp.getMiniappPersonId());
        TaRedPacketPerson mineRedPacketPerson = taRedPacketPersonMapper.selectOne(queryWrapper);
        map.put("mineRedPacketPerson", mineRedPacketPerson);

        // 根据活动id查询这个活动的助力规则
        TaRedPacketHelp taRedPacketHelp = taRedPacketHelpMapper.selectById(taDrainage.getActivityId());
        map.put("taRedPacketHelp", taRedPacketHelp);

        // 查看我的爆红助力列表
        QueryWrapper<TaRedPacketHistory> historyQueryWrapper = new QueryWrapper<>();
        historyQueryWrapper.eq("activity_id", taRedPacket.getActivityId());
        historyQueryWrapper.eq("org_id", taRedPacket.getOrgId());
        historyQueryWrapper.eq("target_mp_person", taMpMiniapp.getMpPersonId());
        historyQueryWrapper.eq("target_miniapp_person", taMpMiniapp.getMiniappPersonId());
        List<TaRedPacketHistory> taRedPacketHistories = taRedPacketHistoryMapper.selectList(historyQueryWrapper);
        map.put("taRedPacketHistories", taRedPacketHistories);
        return map;
    }

    private void mapH5Image2RedPackage(List<TaH5Images> h5ImagesList, TaRedPacket taRedPacket) {
        h5ImagesList.stream().forEach(r -> {
            String img = r.getImageUrl();

            switch (r.getImageType()) {
                case "RedPacket.rp_share_post_img":
                    taRedPacket.setSharePosterImg(img);
                    break;
                case "RedPacket.rp_activity_rules_img":
                    taRedPacket.setActivityRulesImg(img);
                    break;
                case "RedPacket.rp_help_background_img":
                    taRedPacket.setHelpBackgroundImg(img);
                    break;
                case "RedPacket.rp_index_background_img":
                    taRedPacket.setIndexBackgroundImg(img);
                    break;
                case "RedPacket.rp_ranking_background_img":
                    taRedPacket.setRankingBackgroundImg(img);
                    break;

                case "RedPacket.rp_invite_btn_img":
                    taRedPacket.setInviteBtnImg(img);
                    break;

                case "RedPacket.rp_rule_btn_img":
                    taRedPacket.setRuleBtnImg(img);
                    break;

                case "RedPacket.rp_join_btn_img":
                    taRedPacket.setJoinBtnImg(img);
                    break;

                case "RedPacket.rp_top_btn_img":
                    taRedPacket.setTopBtnImg(img);
                    break;

                case "RedPacket.rp_home_btn_img":
                    taRedPacket.setHomeBtnImg(img);
                    break;

                case "RedPacket.rp_help_btn_img":
                    taRedPacket.setHelpBtnImg(img);
                    break;

                case "RedPacket.rp_back_btn_img":
                    taRedPacket.setBackBtnImg(img);
                    break;

                case "RedPacket.rp_poster_btn_img":
                    taRedPacket.setPosterBtnImg(img);
                    break;

                case "RedPacket.rp_building_btn_img":
                    taRedPacket.setBuildingBtnImg(img);
                    break;
                default:
                    break;
            }
        });
    }

    private synchronized String saveRedPacketHistory(TaMpMiniapp taMpMiniapp, TaMpMiniapp parentMpMiniapp, TaRedPacketHelp taRedPacketHelp, Integer orgId, String mpAppid) {
        logger.info("发起助力 saveRedPacketHistory 接收参数：taMpMiniapp：{}，parentMpMiniapp：{}，taRedPacketHelp：{}",JSONObject.toJSONString(taMpMiniapp),JSONObject.toJSONString(parentMpMiniapp),JSONObject.toJSONString(taRedPacketHelp));
        //查看我是否助力过
        QueryWrapper<TaRedPacketHistory> queryWrapper = new QueryWrapper();
        queryWrapper.eq("activity_id", taRedPacketHelp.getActivityId());
        queryWrapper.eq("org_id", orgId);
        queryWrapper.eq("from_mp_person", taMpMiniapp.getMpPersonId());
        queryWrapper.eq("from_miniapp_person", taMpMiniapp.getMiniappPersonId());
        List<TaRedPacketHistory> taRedPacketHistories = taRedPacketHistoryMapper.selectList(queryWrapper);
        //校验总助力次数
        if (taRedPacketHistories.size() >= taRedPacketHelp.getLimitNumPerPerson()) {
            return taRedPacketHelp.getLimitPerPersonIllegalTip();
        }
        //校验单人每日助力次数限制
        List<TaRedPacketHistory> dayHelpList = taRedPacketHistories.stream().filter(e -> e.getCreateDate().toLocalDate().equals(LocalDateTime.now().toLocalDate())).collect(Collectors.toList());
        if (dayHelpList.size() >= taRedPacketHelp.getLimitNumPerDay()) {
            return taRedPacketHelp.getLimitPerDayIllegalTip();
        }
        //校验为同一人助力次数限制
        List<TaRedPacketHistory> eachHelpList = taRedPacketHistories.stream().filter(e -> e.getTargetMiniappPerson().equals(parentMpMiniapp.getMiniappPersonId())).collect(Collectors.toList());
        if (eachHelpList.size() >= taRedPacketHelp.getLimitNumForEachPerson()) {
            return taRedPacketHelp.getLimitForEachPersonIllegalTip();
        }

        //校验还有此次助力成功后是否需要发送红包
        QueryWrapper<TaRedPacketHistory> parentRedPacketHistory = new QueryWrapper();
        parentRedPacketHistory.eq("activity_id", taRedPacketHelp.getActivityId());
        parentRedPacketHistory.eq("org_id", orgId);
        parentRedPacketHistory.eq("target_mp_person", parentMpMiniapp.getMpPersonId());
        parentRedPacketHistory.eq("target_miniapp_person", parentMpMiniapp.getMiniappPersonId());
        List<TaRedPacketHistory> parentRedPacketHistories = taRedPacketHistoryMapper.selectList(parentRedPacketHistory);

        //助力
        TaRedPacketHistory taRedPacketHistory = new TaRedPacketHistory();
        taRedPacketHistory.setActivityId(taRedPacketHelp.getActivityId());
        taRedPacketHistory.setCreateDate(LocalDateTime.now());
        taRedPacketHistory.setFromMiniappPerson(taMpMiniapp.getMiniappPersonId());
        taRedPacketHistory.setFromMpPerson(taMpMiniapp.getMpPersonId());
        taRedPacketHistory.setOrgId(orgId);
        taRedPacketHistory.setTargetMiniappPerson(parentMpMiniapp.getMiniappPersonId());
        taRedPacketHistory.setTargetMpPerson(parentMpMiniapp.getMpPersonId());
        taRedPacketHistoryMapper.insert(taRedPacketHistory);

        //更新此人获得的票数
        QueryWrapper<TaRedPacketPerson> taRedPacketPersonQueryWrapper = new QueryWrapper<>();
        taRedPacketPersonQueryWrapper.eq("activity_id", taRedPacketHelp.getActivityId());
        taRedPacketPersonQueryWrapper.eq("org_id", orgId);
        taRedPacketPersonQueryWrapper.eq("mp_person_id", parentMpMiniapp.getMpPersonId());
        taRedPacketPersonQueryWrapper.eq("miniapp_person_id", parentMpMiniapp.getMiniappPersonId());
        TaRedPacketPerson redPacketPerson = taRedPacketPersonMapper.selectOne(taRedPacketPersonQueryWrapper);
        if (null != redPacketPerson) {
            redPacketPerson.setVotes(redPacketPerson.getVotes() + 1);
            taRedPacketPersonMapper.updateById(redPacketPerson);
        }

        //查看是否助力成功发送红包
        if (parentRedPacketHistories.size() + 1 == taRedPacketHelp.getHelpSuccesPersons()) {
            //发送红包
            sendRedPackage(taMpMiniapp, parentMpMiniapp, taRedPacketHelp, orgId, mpAppid, redPacketPerson);
        }

        return "success";
    }

    /**
     * 发送红包
     *
     * @param taMpMiniapp
     * @param parentMpMiniapp
     * @param taRedPacketHelp
     * @param orgId
     * @param mpAppid
     */
    private synchronized void sendRedPackage(TaMpMiniapp taMpMiniapp, TaMpMiniapp parentMpMiniapp, TaRedPacketHelp taRedPacketHelp, Integer orgId, String mpAppid, TaRedPacketPerson redPacketPerson) {
        //红包金额设置相关信息
        TaRedPacketMoney taRedPacketMoney = taRedPacketmonetMapper.selectById(taRedPacketHelp.getActivityId());
        //总账户金额
        TaOrgAccount taOrgAccount = taOrgAccountMapper.selectOne(new QueryWrapper<TaOrgAccount>().eq("org_id", orgId).eq("status", CommConstant.STATUS_NORMAL));

        //发送红包已达上限
        if (taRedPacketMoney.getLimitPacketNum() != -1 && taRedPacketMoney.getPacketSendedNum() + 1 > taRedPacketMoney.getLimitPacketNum()) {
            return;
        }
        //获取红包的随机数
        int redPackageMoney = getRedPackageMoney(taRedPacketMoney.getMaxPacket(), taRedPacketMoney.getMinPacket());
        redPackageMoney = taOrgAccount.getAvailableBalance() < redPackageMoney ? taOrgAccount.getAvailableBalance() : redPackageMoney;

        //金额不足直接返回
        if (taRedPacketMoney.getBalance()  < redPackageMoney) {
            return;
        }
        //账户余额不足
        if (taOrgAccount.getAvailableBalance() < redPackageMoney) {
            return;
        }

        //获取红包支付相关的配置
        TaRedPacketClient taRedPacketClient = taRedPacketClientMapper.selectById(taRedPacketHelp.getActivityId());
        //获取收红包人的openid
        TaMpPerson parentMpPerson = taMpPersonMapper.selectById(parentMpMiniapp.getMpPersonId());
        //发送红包
        String tradeNo = CommonUtils.generateTradeNo("HB");
        WxPayService wxPayService = getWxPayService();
        WxPaySendRedpackRequest build = WxPaySendRedpackRequest.newBuilder()
//				.consumeMchId(wxPayService.getConfig().getMchId())
                .actName(taRedPacketClient.getActivityName())//活动名称
                .clientIp(String.valueOf(InetAddress.getLoopbackAddress()))//Ip地址
                .mchBillNo(tradeNo)//商户订单号
//				.msgAppid(mpAppid)
                .remark(taRedPacketClient.getRemark())//备注
                .reOpenid(parentMpPerson.getMpOpenid())//接受红包的用户openid

                .sceneId("PRODUCT_1")//场景id
                .sendName(taRedPacketClient.getMchName())//红包发送者名称
                .totalAmount(redPackageMoney)//付款金额，单位分
                .totalNum(1)//红包发放总人数
                .wishing(taRedPacketClient.getBlessing())//红包祝福语
                .wxAppid(mpAppid)//公众账号appid
                .build();
        try {
            logger.info("发起助力 发送微信红包请求参数：{}", JSONObject.toJSONString(build));
            WxPaySendRedpackResult wxPaySendRedpackResult = wxPayService.sendRedpack(build);
            logger.info("发起助力 发送微信红包返回结果：{}", JSONObject.toJSONString(wxPaySendRedpackResult));
            String resultCode = wxPaySendRedpackResult.getResultCode();
            if (resultCode.equals("SUCCESS")) {
                taRedPacketMoney.setPacketSendedNum(taRedPacketMoney.getPacketSendedNum() + 1);
                taRedPacketmonetMapper.updateById(taRedPacketMoney);
                //插入订单表并扣钱反更新
                saveRedpacketOrder(tradeNo, wxPaySendRedpackResult, parentMpMiniapp, taRedPacketHelp, orgId, mpAppid, redPacketPerson, taRedPacketClient);
            } else {
                return;
            }
        } catch (WxPayException e) {
            e.printStackTrace();
        }
    }

    private synchronized void saveRedpacketOrder(String tradeNo, WxPaySendRedpackResult wxPaySendRedpackResult, TaMpMiniapp parentMpMiniapp, TaRedPacketHelp taRedPacketHelp, Integer orgId, String mpAppid, TaRedPacketPerson redPacketPerson, TaRedPacketClient taRedPacketClient) {
        redPacketPerson.setPacketAmount(wxPaySendRedpackResult.getTotalAmount());
        redPacketPerson.setPacketStatus(1);
        redPacketPerson.setIsSuccess(true);
        taRedPacketPersonMapper.updateById(redPacketPerson);
        //先扣钱
        TaOrgAccount taOrgAccount = taOrgAccountMapper.selectOne(new QueryWrapper<TaOrgAccount>().eq("org_id", orgId).eq("status", CommConstant.STATUS_NORMAL));
        taOrgAccount.setRealBalance(taOrgAccount.getRealBalance() - wxPaySendRedpackResult.getTotalAmount());
        taOrgAccount.setAvailableBalance(taOrgAccount.getAvailableBalance() - wxPaySendRedpackResult.getTotalAmount());
        taOrgAccount.setPurchaseAmount(taOrgAccount.getPurchaseAmount() + wxPaySendRedpackResult.getTotalAmount());
        taOrgAccountMapper.updateById(taOrgAccount);
        TaRedPacketMoney taRedPacketMoney = taRedPacketmonetMapper.selectById(taRedPacketHelp.getActivityId());
        taRedPacketMoney.setBalance(taRedPacketMoney.getBalance() - wxPaySendRedpackResult.getTotalAmount());
        taRedPacketmonetMapper.updateById(taRedPacketMoney);

        //插入组织订单表
        TaOrgOrder taOrgOrder = new TaOrgOrder();
        taOrgOrder.setAmount(wxPaySendRedpackResult.getTotalAmount());
        taOrgOrder.setCreateDate(LocalDateTime.now());
        taOrgOrder.setOrgId(orgId);
        taOrgOrder.setPayDate(LocalDateTime.now());
        taOrgOrder.setStatus(CommConstant.STATUS_NORMAL);
        taOrgOrder.setTradeNo(tradeNo);
        taOrgOrder.setTradingStatus(CommConstant.TRADING_STATUS_SUCCESS);
        taOrgOrder.setExpiryDate(LocalDateTime.now().plusMinutes(30));
        taOrgOrder.setRemark(taRedPacketClient.getRemark());
        taOrgOrder.setUserId(0);
        taOrgOrder.setUserName("当前系统");
        taOrgOrderMapper.insert(taOrgOrder);

        //插入组织订单明细表
        TaOrgOrderDetail taOrgOrderDetail = new TaOrgOrderDetail();
        taOrgOrderDetail.setAmount(wxPaySendRedpackResult.getTotalAmount());
        taOrgOrderDetail.setItemType(CommConstant.ITEM_TYPE_REDPACKAGE);
        taOrgOrderDetail.setOrderId(taOrgOrder.getOrderId());
        taOrgOrderDetail.setOrgId(orgId);
        taOrgOrderDetail.setQuantity(1);
        taOrgOrderDetail.setReceiverId(parentMpMiniapp.getMiniappPersonId());
        taOrgOrderDetail.setReceiverMpId(parentMpMiniapp.getMpPersonId());
        TaPerson taPerson = taPersonMapper.selectById(parentMpMiniapp.getMiniappPersonId());
        taOrgOrderDetail.setReceiverName(taPerson.getNickname());
        taOrgOrderDetail.setStatus(CommConstant.STATUS_NORMAL);
        taOrgOrderDetail.setTargetId(taRedPacketHelp.getActivityId());
        taOrgOrderDetail.setTargetType(CommConstant.ITEM_TYPE_REDPACKAGE);
        taOrgOrderDetailMapper.insert(taOrgOrderDetail);

        //插入账户流水表
        TaOrgAccountDetailedList taOrgAccountDetailedList = new TaOrgAccountDetailedList();
        taOrgAccountDetailedList.setAccountId(taOrgAccount.getAccountId());
        taOrgAccountDetailedList.setAmount(wxPaySendRedpackResult.getTotalAmount());
        taOrgAccountDetailedList.setCreateDate(LocalDateTime.now());
        taOrgAccountDetailedList.setOrderId(taOrgOrder.getOrderId());
        taOrgAccountDetailedList.setOrgId(orgId);
        taOrgAccountDetailedList.setSignType(-1);
        taOrgAccountDetailedList.setStatus(CommConstant.STATUS_NORMAL);
        taOrgAccountDetailedList.setRemark(taRedPacketClient.getRemark());
        taOrgAccountDetailedList.setUserId(0);
        taOrgAccountDetailedList.setUserName("当前系统");
        taOrgAccountDetailedListMapper.insert(taOrgAccountDetailedList);

    }

    /**
     * 获取商户号信息
     *
     * @return
     */
    private WxPayService getWxPayService() {
        TaWxPayConfig taWxPayConfig = taWxPayConfigMapper.selectOne(new QueryWrapper<TaWxPayConfig>().eq("org_id", 0));
        WxPayConfig payConfig = new WxPayConfig();
        payConfig.setAppId(StringUtils.trimToNull(taWxPayConfig.getAppid()));
        payConfig.setMchId(StringUtils.trimToNull(taWxPayConfig.getMchId()));
        payConfig.setMchKey(StringUtils.trimToNull(taWxPayConfig.getMchKey()));
        payConfig.setKeyPath(StringUtils.trimToNull(taWxPayConfig.getApiPath()));
        WxPayService wxPayService = new WxPayServiceImpl();
        wxPayService.setConfig(payConfig);
        return wxPayService;
    }

    /**
     * 获取范围值之内的红包的随机数
     *
     * @param maxPacket
     * @param minPacket
     * @return
     */
    private int getRedPackageMoney(Integer maxPacket, Integer minPacket) {
        Random random = new Random();
        return random.nextInt(maxPacket) % (maxPacket - minPacket + 1) + minPacket;
    }
}
