package com.sqx.modules.app.service.impl;


import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.thread.ThreadUtil;
import cn.hutool.core.util.IdcardUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.aliyun.oss.ClientException;
import com.aliyuncs.CommonRequest;
import com.aliyuncs.CommonResponse;
import com.aliyuncs.DefaultAcsClient;
import com.aliyuncs.IAcsClient;
import com.aliyuncs.http.MethodType;
import com.aliyuncs.profile.DefaultProfile;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.getui.push.v2.sdk.ApiHelper;
import com.getui.push.v2.sdk.GtApiConfiguration;
import com.getui.push.v2.sdk.api.PushApi;
import com.getui.push.v2.sdk.common.ApiResult;
import com.getui.push.v2.sdk.dto.req.Audience;
import com.getui.push.v2.sdk.dto.req.message.PushChannel;
import com.getui.push.v2.sdk.dto.req.message.PushDTO;
import com.getui.push.v2.sdk.dto.req.message.PushMessage;
import com.getui.push.v2.sdk.dto.req.message.android.GTNotification;
import com.getui.push.v2.sdk.dto.req.message.ios.Alert;
import com.getui.push.v2.sdk.dto.req.message.ios.Aps;
import com.getui.push.v2.sdk.dto.req.message.ios.IosDTO;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.github.qcloudsms.SmsSingleSenderResult;
import com.sqx.common.exception.SqxException;
import com.sqx.common.utils.DateUtils;
import com.sqx.common.utils.PageUtils;
import com.sqx.common.utils.Result;
import com.sqx.modules.app.dao.AuthCertNoDTO;
import com.sqx.modules.app.dao.MsgDao;
import com.sqx.modules.app.dao.UserDao;
import com.sqx.modules.app.entity.*;
import com.sqx.modules.app.service.*;
import com.sqx.modules.app.utils.JwtUtils;
import com.sqx.modules.app.utils.UserConstantInterface;
import com.sqx.modules.common.entity.CommonInfo;
import com.sqx.modules.common.service.CommonInfoService;
import com.sqx.modules.discSpinning.service.DiscSpinningService;
import com.sqx.modules.file.utils.Md5Utils;
import com.sqx.modules.invite.service.InviteService;
import com.sqx.modules.message.entity.MessageInfo;
import com.sqx.modules.message.service.MessageService;
import com.sqx.modules.sys.entity.SysUserEntity;
import com.sqx.modules.sys.service.SysUserService;
import com.sqx.modules.utils.HttpClientUtil;
import com.sqx.modules.utils.InvitationCodeUtil;
import com.sqx.modules.utils.MD5Util;
import com.sqx.modules.utils.TimeCompleteUtils;
import com.tencentcloudapi.common.Credential;
import com.tencentcloudapi.common.exception.TencentCloudSDKException;
import com.tencentcloudapi.common.profile.ClientProfile;
import com.tencentcloudapi.common.profile.HttpProfile;
import com.tencentcloudapi.sms.v20210111.SmsClient;
import com.tencentcloudapi.sms.v20210111.models.SendSmsRequest;
import com.tencentcloudapi.sms.v20210111.models.SendSmsResponse;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.codec.digest.DigestUtils;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import weixin.popular.api.SnsAPI;
import weixin.popular.util.JsonUtil;

import javax.servlet.http.HttpServletRequest;
import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.locks.ReentrantReadWriteLock;

/**
 * 用户
 *
 * @author fang
 * @date 2021/2/27
 */

@Service("userService")
@Slf4j
public class UserServiceImpl extends ServiceImpl<UserDao, UserEntity> implements UserService {

    @Autowired
    private CommonInfoService commonInfoService;
    @Autowired
    private MsgDao msgDao;
    @Autowired
    private JwtUtils jwtUtils;
    private int number = 1;
    @Autowired
    private InviteService inviteService;
    @Autowired
    private UserMoneyService userMoneyService;
    @Autowired
    private UserMoneyDetailsService userMoneyDetailsService;
    @Autowired
    private UserVipService userVipService;
    @Autowired
    private MessageService messageService;
    @Autowired
    private CommonInfoService commonRepository;
    @Autowired
    private DiscSpinningService discSpinningService;
    @Autowired
    private SysUserService sysUserService;
    private final AliService aliService;
    private final UserInfoService userInfoService;

    @Value("${spring.profiles.active}")
    private String profiles;

    private ReentrantReadWriteLock reentrantReadWriteLock = new ReentrantReadWriteLock(true);

    public UserServiceImpl(@Lazy AliService aliService, UserInfoService userInfoService) {
        this.aliService = aliService;
        this.userInfoService = userInfoService;
    }

    @Override
    public Result authenticationRegister(JSONObject jsonObject, HttpServletRequest request) {
        reentrantReadWriteLock.writeLock().lock();
        try {
            String apiKey = request.getHeader("apiKey");
            if (StringUtils.isEmpty(apiKey)) {
                return Result.error("请求错误，请检查参数后重试！");
            } else if (StringUtils.isNotEmpty(apiKey)) {
                String value = commonInfoService.findOne(861).getValue();
                if (!apiKey.equals(value)) {
                    return Result.error("请求错误，请检查参数后重试！");
                }
            }
            String phone = jsonObject.getString("phone");
            if (StringUtils.isEmpty(phone)) {
                return Result.error("phone参数不能为空");
            }
            String money = jsonObject.getString("money");
            if (StringUtils.isEmpty(money)) {
                return Result.error("money参数不能为空");
            }
            String idempotentId = jsonObject.getString("idempotentId");
            if (StringUtils.isEmpty(idempotentId)) {
                return Result.error("idempotentId参数不能为空");
            }
            String sign = jsonObject.getString("sign");
            if (StringUtils.isEmpty(sign)) {
                return Result.error("sign参数不能为空");
            }
            String apiSecret = commonInfoService.findOne(862).getValue();
            String signs = MD5Util.md5Encrypt32Upper(phone + money + apiSecret);
            if (!signs.equals(sign)) {
                return Result.error("sign参数错误！");
            }
            MessageInfo messageInfo = messageService.getOne(new QueryWrapper<MessageInfo>().eq("state", 10).eq("platform", idempotentId));
            if (messageInfo != null) {
                //请求已经处理过了
                Map<String, String> result = new HashMap<>();
                result.put("phone", messageInfo.getTitle());
                result.put("userType", messageInfo.getContent());
                return Result.success().put("data", result);
            }
            messageInfo = new MessageInfo();
            messageInfo.setState("10");
            messageInfo.setPlatform(idempotentId);
            messageInfo.setTitle(phone);
            UserEntity userEntity = queryByPhone(phone);
            if (userEntity != null) {
                //老用户
                userMoneyService.updateMoney(1, userEntity.getUserId(), Double.parseDouble(money));
                //inviteMoneyDao.updateInviteMoneySum(money,userId);
                SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                UserMoneyDetails userMoneyDetails = new UserMoneyDetails();
                userMoneyDetails.setUserId(userEntity.getUserId());
                userMoneyDetails.setTitle("[增加金币]赠送金币：" + money);
                userMoneyDetails.setContent("[增加金币]赠送金币：" + money);
                userMoneyDetails.setType(1);
                // ✅
                userMoneyDetails.setClassify(1);
                userMoneyDetails.setMoney(new BigDecimal(money));
                userMoneyDetails.setCreateTime(sdf.format(new Date()));
                userMoneyDetails.setMoneyType(2);
                userMoneyDetailsService.save(userMoneyDetails);

                messageInfo.setContent("2");
            } else {
                //新用户
                userEntity = new UserEntity();
                userEntity.setPhone(phone);
                userEntity.setUserName(userEntity.getPhone().replaceAll("(\\d{3})\\d*([0-9a-zA-Z]{4})", "$1****$2"));
                userEntity.setPassword(DigestUtils.sha256Hex(userEntity.getPhone()));
                userEntity.setInviterCode(commonInfoService.findOne(88).getValue());
                userEntity.setCreateTime(DateUtils.format(new Date()));
                userEntity.setStatus(1);
                baseMapper.insert(userEntity);
                userEntity.setInvitationCode(InvitationCodeUtil.toSerialCode(userEntity.getUserId()));
                baseMapper.updateById(userEntity);

                //赠送金币
                userMoneyService.updateMoney(1, userEntity.getUserId(), Double.parseDouble(money));
                //inviteMoneyDao.updateInviteMoneySum(money,userId);
                SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                UserMoneyDetails userMoneyDetails = new UserMoneyDetails();
                userMoneyDetails.setUserId(userEntity.getUserId());
                userMoneyDetails.setTitle("[增加金币]赠送金币：" + money);
                userMoneyDetails.setContent("[增加金币]赠送金币：" + money);
                userMoneyDetails.setType(1);
                // ✅
                userMoneyDetails.setClassify(1);
                userMoneyDetails.setMoney(new BigDecimal(money));
                userMoneyDetails.setCreateTime(sdf.format(new Date()));
                userMoneyDetails.setMoneyType(2);
                userMoneyDetailsService.save(userMoneyDetails);

                //发送短信
                sendMsg(phone, "newUser", phone);
                messageInfo.setContent("1");
            }
            messageService.save(messageInfo);
            Map<String, String> result = new HashMap<>();
            result.put("phone", messageInfo.getTitle());
            result.put("userType", messageInfo.getContent());
            return Result.success().put("data", result);
        } catch (Exception e) {
            e.printStackTrace();
            log.error("认证注册用户出错：" + e.getMessage(), e);
        } finally {
            reentrantReadWriteLock.writeLock().unlock();
        }
        return Result.error("系统繁忙，请稍后再试！");
    }


    @Override
    public Result getNewUserRed(Long userId) {
        reentrantReadWriteLock.writeLock().lock();
        try {
            UserEntity userEntity = baseMapper.selectById(userId);
            if (userEntity.getIsNewUser() != null && userEntity.getIsNewUser() == 1) {
                return Result.error("您已经领取过了！");
            }
            userEntity.setIsNewUser(1);
            baseMapper.updateById(userEntity);
            String value = commonInfoService.findOne(837).getValue();
            if (StringUtils.isNotEmpty(value)) {
                BigDecimal money = new BigDecimal(value);
                userMoneyService.updateMoney(1, userId, money.doubleValue());
                UserMoneyDetails userMoneyDetails = new UserMoneyDetails();
                userMoneyDetails.setUserId(userId);
                userMoneyDetails.setTitle("[新用户红包]");
                userMoneyDetails.setContent("增加金币：" + money);
                userMoneyDetails.setType(1);
                // ✅
                userMoneyDetails.setClassify(1);
                userMoneyDetails.setMoney(money);
                userMoneyDetails.setCreateTime(DateUtils.format(new Date()));
                userMoneyDetails.setMoneyType(2);
                userMoneyDetailsService.save(userMoneyDetails);
            }
            return Result.success();
        } catch (Exception e) {
            e.printStackTrace();
            log.error("新用户领取红包出错：" + e.getMessage(), e);
        } finally {
            reentrantReadWriteLock.writeLock().unlock();
        }
        return Result.error("系统繁忙，请稍后再试！");

    }


    @Override
    public UserEntity queryByPhone(String phone) {
        return baseMapper.selectOne(new QueryWrapper<UserEntity>().eq("phone", phone));
    }

    @Override
    public UserEntity queryByOpenId(String openId) {
        return baseMapper.selectOne(new QueryWrapper<UserEntity>().eq("open_id", openId));
    }

    @Override
    public UserEntity queryByWxId(String wxId) {
        return baseMapper.selectOne(new QueryWrapper<UserEntity>().eq("wx_id", wxId));
    }

    @Override
    public UserEntity queryByDyOpenId(String dyOpenId) {
        return baseMapper.selectOne(new QueryWrapper<UserEntity>().eq("dy_open_id", dyOpenId));
    }

    @Override
    public UserEntity queryByKsOpenId(String ksOpenId) {
        return baseMapper.selectOne(new QueryWrapper<UserEntity>().eq("ks_open_id", ksOpenId));
    }

    @Override
    public UserEntity queryByWxOpenId(String openId) {
        return baseMapper.selectOne(new QueryWrapper<UserEntity>().eq("wx_open_id", openId));
    }

    @Override
    public UserEntity queryByAppleId(String appleId) {
        return baseMapper.selectOne(new QueryWrapper<UserEntity>().eq("apple_id", appleId));
    }

    @Override
    public UserEntity queryByUserId(Long userId) {
        return baseMapper.selectOne(new QueryWrapper<UserEntity>().eq("user_id", userId));
    }

    @Override
    public UserEntity queryByInvitationCode(String invitationCode) {
        return baseMapper.selectOne(new QueryWrapper<UserEntity>().eq("invitation_code", invitationCode));
    }

    @Override
    public Result updatePhone(String phone, String msg, Long userId) {
        Msg msg1 = msgDao.findByPhoneAndCode(phone, msg);
        //校验短信验证码
        if (msg1 != null) {
            msgDao.deleteById(msg1.getId());
            UserEntity userInfo = queryByPhone(phone);
            if (userInfo != null) {
                return Result.error("手机号已经被其他账号绑定");
            } else {
                UserEntity one = baseMapper.selectById(userId);
                one.setPhone(phone);
                baseMapper.updateById(one);
                return Result.success();
            }
        }
        return Result.error("验证码不正确");
    }

    @Override
    public Result iosRegister(String appleId) {
        if (StringUtils.isEmpty(appleId)) {
            return Result.error("账号信息获取失败，请退出重试！");
        }
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        String date = sdf.format(new Date());
        // 根据返回的user实体类，判断用户是否是新用户，不是的话，更新最新登录时间，是的话，将用户信息存到数据库
        UserEntity userInfo = queryByAppleId(appleId);
        if (userInfo != null) {
            if (userInfo.getStatus().equals(2)) {
                return Result.error("账号已被封禁，请联系客服处理！");
            }
            userInfo.setUpdateTime(date);
            baseMapper.updateById(userInfo);
            //返回用户信息
            UserEntity user = queryByAppleId(appleId);
            return getResult(user);
        } else {
            return Result.error(-200, "请先绑定手机号账号！");
        }
    }

    @Override
    public Result wxLogin(String code) {
        try {
            String appid = commonInfoService.findOne(45).getValue();
            String secret = commonInfoService.findOne(46).getValue();
            // 配置请求参数
            Map<String, String> param = new HashMap<>();
            param.put("appid", appid);
            param.put("secret", secret);
            param.put("js_code", code);
            param.put("grant_type", UserConstantInterface.WX_LOGIN_GRANT_TYPE);
            param.put("scope", "snsapi_userinfo");
            // 发送请求
            String wxResult = HttpClientUtil.doGet(UserConstantInterface.WX_LOGIN_URL, param);
            log.info(wxResult);
            JSONObject jsonObject = JSONObject.parseObject(wxResult);
            // 获取参数返回的
            String session_key = jsonObject.get("session_key").toString();
            String open_id = jsonObject.get("openid").toString();
            UserEntity userEntity = queryByOpenId(open_id);
            Map<String, String> map = new HashMap<>();
            // 封装返回小程序
            map.put("session_key", session_key);
            map.put("open_id", open_id);
            if (jsonObject.get("unionid") != null) {
                String unionid = jsonObject.get("unionid").toString();
                map.put("unionid", unionid);
            } else {
                map.put("unionid", "-1");
            }
            String value = commonInfoService.findOne(237).getValue();
            if ("是".equals(value)) {
                if (userEntity == null || StringUtils.isEmpty(userEntity.getPhone())) {
                    map.put("flag", "1");
                } else {
                    map.put("flag", "2");
                }
            } else {
                map.put("flag", "2");
            }
            return Result.success("登陆成功").put("data", map);
        } catch (Exception e) {
            System.err.println(e.toString());
            return Result.success("登录失败！");
        }
    }


    @Override
    public Result wxRegister(UserEntity userInfo1) {
        if (StringUtils.isEmpty(userInfo1.getOpenId())) {
            return Result.error("账号信息获取失败，请退出重试！");
        }
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        String date = sdf.format(new Date());
        // 根据返回的user实体类，判断用户是否是新用户，不是的话，更新最新登录时间，是的话，将用户信息存到数据库
        UserEntity userInfo = queryByOpenId(userInfo1.getOpenId());
        if (userInfo != null) {
            if (userInfo.getStatus().equals(2)) {
                return Result.error("账号已被封禁，请联系客服处理！");
            }
            /*if (StringUtils.isNotEmpty(userInfo1.getUserName())) {
                userInfo.setUserName(userInfo1.getUserName());
            }
            if (StringUtils.isNotEmpty(userInfo1.getAvatar())) {
                userInfo.setAvatar(userInfo1.getAvatar());
            }
            if (StringUtils.isNotEmpty(userInfo1.getPhone())) {
                userInfo.setPhone(userInfo1.getPhone());
            }*/
            if (StringUtils.isNotEmpty(userInfo1.getPhone())) {
                userInfo.setPhone(userInfo1.getPhone());
            }
            userInfo.setUpdateTime(date);
            baseMapper.updateById(userInfo);
        } else {
            //判断是否在app登陆过  手机号是否有账号
            UserEntity userByMobile = null;
            if (StringUtils.isNotEmpty(userInfo1.getPhone())) {
                userByMobile = queryByPhone(userInfo1.getPhone());
            }
            if (userByMobile != null) {
                //有账号则绑定账号
                userByMobile.setOpenId(userInfo1.getOpenId());
                baseMapper.updateById(userByMobile);
                if (userByMobile.getStatus().equals(2)) {
                    return Result.error("账号已被封禁，请联系客服处理！");
                }
            } else {
                if (StringUtils.isEmpty(userInfo1.getInviterCode())) {
                    userInfo1.setInviterCode(commonInfoService.findOne(88).getValue());
                }
                UserEntity userEntity = queryByInvitationCode(userInfo1.getInviterCode());
                if (userEntity != null && StringUtils.isEmpty(userInfo1.getQdCode())) {
                    userInfo1.setQdCode(userEntity.getQdCode());
                }
                //没有则生成新账号
                userInfo1.setCreateTime(date);
                userInfo1.setPlatform("小程序");
                userInfo1.setStatus(1);
                userInfo1.setPassword(DigestUtils.sha256Hex(userInfo1.getPhone()));
                userInfo1.setRate(new BigDecimal(commonInfoService.findOne(420).getValue()));
                userInfo1.setTwoRate(new BigDecimal(commonInfoService.findOne(421).getValue()));
                baseMapper.insert(userInfo1);
                userInfo1.setInvitationCode(InvitationCodeUtil.toSerialCode(userInfo1.getUserId()));
                baseMapper.updateById(userInfo1);
                if (userEntity != null) {
                    inviteService.saveBody(userInfo1.getUserId(), userEntity);
                }
//                userMoneyService.selectUserMoneyByUserId(userInfo1.getUserId());
            }
        }
        //返回用户信息
        UserEntity user = queryByOpenId(userInfo1.getOpenId());
        return getResult(user);
    }


    @Override
    public Result wxBindMobile(String phone, String code, String wxOpenId, String token, String platform, Integer sysPhone, String inviterCode, String qdCode) {
        Msg byPhoneAndCode = msgDao.findByPhoneAndCode(phone, code);
        if (byPhoneAndCode == null) {
            return Result.error("验证码错误");
        }
        msgDao.deleteById(byPhoneAndCode.getId());
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        String time = simpleDateFormat.format(new Date());
        UserEntity userInfo = queryByPhone(phone);
        if (userInfo != null) {
            if (StringUtils.isNotEmpty(userInfo.getWxOpenId())) {
                return Result.error("当前手机号已经被其他微信绑定");
            }
            //小程序登陆过
            userInfo.setWxOpenId(wxOpenId);
            String s = HttpClientUtil.doGet("https://api.weixin.qq.com/sns/userinfo?access_token=" + token + "&openid=" + wxOpenId);
            AppUserInfo user = JsonUtil.parseObject(s, AppUserInfo.class);
            if (user != null && user.getNickname() != null) {
                if (user.getHeadimgurl() != null) {
                    userInfo.setAvatar(user.getHeadimgurl());
                }
                userInfo.setSex(user.getSex());
                if (user.getNickname() != null) {
                    userInfo.setUserName(user.getNickname().replaceAll("(\\d{3})\\d*([0-9a-zA-Z]{4})", "$1****$2"));
                }
            }
            baseMapper.updateById(userInfo);
        } else {
            //小程序没有登陆过
            userInfo = new UserEntity();
            userInfo.setQdCode(qdCode);
            if (StringUtils.isEmpty(inviterCode)) {
                inviterCode = commonInfoService.findOne(88).getValue();
            }
            UserEntity userEntity = queryByInvitationCode(inviterCode);
            if (userEntity != null && StringUtils.isEmpty(userInfo.getQdCode())) {
                userInfo.setQdCode(userEntity.getQdCode());
            }
            userInfo.setInviterCode(inviterCode);
            String s = HttpClientUtil.doGet("https://api.weixin.qq.com/sns/userinfo?access_token=" + token + "&openid=" + wxOpenId);
            AppUserInfo user = JsonUtil.parseObject(s, AppUserInfo.class);
            if (user != null && user.getNickname() != null) {
                if (user.getHeadimgurl() != null) {
                    userInfo.setAvatar(user.getHeadimgurl());
                }
                userInfo.setSex(user.getSex());
                if (user.getNickname() != null) {
                    userInfo.setUserName(user.getNickname().replaceAll("(\\d{3})\\d*([0-9a-zA-Z]{4})", "$1****$2"));
                }
            }
            userInfo.setWxOpenId(wxOpenId);
            userInfo.setPhone(phone);
            userInfo.setPlatform(platform);
            userInfo.setCreateTime(time);
            userInfo.setSysPhone(sysPhone);
            userInfo.setStatus(1);
            userInfo.setUpdateTime(time);
            userInfo.setRate(new BigDecimal(commonInfoService.findOne(420).getValue()));
            userInfo.setTwoRate(new BigDecimal(commonInfoService.findOne(421).getValue()));
            baseMapper.insert(userInfo);
            if (userEntity != null) {
                inviteService.saveBody(userInfo.getUserId(), userEntity);
            }
        }
        UserEntity userEntity = queryByWxOpenId(userInfo.getWxOpenId());
        return getResult(userEntity);
    }

    @Override
    public Result iosBindMobile(String phone, String code, String appleId, String platform, Integer sysPhone, String inviterCode, String qdCode) {
        Msg byPhoneAndCode = msgDao.findByPhoneAndCode(phone, code);
        if (byPhoneAndCode == null) {
            return Result.error("验证码错误");
        }
        msgDao.deleteById(byPhoneAndCode.getId());
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        String time = simpleDateFormat.format(new Date());
        UserEntity userInfo = queryByPhone(phone);
        if (userInfo != null) {
            if (StringUtils.isNotEmpty(userInfo.getAppleId())) {
                return Result.error("当前手机号已经被其他苹果绑定");
            }
            userInfo.setAppleId(appleId);
            userInfo.setUpdateTime(simpleDateFormat.format(new Date()));
            baseMapper.updateById(userInfo);
        } else {
            userInfo = new UserEntity();
            userInfo.setQdCode(qdCode);
            if (StringUtils.isEmpty(inviterCode)) {
                inviterCode = commonInfoService.findOne(88).getValue();
            }
            UserEntity userEntity = queryByInvitationCode(inviterCode);
            if (userEntity != null && StringUtils.isEmpty(userInfo.getQdCode())) {
                userInfo.setQdCode(userEntity.getQdCode());
            }
            userInfo.setAppleId(appleId);
            userInfo.setInviterCode(inviterCode);
            userInfo.setSex(0);
            userInfo.setUserName(phone.replaceAll("(\\d{3})\\d*([0-9a-zA-Z]{4})", "$1****$2"));
            userInfo.setPhone(phone);
            userInfo.setPlatform(platform);
            userInfo.setCreateTime(time);
            userInfo.setSysPhone(sysPhone);
            userInfo.setStatus(1);
            userInfo.setUpdateTime(time);
            userInfo.setRate(new BigDecimal(commonInfoService.findOne(420).getValue()));
            userInfo.setTwoRate(new BigDecimal(commonInfoService.findOne(421).getValue()));
            baseMapper.insert(userInfo);
            if (userEntity != null) {
                inviteService.saveBody(userInfo.getUserId(), userEntity);
            }
        }
        UserEntity userEntity = queryByAppleId(userInfo.getAppleId());
        return getResult(userEntity);
    }


    @Override
    public Result phoneLogin(String phone) {
        UserEntity userInfo = queryByPhone(phone);
        if (userInfo != null) {
            if (userInfo.getStatus().equals(2)) {
                return Result.error(500, "账号已被禁用，请联系客服处理！");
            }
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            userInfo.setUpdateTime(sdf.format(new Date()));
            baseMapper.updateById(userInfo);
            return getResult(userInfo);
        } else {
            return Result.error(201, "请绑定密码！");
        }
    }


    @Override
    public Result bindMobile(String phone, String platform, Integer sysPhone, String inviterCode, String qdCode) {
        UserEntity userInfo = new UserEntity();
        userInfo.setQdCode(qdCode);
        if (StringUtils.isEmpty(inviterCode)) {
            inviterCode = commonInfoService.findOne(88).getValue();
        }
        UserEntity userEntity = queryByInvitationCode(inviterCode);
        if (userEntity != null && StringUtils.isEmpty(userInfo.getQdCode())) {
            userInfo.setQdCode(userEntity.getQdCode());
        }
        userInfo.setInviterCode(inviterCode);
        userInfo.setSex(0);
        userInfo.setUserName(phone.replaceAll("(\\d{3})\\d*([0-9a-zA-Z]{4})", "$1****$2"));
        userInfo.setPhone(phone);
        userInfo.setPlatform(platform);
        userInfo.setCreateTime(DateUtils.format(new Date()));
        userInfo.setSysPhone(sysPhone);
        userInfo.setStatus(1);
        userInfo.setUpdateTime(DateUtils.format(new Date()));
        userInfo.setRate(new BigDecimal(commonInfoService.findOne(420).getValue()));
        userInfo.setTwoRate(new BigDecimal(commonInfoService.findOne(421).getValue()));
        baseMapper.insert(userInfo);
        if (userEntity != null) {
            inviteService.saveBody(userInfo.getUserId(), userEntity);
        }
        return getResult(userInfo);
    }


    @Override
    public Result wxAppLogin(String wxOpenId, String token) {
        UserEntity userEntity = queryByWxOpenId(wxOpenId);
        if (userEntity != null) {
            if (userEntity.getStatus().equals(2)) {
                return Result.error("账号已被禁用，请联系客服处理！");
            }
            String s = HttpClientUtil.doGet("https://api.weixin.qq.com/sns/userinfo?access_token=" + token + "&openid=" + wxOpenId);
            AppUserInfo user = JsonUtil.parseObject(s, AppUserInfo.class);
            if (user != null && user.getNickname() != null) {
                if (user.getHeadimgurl() != null) {
                    userEntity.setAvatar(user.getHeadimgurl());
                }
                userEntity.setSex(user.getSex());
                if (user.getNickname() != null) {
                    userEntity.setUserName(user.getNickname().replaceAll("(\\d{3})\\d*([0-9a-zA-Z]{4})", "$1****$2"));
                }
            }
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            userEntity.setUpdateTime(sdf.format(new Date()));
            baseMapper.updateById(userEntity);
            return getResult(userEntity);
        } else {
            return Result.error(-200, "请先绑定手机号账号！");
        }
    }

    @Override
    public Result dyLogin(String code, String anonymous_code) {
        String appid = commonInfoService.findOne(805).getValue();
        String secret = commonInfoService.findOne(806).getValue();
        // 配置请求参数
        JSONObject param = new JSONObject();
        param.put("appid", appid);
        param.put("secret", secret);
        param.put("code", code);
        param.put("anonymous_code", anonymous_code);
        // 发送请求
        String wxResult = HttpClientUtil.doPostJson("https://developer.toutiao.com/api/apps/v2/jscode2session", param.toJSONString());
        log.info(wxResult);
        JSONObject jsonObject = JSONObject.parseObject(wxResult);
        String err_no = jsonObject.getString("err_no");
        if (!"0".equals(err_no)) {
            return Result.error(jsonObject.getString("err_tips"));
        }
        JSONObject data = jsonObject.getJSONObject("data");
        String openid = data.getString("openid");

        if (StringUtils.isEmpty(openid)) {
            openid = data.getString("anonymous_openid");
        }
        UserEntity userEntity = queryByDyOpenId(openid);
        Map<String, String> resultMap = new HashMap<>();
        resultMap.put("dyOpenId", openid);
        String value = commonInfoService.findOne(814).getValue();
        if ("是".equals(value)) {
            if (userEntity == null || StringUtils.isEmpty(userEntity.getPhone())) {
                resultMap.put("flag", "1");
            } else {
                resultMap.put("flag", "2");
            }
        } else {
            resultMap.put("flag", "2");
        }
        return Result.success("登陆成功").put("data", resultMap);
    }

    @Override
    public Result dyRegister(UserEntity userInfo1) {
        if (StringUtils.isEmpty(userInfo1.getDyOpenId())) {
            return Result.error("账号信息获取失败，请退出重试！");
        }
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        String date = sdf.format(new Date());
        // 根据返回的user实体类，判断用户是否是新用户，不是的话，更新最新登录时间，是的话，将用户信息存到数据库
        UserEntity userInfo = queryByDyOpenId(userInfo1.getDyOpenId());
        if (userInfo != null) {
            if (userInfo.getStatus().equals(2)) {
                return Result.error("账号已被封禁，请联系客服处理！");
            }
            userInfo.setUpdateTime(date);
            baseMapper.updateById(userInfo);
        } else {
            //判断是否在app登陆过  手机号是否有账号
            UserEntity userByMobile = null;
            if (StringUtils.isNotEmpty(userInfo1.getPhone())) {
                userByMobile = queryByPhone(userInfo1.getPhone());
            }
            if (userByMobile != null) {
                //有账号则绑定账号
                userByMobile.setDyOpenId(userInfo1.getDyOpenId());
                baseMapper.updateById(userByMobile);
                if (userByMobile.getStatus().equals(2)) {
                    return Result.error("账号已被封禁，请联系客服处理！");
                }
            } else {
                if (StringUtils.isEmpty(userInfo1.getInviterCode())) {
                    userInfo1.setInviterCode(commonInfoService.findOne(88).getValue());
                }
                UserEntity userEntity = queryByInvitationCode(userInfo1.getInviterCode());
                //没有则生成新账号
                userInfo1.setCreateTime(date);
                userInfo1.setPlatform("抖音");
                userInfo1.setStatus(1);
                if (StringUtils.isNotEmpty(userInfo1.getPhone())) {
                    userInfo1.setPassword(DigestUtils.sha256Hex(userInfo1.getPhone()));
                }
                userInfo1.setRate(new BigDecimal(commonInfoService.findOne(420).getValue()));
                userInfo1.setTwoRate(new BigDecimal(commonInfoService.findOne(421).getValue()));
                baseMapper.insert(userInfo1);
                userInfo1.setInvitationCode(InvitationCodeUtil.toSerialCode(userInfo1.getUserId()));
                baseMapper.updateById(userInfo1);
                if (userEntity != null) {
                    inviteService.saveBody(userInfo1.getUserId(), userEntity);
                }
//                userMoneyService.selectUserMoneyByUserId(userInfo1.getUserId());
            }
        }
        //返回用户信息
        UserEntity user = queryByDyOpenId(userInfo1.getDyOpenId());
        return getResult(user);
    }


    @Override
    public Result ksLogin(String code) {
        String appid = commonInfoService.findOne(828).getValue();
        String secret = commonInfoService.findOne(829).getValue();
        // 配置请求参数
        HashMap<String, String> param = new HashMap<>();
        param.put("app_id", appid);
        param.put("app_secret", secret);
        param.put("js_code", code);
        // 发送请求
        String ksResult = HttpClientUtil.doPost("https://open.kuaishou.com/oauth2/mp/code2session", param);
        log.info(ksResult);
        JSONObject jsonObject = JSONObject.parseObject(ksResult);
        String result = jsonObject.getString("result");
        if (!"1".equals(result)) {
            return Result.error("登录失败！");
        }

        String session_key = jsonObject.getString("session_key");
        String openid = jsonObject.getString("open_id");

        UserEntity userEntity = queryByDyOpenId(openid);
        Map<String, String> resultMap = new HashMap<>();
        resultMap.put("ksOpenId", openid);
        resultMap.put("session_key", session_key);
        String value = commonInfoService.findOne(830).getValue();
        if ("是".equals(value)) {
            if (userEntity == null || StringUtils.isEmpty(userEntity.getPhone())) {
                resultMap.put("flag", "1");
            } else {
                resultMap.put("flag", "2");
            }
        } else {
            resultMap.put("flag", "2");
        }
        return Result.success("登陆成功").put("data", resultMap);
    }

    @Override
    public Result ksRegister(UserEntity userInfo1) {
        if (StringUtils.isEmpty(userInfo1.getKsOpenId())) {
            return Result.error("账号信息获取失败，请退出重试！");
        }
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        String date = sdf.format(new Date());
        // 根据返回的user实体类，判断用户是否是新用户，不是的话，更新最新登录时间，是的话，将用户信息存到数据库
        UserEntity userInfo = queryByKsOpenId(userInfo1.getKsOpenId());
        if (userInfo != null) {
            if (userInfo.getStatus().equals(2)) {
                return Result.error("账号已被封禁，请联系客服处理！");
            }
            userInfo.setUpdateTime(date);
            baseMapper.updateById(userInfo);
        } else {
            //判断是否在app登陆过  手机号是否有账号
            UserEntity userByMobile = null;
            if (StringUtils.isNotEmpty(userInfo1.getPhone())) {
                userByMobile = queryByPhone(userInfo1.getPhone());
            }
            if (userByMobile != null) {
                //有账号则绑定账号
                userByMobile.setKsOpenId(userInfo1.getKsOpenId());
                baseMapper.updateById(userByMobile);
                if (userByMobile.getStatus().equals(2)) {
                    return Result.error("账号已被封禁，请联系客服处理！");
                }
            } else {
                if (StringUtils.isEmpty(userInfo1.getInviterCode())) {
                    userInfo1.setInviterCode(commonInfoService.findOne(88).getValue());
                }
                UserEntity userEntity = queryByInvitationCode(userInfo1.getInviterCode());
                //没有则生成新账号
                userInfo1.setCreateTime(date);
                userInfo1.setPlatform("快手");
                userInfo1.setStatus(1);
                if (StringUtils.isNotEmpty(userInfo1.getPhone())) {
                    userInfo1.setPassword(DigestUtils.sha256Hex(userInfo1.getPhone()));
                }
                userInfo1.setRate(new BigDecimal(commonInfoService.findOne(420).getValue()));
                userInfo1.setTwoRate(new BigDecimal(commonInfoService.findOne(421).getValue()));
                baseMapper.insert(userInfo1);
                userInfo1.setInvitationCode(InvitationCodeUtil.toSerialCode(userInfo1.getUserId()));
                baseMapper.updateById(userInfo1);
                if (userEntity != null) {
                    inviteService.saveBody(userInfo1.getUserId(), userEntity);
                }
//                userMoneyService.selectUserMoneyByUserId(userInfo1.getUserId());
            }
        }
        //返回用户信息
        UserEntity user = queryByKsOpenId(userInfo1.getKsOpenId());
        return getResult(user);
    }

    @Override
    public Result registerCode(String phone, String msg, String platform, Integer sysPhone, String password,
                               String inviterCode, String wxId, String qdCode) {
        //校验手机号是否存在
        UserEntity userInfo = queryByPhone(phone);
        if (userInfo != null) {
            if (StringUtils.isNotEmpty(password)) {
                //密码登录
                if (StringUtils.isEmpty(userInfo.getPassword())) {
                    return Result.error("当前账号未绑定密码，请前往忘记密码中进行重置！");
                }
                if (!userInfo.getPassword().equals(DigestUtils.sha256Hex(password))) {
                    return Result.error("账号或密码不正确！");
                }
            } else if (StringUtils.isNotEmpty(msg)) {
                //验证码登录
                Msg msg1 = msgDao.findByPhoneAndCode(phone, msg);
                if (msg1 == null) {
                    return Result.error("验证码不正确！");
                }
                msgDao.deleteById(msg1.getId());
            } else {
                return Result.error("登录失败，请刷新页面重试！");
            }
            if (userInfo.getStatus().equals(2)) {
                return Result.error("账号已被禁用，请联系客服处理！");
            }
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            if (StringUtils.isNotEmpty(wxId) && StringUtils.isNotEmpty(userInfo.getWxId()) && !wxId.equals(userInfo.getWxId())) {
                return Result.error("当前手机号已经绑定过了，请更换其他手机号！");
            }
            if (StringUtils.isNotEmpty(wxId)) {
                userInfo.setWxId(wxId);
            }
            userInfo.setUpdateTime(sdf.format(new Date()));
            baseMapper.updateById(userInfo);
            return getResult(userInfo);
        } else {
            // 如果 platform 为空 则表示登录的时候输错了手机号
            if (StringUtils.isEmpty(platform)) {
                return Result.error("手机号未注册！");
            }
            if (StringUtils.isEmpty(msg)) {
                return Result.error("验证码不能为空！");
            }
            Msg msg1 = msgDao.findByPhoneAndCode(phone, msg);
            if (msg1 == null) {
                return Result.error("验证码不正确！");
            }
//            Msg msg1 = null;
//            if (!"prod".equals(profiles) || !"61626364".equals(msg)) {
//                msg1 = msgDao.findByPhoneAndCode(phone, msg);
//                if (msg1 == null) {
//                    return Result.error("验证码不正确！");
//                }
//            }

            userInfo = new UserEntity();
            UserEntity userEntity = null;
            if (StringUtils.isNotEmpty(inviterCode)) {
                userEntity = queryByInvitationCode(inviterCode);
                if (userEntity == null) {
                    return Result.error("邀请码不正确！");
                }
            } else {
                userInfo.setInviterCode(commonInfoService.findOne(88).getValue());
                userEntity = queryByInvitationCode(userInfo.getInviterCode());
            }
            SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            String time = simpleDateFormat.format(new Date());
            if (StringUtils.isNotEmpty(wxId)) {
                userInfo.setWxId(wxId);
            }
            if (StringUtils.isEmpty(qdCode)) {
                qdCode = userEntity.getQdCode();
            } else {
                SysUserEntity sysUserEntity = sysUserService.selectSysUserByQdCode(qdCode);
                if (sysUserEntity == null) {
                    return Result.error("请使用正确的渠道码！");
                }
            }
            userInfo.setQdCode(qdCode);
            userInfo.setPhone(phone);
            userInfo.setUserName(phone.replaceAll("(\\d{3})\\d*([0-9a-zA-Z]{4})", "$1****$2"));
            userInfo.setPlatform(platform);
            userInfo.setCreateTime(time);
            userInfo.setSysPhone(sysPhone);
            if (StringUtils.isNotBlank(password)) {
                userInfo.setPassword(DigestUtils.sha256Hex(password));
            } else {
                userInfo.setPassword(DigestUtils.sha256Hex(phone));
            }
            userInfo.setStatus(1);
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            userInfo.setUpdateTime(sdf.format(new Date()));
            userInfo.setRate(new BigDecimal(commonInfoService.findOne(420).getValue()));
            userInfo.setTwoRate(new BigDecimal(commonInfoService.findOne(421).getValue()));
            baseMapper.insert(userInfo);
            userInfo.setInvitationCode(InvitationCodeUtil.toSerialCode(userInfo.getUserId()));
            baseMapper.updateById(userInfo);
            if (msg1 != null) {
                msgDao.deleteById(msg1.getId());
            }
            if (userEntity != null) {
                inviteService.saveBody(userInfo.getUserId(), userEntity);
            }
            return getResult(userInfo);
        }
    }


    @Override
    public Result bindWxOpenPhone(Long userId, String phone, String msg) {
        Msg byPhoneAndCode = msgDao.findByPhoneAndCode(phone, msg);
        if (byPhoneAndCode == null) {
            return Result.error("验证码错误");
        }
        msgDao.deleteById(byPhoneAndCode.getId());
        UserEntity userEntity = queryByPhone(phone);
        if (userEntity != null) {
            return Result.error("当前手机号已经绑定过了，请直接登录！");
        }
        UserEntity byId = baseMapper.selectById(userId);
        byId.setPhone(phone);
        baseMapper.updateById(byId);
        return Result.success();
    }

    @Override
    public Result forgetPwd(String pwd, String phone, String msg) {
        try {
            Msg byPhoneAndCode = msgDao.findByPhoneAndCode(phone, msg);
            //校验短信验证码
            if (byPhoneAndCode == null) {
                return Result.error("验证码不正确");
            }
            UserEntity userByPhone = queryByPhone(phone);
            userByPhone.setPassword(DigestUtils.sha256Hex(pwd));
            msgDao.deleteById(byPhoneAndCode.getId());
            baseMapper.updateById(userByPhone);
            return Result.success();
        } catch (Exception e) {
            e.printStackTrace();
            return Result.error("服务器内部错误");
        }
    }


    @Override
    public Result login(String phone, String pwd) {
        UserEntity userEntity = queryByPhone(phone);
        if (userEntity == null) {
            return Result.error("手机号未注册！");
        }
        if (!userEntity.getPassword().equals(DigestUtils.sha256Hex(pwd))) {
            return Result.error("密码不正确！");
        }
        if (userEntity.getStatus().equals(2)) {
            return Result.error("账号已被禁用，请联系客服处理！");
        }
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        userEntity.setUpdateTime(sdf.format(new Date()));
        baseMapper.updateById(userEntity);
        return getResult(userEntity);
    }


    @Override
    public Result getResult(UserEntity user) {
        //生成token
        String token = jwtUtils.generateToken(user.getUserId());
        Map<String, Object> map = new HashMap<>();
        map.put("token", token);
        map.put("expire", jwtUtils.getExpire());
        map.put("user", user);
        return Result.success(map);
    }


    @Override
    public Result sendMsg(String phone, String state, String pwd) {
        int code = (int) ((Math.random() * 9 + 1) * 100000);
        System.out.println("sendMsg code is " + code);
        SmsSingleSenderResult result = null;
        if ("bindWx".equals(state)) {
            UserEntity userByPhone = queryByPhone(phone);
            if (userByPhone != null && StringUtils.isNotEmpty(userByPhone.getWxOpenId())) {
                return Result.error("当前手机号已被其他微信账号绑定");
            }
        } else if ("bindIos".equals(state)) {
            UserEntity userByPhone = queryByPhone(phone);
            if (userByPhone != null && StringUtils.isNotEmpty(userByPhone.getAppleId())) {
                return Result.error("当前手机号已被其他苹果账号绑定");
            }
        } else if ("login".equals(state)) {
            UserEntity userByPhone = queryByPhone(phone);
            if (userByPhone != null) {
                return Result.error("当前手机号已注册！");
            }
        } else if ("forget".equals(state)) {
            UserEntity userByPhone = queryByPhone(phone);
            if (userByPhone == null) {
                return Result.error("手机号未注册！");
            }
        }
        CommonInfo three = commonInfoService.findOne(79);
        //默认使用腾讯云
        if (three == null || "1".equals(three.getValue())) {
            //腾讯云短信发送
            return sendMsgTencent(phone, state, code);
        } else if ("2".equals(three.getValue())) {
            //阿里云短信发送
            return sendMsgAlibaba(phone, state, code);
        } else {
            return sendMsgDXB(phone, state, code, pwd);
        }
    }


    private Result sendMsgAlibaba(String phone, String state, int code) {

        CommonInfo three = commonInfoService.findOne(85);
        String accessKeyId = three.getValue();
        CommonInfo four = commonInfoService.findOne(86);
        String accessSecret = four.getValue();
        DefaultProfile profile = DefaultProfile.getProfile("cn-hangzhou", accessKeyId, accessSecret);
        IAcsClient client = new DefaultAcsClient(profile);
        CommonInfo name = commonInfoService.findOne(81);
        CommonRequest request = new CommonRequest();
        request.setSysMethod(MethodType.POST);
        request.setSysDomain("dysmsapi.aliyuncs.com");
        request.setSysVersion("2017-05-25");
        request.setSysAction("SendSms");
        request.putQueryParameter("RegionId", "cn-hangzhou");
        request.putQueryParameter("PhoneNumbers", phone);
        request.putQueryParameter("SignName", name.getValue());
        String value;
        switch (state) {
            case "login":
                value = commonInfoService.findOne(82).getValue();
                break;
            case "forget":
                value = commonInfoService.findOne(83).getValue();
                break;
            case "bindWx":
                value = commonInfoService.findOne(84).getValue();
                break;
            case "bindIos":
                value = commonInfoService.findOne(84).getValue();
                break;
            default:
                value = commonInfoService.findOne(82).getValue();
                break;
        }
        request.putQueryParameter("TemplateCode", value);
        request.putQueryParameter("TemplateParam", "{\"code\":\"" + code + "\"}");
        try {
            CommonResponse response = client.getCommonResponse(request);
            System.out.println(response.getData());
            String data = response.getData();
            JSONObject jsonObject = JSON.parseObject(data);
            if ("OK".equals(jsonObject.get("Code"))) {
                Msg byPhone = msgDao.findByPhone(phone);
                if (byPhone != null) {
                    byPhone.setCode(String.valueOf(code));
                    byPhone.setPhone(phone);
                    msgDao.updateById(byPhone);
                } else {
                    Msg msg = new Msg();
                    msg.setCode(String.valueOf(code));
                    msg.setPhone(phone);
                    msgDao.insert(msg);
                }
                UserEntity userByPhone = queryByPhone(phone);
                if (userByPhone != null) {
                    return Result.success("login");
                } else {
                    return Result.success("register");
                }
            } else {
                if (jsonObject.get("Message").toString().contains("分钟")) {
                    return Result.error("短信发送过于频繁，请一分钟后再试！");
                } else if (jsonObject.get("Message").toString().contains("小时")) {
                    return Result.error("短信发送过于频繁，请一小时后再试！");
                } else if (jsonObject.get("Message").toString().contains("天")) {
                    return Result.error("短信发送过于频繁，请明天再试！");
                }
                log.info(jsonObject.get("Message").toString());
                return Result.error("短信发送失败！");
            }
        } catch (ClientException | com.aliyuncs.exceptions.ClientException e) {
            e.printStackTrace();
        }
        return Result.error("验证码发送失败");
    }


    private Result sendMsgTencent(String phone, String state, int code) {
        SmsSingleSenderResult result = null;

        CommonInfo three = commonInfoService.findOne(31);
        String clientId = three.getValue();
        CommonInfo four = commonInfoService.findOne(32);
        String clientSecret = four.getValue();
        try {
            String secretId = commonInfoService.findOne(240).getValue();
            String secretKey = commonInfoService.findOne(241).getValue();
            // 实例化一个认证对象，入参需要传入腾讯云账户 SecretId 和 SecretKey，此处还需注意密钥对的保密
            // 代码泄露可能会导致 SecretId 和 SecretKey 泄露，并威胁账号下所有资源的安全性。以下代码示例仅供参考，建议采用更安全的方式来使用密钥，请参见：https://cloud.tencent.com/document/product/1278/85305
            // 密钥可前往官网控制台 https://console.cloud.tencent.com/cam/capi 进行获取
            Credential cred = new Credential(secretId, secretKey);
            // 实例化一个http选项，可选的，没有特殊需求可以跳过
            HttpProfile httpProfile = new HttpProfile();
            httpProfile.setEndpoint("sms.tencentcloudapi.com");
            // 实例化一个client选项，可选的，没有特殊需求可以跳过
            ClientProfile clientProfile = new ClientProfile();
            clientProfile.setHttpProfile(httpProfile);
            // 实例化要请求产品的client对象,clientProfile是可选的
            SmsClient client = new SmsClient(cred, "ap-beijing", clientProfile);
            // 实例化一个请求对象,每个接口都会对应一个request对象
            SendSmsRequest req = new SendSmsRequest();
            String[] phoneNumberSet1 = {phone};
            req.setPhoneNumberSet(phoneNumberSet1);

            req.setSmsSdkAppId(clientId);
            CommonInfo one = commonInfoService.findOne(81);
            req.setSignName(one.getValue());
            switch (state) {
                case "register":
                    req.setTemplateId(commonInfoService.findOne(242).getValue());
                    break;
                case "forget":
                    req.setTemplateId(commonInfoService.findOne(243).getValue());
                    break;
                case "bind":
                    req.setTemplateId(commonInfoService.findOne(244).getValue());
                    break;
                default:
                    req.setTemplateId(commonInfoService.findOne(242).getValue());
                    break;
            }
            String[] templateParamSet1 = {String.valueOf(code)};
            req.setTemplateParamSet(templateParamSet1);

            // 返回的resp是一个SendSmsResponse的实例，与请求对象对应
            SendSmsResponse resp = client.SendSms(req);
            // 输出json格式的字符串回包
            JSONObject jsonObject = JSONObject.parseObject(SendSmsResponse.toJsonString(resp));
            JSONArray sendStatusSet = jsonObject.getJSONArray("SendStatusSet");
            JSONObject jsonObject1 = sendStatusSet.getJSONObject(0);
            if ("Ok".equals(jsonObject1.getString("Code"))) {
                Msg byPhone = msgDao.findByPhone(phone);
                if (byPhone != null) {
                    byPhone.setCode(String.valueOf(code));
                    byPhone.setPhone(phone);
                    msgDao.updateById(byPhone);
                } else {
                    Msg msg = new Msg();
                    msg.setCode(String.valueOf(code));
                    msg.setPhone(phone);
                    msgDao.insert(msg);
                }
                UserEntity userByPhone = queryByPhone(phone);
                if (userByPhone != null) {
                    return Result.success("login");
                } else {
                    return Result.success("register");
                }
            }
        } catch (TencentCloudSDKException e) {
            System.out.println(e.toString());
        }
        return Result.error("验证码发送失败");
    }


    private Result sendMsgDXB(String phone, String state, int code, String pwd) {
        CommonInfo three = commonInfoService.findOne(238);
        CommonInfo four = commonInfoService.findOne(239);
        CommonInfo name = commonInfoService.findOne(81);
        String testUsername = three.getValue(); //在短信宝注册的用户名
        String testPassword = four.getValue(); //在短信宝注册的密码
        String value = "";
        switch (state) {
            case "register":
                value = "【" + name.getValue() + "】验证码: " + code + "，此验证码可用于登录或注册，10分钟内有效，如非您本人操作，可忽略本条消息";
                break;
            case "forget":
                value = "【" + name.getValue() + "】验证码: " + code + "，您正在执行找回密码操作，10分钟内有效，如非您本人操作，可忽略本条消息";
                break;
            case "bind":
                value = "【" + name.getValue() + "】验证码: " + code + "，您正在执行绑定手机号操作，10分钟内有效，如非您本人操作，可忽略本条消息";
                break;
            case "newUser":
                value = "【" + name.getValue() + "】新用户账号注册成功，账号：" + phone + "，密码：" + pwd + "，请及时登录并修改密码！";
                break;
            default:
                value = "【" + name.getValue() + "】验证码: " + code + "，此验证码可用于登录或注册，10分钟内有效，如非您本人操作，可忽略本条消息";
                break;
        }
        StringBuilder httpArg = new StringBuilder();
        httpArg.append("u=").append(testUsername).append("&");
        httpArg.append("p=").append(Md5Utils.md5s(testPassword)).append("&");
        httpArg.append("m=").append(phone).append("&");
        httpArg.append("c=").append(Md5Utils.encodeUrlString(value, "UTF-8"));
        String result = Md5Utils.request("https://api.smsbao.com/sms", httpArg.toString());
        log.error("短信包返回值：" + result);
        if ("0".equals(result)) {
            Msg byPhone = msgDao.findByPhone(phone);
            if (byPhone != null) {
                byPhone.setCode(String.valueOf(code));
                byPhone.setPhone(phone);
                msgDao.updateById(byPhone);
            } else {
                Msg msg = new Msg();
                msg.setCode(String.valueOf(code));
                msg.setPhone(phone);
                msgDao.insert(msg);
            }
            UserEntity userByPhone = queryByPhone(phone);
            if (userByPhone != null) {
                return Result.success("login");
            } else {
                return Result.success("register");
            }
        } else {
//            return ResultUtil.error(6, result.errMsg);
            if ("30".equals(result)) {
                return Result.error("错误密码");
            } else if ("40".equals(result)) {
                return Result.error("账号不存在");
            } else if ("41".equals(result)) {
                return Result.error("余额不足");
            } else if ("43".equals(result)) {
                return Result.error("IP地址限制");
            } else if ("50".equals(result)) {
                return Result.error("内容含有敏感词");
            } else if ("51".equals(result)) {
                return Result.error("手机号码不正确");
            }
        }

        return Result.error("验证码发送失败");
    }


    @Override
    public Result getOpenId(String code, Long userId) {
        try {
            //微信appid
            CommonInfo one = commonInfoService.findOne(5);
            //微信秘钥
            CommonInfo two = commonInfoService.findOne(21);
            String openid = SnsAPI.oauth2AccessToken(one.getValue(), two.getValue(), code).getOpenid();
            if (StringUtils.isNotEmpty(openid)) {
                UserEntity userEntity = new UserEntity();
                userEntity.setUserId(userId);
                userEntity.setWxId(openid);
                baseMapper.updateById(userEntity);
                return Result.success().put("data", openid);
            }
            return Result.error("获取失败");
        } catch (Exception e) {
            log.error("GET_OPENID_FAIL");
            return Result.error("获取失败,出错了！");
        }
    }

    @Override
    public UserEntity selectUserById(Long userId) {
        UserEntity userEntity = baseMapper.selectById(userId);
        if (userEntity != null) {
            UserVip userVip = userVipService.selectUserVipByUserId(userId);
            if (userVip != null) {
                userEntity.setMember(userVip.getIsVip());
                userEntity.setEndTime(userVip.getEndTime());
            }
        }
        return userEntity;
    }


    @Override
    public PageUtils selectUserPage(Integer page, Integer limit, String search, Integer sex, String platform,
                                    String sysPhone, Integer status, Integer member, String inviterCode, String userName,
                                    String invitationCode, String startTime, String endTime, String qdCode, String sysUserName, Integer vipType) {
        PageHelper.startPage(page, limit);
        List<UserEntity> entities = baseMapper.selectUserPage(search, sex, platform, sysPhone, status, member,
                inviterCode, userName, invitationCode, TimeCompleteUtils.completeStartTime(startTime), TimeCompleteUtils.completeEndTime(endTime), qdCode, sysUserName, vipType);
        PageInfo<UserEntity> pageInfo = new PageInfo<>(entities);
        return PageUtils.page(pageInfo);
    }

    @Override
    public List<UserEntity> userListExcel(String startTime, String endTime, UserEntity userEntity) {
        return baseMapper.userListExcel(startTime, endTime, userEntity);
    }


    @Override
    public int queryInviterCount(String inviterCode) {
        return baseMapper.queryInviterCount(inviterCode);
    }

    @Override
    public int queryUserCount(int type, String date, String platform, String qdCode) {
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:ss:mm");
        if (date == null || date == "") {
            date = simpleDateFormat.format(new Date());
        }
        return baseMapper.queryUserCount(type, date, platform, qdCode);
    }

    @Override
    public Double queryPayMoney(int type, String qdCode) {
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:ss:mm");
        String date = simpleDateFormat.format(new Date());
        return baseMapper.queryPayMoney(type, date, qdCode);
    }

    @Override
    public PageUtils queryCourseOrder(Long page, Long limit, int type, String date, Long sysUserId) {
        DateTime parse = DateUtil.parse(date, "yyyy-MM-dd");

        String startTime = DateUtil.format(parse, "yyyy-MM-dd 00:00:00");
        String endTime = DateUtil.format(parse, "yyyy-MM-dd 23:59:59");
        if (type == 2) {
            startTime = DateUtil.format(DateUtil.beginOfMonth(parse), "yyyy-MM-dd 00:00:00");
            endTime = DateUtil.format(DateUtil.endOfMonth(parse), "yyyy-MM-dd 23:59:59");
        } else if (type == 3) {
            startTime = DateUtil.format(DateUtil.beginOfYear(parse), "yyyy-MM-dd 00:00:00");
            endTime = DateUtil.format(DateUtil.endOfYear(parse), "yyyy-MM-dd 23:59:59");
        }

        PageHelper.startPage(page.intValue(), limit.intValue());
        List<Map<String, Object>> list = baseMapper.queryCourseOrder(type, startTime, endTime, sysUserId);
        PageInfo<Map<String, Object>> pageInfo = new PageInfo<>(list);

        return PageUtils.page(pageInfo, true);
    }

    @Override
    public int userMessage(String date, int type, String qdCode, Integer vipType) {
        return baseMapper.userMessage(date, type, qdCode, vipType);
    }


    @Override
    public void pushToSingle(String title, String content, String clientId) {
        try {
            if (StringUtils.isNotEmpty(clientId)) {
                UserEntity userEntity = baseMapper.selectOne(new QueryWrapper<UserEntity>().eq("clientid", clientId));
                GtApiConfiguration apiConfiguration = new GtApiConfiguration();
                //填写应用配置
                apiConfiguration.setAppId(commonInfoService.findOne(61).getValue());
                apiConfiguration.setAppKey(commonInfoService.findOne(60).getValue());
                apiConfiguration.setMasterSecret(commonInfoService.findOne(62).getValue());
                // 接口调用前缀，请查看文档: 接口调用规范 -> 接口前缀, 可不填写appId
                apiConfiguration.setDomain("https://restapi.getui.com/v2/");
                // 实例化ApiHelper对象，用于创建接口对象
                ApiHelper apiHelper = ApiHelper.build(apiConfiguration);
                // 创建对象，建议复用。目前有PushApi、StatisticApi、UserApi
                PushApi pushApi = apiHelper.creatApi(PushApi.class);
                //根据cid进行单推
                PushDTO<Audience> pushDTO = new PushDTO<Audience>();
                // 设置推送参数
                pushDTO.setRequestId(System.currentTimeMillis() + "");
                PushMessage pushMessage = new PushMessage();
                if (userEntity == null || userEntity.getSysPhone() == null || userEntity.getSysPhone() == 1) {
                    //安卓推送
                    GTNotification notification = new GTNotification();
                    pushDTO.setPushMessage(pushMessage);
                    // 配置通知栏图标
                    notification.setLogo(commonInfoService.findOne(19).getValue() + "/logo.png"); //配置通知栏图标，需要在客户端开发时嵌入，默认为push.png
                    // 配置通知栏网络图标
                    notification.setLogoUrl(commonInfoService.findOne(19).getValue() + "/logo.png");
                    notification.setTitle(title);
                    notification.setBody(content);
                    notification.setClickType("startapp");
                    notification.setUrl(commonInfoService.findOne(19).getValue());
                    notification.setChannelLevel("3");
                    pushMessage.setNotification(notification);
                } else {
                    pushMessage.setTransmission(title);
                    pushDTO.setPushMessage(pushMessage);
                    PushChannel pushChannel = new PushChannel();
                    IosDTO iosDTO = new IosDTO();
                    Aps aps = new Aps();
                    Alert alert = new Alert();
                    alert.setTitle(title);
                    alert.setBody(content);
                    aps.setAlert(alert);
                    aps.setSound("default");
                    iosDTO.setAps(aps);
                    pushChannel.setIos(iosDTO);
                    pushDTO.setPushChannel(pushChannel);
                }
                // 设置接收人信息
                Audience audience = new Audience();
                audience.addCid(clientId);
                pushDTO.setAudience(audience);
                // 进行cid单推
                ApiResult<Map<String, Map<String, String>>> apiResult = pushApi.pushToSingleByCid(pushDTO);
                if (apiResult.isSuccess()) {
                    // success
                    log.info("消息推送成功：" + apiResult.getData());
                } else {
                    // failed
                    log.error("消息推送失败：code:" + apiResult.getCode() + ", msg: " + apiResult.getMsg());
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
            log.error("消息推送异常：" + e.getMessage(), e);
        }
    }

    @Override
    public Result selectInviteUserList(Integer page, Integer limit, String userName, String phone) {
        PageHelper.startPage(page,limit);
        return Result.success().put("data", PageUtils.page(new PageInfo<>(baseMapper.selectInviteUserList(userName, phone)),true));
    }

    @Override
    public Result loginByOpenId(String openId) {
        UserEntity userEntity = queryByWxId(openId);
        if (userEntity == null) {
            return Result.error(-200, "未注册！");
        }
        String token = jwtUtils.generateToken(userEntity.getUserId());
        Map<String, Object> map = new HashMap<>();
        map.put("token", token);
        map.put("expire", jwtUtils.getExpire());
        map.put("user", userEntity);
        return Result.success(map);
    }

    @Override
    public Result selectUserOnLineCount(String qdCode) {
        return Result.success().put("data", baseMapper.selectUserOnLineCount(qdCode));
    }

    @Override
    public int updateUserClientIdIsNull(String clientid) {
        return baseMapper.updateUserClientIdIsNull(clientid);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void firstBindAwardsMoney(UserEntity entity) {
//        reentrantReadWriteLock.writeLock().lock();
        try {
            CommonInfo one = commonRepository.findOne(920);
            BigDecimal money = new BigDecimal(one.getValue());
            userMoneyService.updateAmount(1, entity.getUserId(), money.doubleValue());
            UserMoneyDetails userMoneyDetails = new UserMoneyDetails();
            userMoneyDetails.setUserId(entity.getUserId());
            userMoneyDetails.setTitle("[首绑支付宝]");
            userMoneyDetails.setContent("现金红包奖励：" + money + "元");
            // 充值
            userMoneyDetails.setType(1);
            // 任务领取
            userMoneyDetails.setClassify(7);
            userMoneyDetails.setMoney(money);
            userMoneyDetails.setCreateTime(DateUtil.format(new Date(System.currentTimeMillis() - 1000), "yyyy-MM-dd HH:mm:ss"));
            userMoneyDetails.setMoneyType(1);
            boolean ret = userMoneyDetailsService.save(userMoneyDetails);
            if (ret) {
                ThreadUtil.execAsync(() -> {
                    discSpinningService.withdrawAsync(entity, money.doubleValue(), "[提现]");
                });
            }
        } catch (Exception e) {
            log.error("首绑支付宝发放奖励异常，用户信息：{}", JSONUtil.toJsonStr(entity));
            log.error("首绑支付宝发放奖励异常：", e);
            throw new RuntimeException("首绑奖励失败");
        } finally {
//            reentrantReadWriteLock.writeLock().unlock();
        }
    }


    @Override
    public Object authCertNo(long userId, AuthCertNoDTO authCertNoDTO) {
        authCertNoDTO.setName(StrUtil.trim(authCertNoDTO.getName()));
        authCertNoDTO.setIdNum(StrUtil.trim(authCertNoDTO.getIdNum()));
        if (!IdcardUtil.isValidCard(authCertNoDTO.getIdNum())) {
            throw new SqxException("身份证号码有误");
        }

        UserEntity userEntity = baseMapper.selectById(userId);
        if (userEntity == null) {
            throw new SqxException("用户信息不存在");
        }

        UserInfo userInfo = userInfoService.getByUserId(userId);
        if (userInfo.getCertName() != null) {
            throw new SqxException("此账号已认证");
        }

        Integer count = userInfoService.countCertCount(authCertNoDTO.getName(), authCertNoDTO.getIdNum());
        if (count > 1) {
            throw new SqxException("此实名信息已存在");
        }

        aliService.authCertNo(authCertNoDTO.getName(), authCertNoDTO.getIdNum());

        userInfo.setCertName(authCertNoDTO.getName());
        userInfo.setCertNo(authCertNoDTO.getIdNum());
        userInfo.setUpdateTime(DateUtil.date());
        return userInfoService.updateById(userInfo);
    }
}
