package com.xhpc.user.controller;

import cn.hutool.extra.mail.MailUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.alipay.api.AlipayApiException;
import com.alipay.api.AlipayClient;
import com.alipay.api.CertAlipayRequest;
import com.alipay.api.DefaultAlipayClient;
import com.alipay.api.internal.util.AlipayEncrypt;
import com.alipay.api.request.AlipaySystemOauthTokenRequest;
import com.alipay.api.response.AlipaySystemOauthTokenResponse;
import com.aliyun.ocr20191230.models.RecognizeDrivingLicenseResponse;
import com.aliyun.ocr20191230.models.RecognizeDrivingLicenseResponseBody;
import com.xhpc.common.api.SettingConfigService;
import com.xhpc.common.core.constant.HttpStatus;
import com.xhpc.common.core.domain.R;
import com.xhpc.common.core.utils.HttpUtils;
import com.xhpc.common.core.utils.StringUtils;
import com.xhpc.common.core.utils.sign.Base64;
import com.xhpc.common.core.web.controller.BaseController;
import com.xhpc.common.core.web.domain.AjaxResult;
import com.xhpc.common.core.web.page.TableDataInfo;
import com.xhpc.common.log.annotation.Log;
import com.xhpc.common.log.enums.BusinessType;
import com.xhpc.common.redis.service.RedisService;
import com.xhpc.common.util.UserTypeUtil;
import com.xhpc.user.domain.XhpcUserVehicle;
import com.xhpc.user.service.IXhpcAppUserUserService;
import com.xhpc.user.service.IXhpcUserVehicleService;
import com.xhpc.user.util.WechatDecryptDataUtil;
import io.swagger.annotations.ApiOperation;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.env.Environment;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import javax.servlet.http.HttpServletRequest;
import java.io.InputStream;
import java.net.URL;
import java.security.AlgorithmParameters;
import java.security.Security;
import java.time.Instant;
import java.util.*;
import java.util.concurrent.TimeUnit;

import static com.xhpc.common.data.redis.StaticBeanUtil.REDIS;

/**
 * C端用户
 *
 * @author ruoyi
 */
@RestController
@RequestMapping("/app/user")
public class XhpcAppUserController extends BaseController {

    @Autowired
    private IXhpcAppUserUserService iXhpcAppUserUserService;

    @Autowired
    private SettingConfigService settingConfigService;

    @Autowired
    private Environment environment;
    @Autowired
    private RedisService redisService;
    @Resource
    private IXhpcUserVehicleService xhpcUserVehicleService;
    public static final String accessKeyId = "LTAI5t6Nr7MdNjMN4xNvgo1W";
    public static final String accessKeySecret = "hXQopkhlny10aiBBEFia2dHu6RHCqV";

    /**
     * 查询用户金额是否为负数，弹出框提示用户
     */
    @ApiOperation("查询用户金额是否为负数，弹出框提示用户")
    @GetMapping("/userInfoMoney")
    public AjaxResult userInfoMoney(HttpServletRequest request) {
        return iXhpcAppUserUserService.userInfoMoney(request);
    }


    /**
     * C端用户详情
     */
    @ApiOperation("C端用户详情")
    //@PreAuthorize(hasPermi = "app:user:info")
    @GetMapping("/info")
    public AjaxResult info(@RequestParam Long appUserId) {
        return AjaxResult.success(iXhpcAppUserUserService.info(appUserId));
    }

    /**
     * C端用户分页列表
     */
    //@PreAuthorize(hasPermi = "app:user:page")
    @GetMapping("/page")
    public TableDataInfo page(HttpServletRequest request, String phone) {
        List<Map<String, Object>> list = iXhpcAppUserUserService.selectAppUserList(request, phone);
        return getDataTable(list);
    }

    /**
     * 禁用/启用C端用户
     */
    @Log(title = "C端用户--（禁用/启用）", businessType = BusinessType.UPDATE)
    @ApiOperation("禁用/启用C端用户")
    //@PreAuthorize(hasPermi = "app:user:status")
    @PostMapping("/status")
    public AjaxResult status(@RequestBody Map<String, Object> map) {
        String appUserId = StringUtils.valueOf(map.get("appUserId"));
        if (StringUtils.isEmpty(appUserId)) {
            return AjaxResult.error(HttpStatus.NOT_NULL, "C端用户信息不能为空");
        }
        iXhpcAppUserUserService.status(Long.parseLong(appUserId));
        return AjaxResult.success();
    }

    /**
     * 统计
     *
     * @param phone
     * @return
     */
    @GetMapping("/userSum")
    public AjaxResult userSum(String phone) {
        return AjaxResult.success(iXhpcAppUserUserService.userSum(phone));
    }


    /**
     * 以下为小程序接口
     */

    /**
     * C端用户注册
     */
    //@Log(title = "C端用户--注册", businessType = BusinessType.INSERT)
    @ApiOperation("注册")
    @PostMapping("/register")
    public R<?> register(@RequestBody Map<String, Object> map) {
        return iXhpcAppUserUserService.register(map);
    }

    /**
     * C端用户登录
     */
    @ApiOperation("登录")
    @PostMapping("/login")
    public R<?> login(@RequestBody Map<String, Object> map) {
        return iXhpcAppUserUserService.login(map);
    }

    /**
     * app用户登录
     */
    @ApiOperation("app用户登录")
    @PostMapping("/appUserLogin")
    public R<?> appUserLogin(HttpServletRequest request,@RequestBody Map<String, Object> map) {
        return iXhpcAppUserUserService.appUserLogin(request,map);
    }

    /**
     * APP用户注册
     * @param map
     * @return
     */
    @ApiOperation("APP用户注册")
    @PostMapping("/apprRegister")
    public R<?> apprRegister(HttpServletRequest request,@RequestBody Map<String, Object> map) {
        return iXhpcAppUserUserService.apprRegister(request,map);
    }

    /**
     * C端用户授权登录
     */
    @ApiOperation("授权登录")
    @PostMapping("/loginPhone")
    public R<?> loginPhone(@RequestBody Map<String, Object> map) {
        return iXhpcAppUserUserService.loginPhone(map);
    }

    /**
     * 小程序用户详情
     */
    @ApiOperation("小程序用户详情")
    @GetMapping("/appInfo")
    public AjaxResult appInfo(HttpServletRequest request) {
        return iXhpcAppUserUserService.appInfo(request);
    }

    /**
     * 小程序用户退出
     */
    @ApiOperation("小程序用户退出")
    @PostMapping("/loginOut")
    public R<?> loginOut(HttpServletRequest request, @RequestParam String type) {
        return iXhpcAppUserUserService.loginOut(request, type);
    }

    /**
     * app用户退出
     */
    @ApiOperation("app用户退出")
    @GetMapping("/appLoginOut")
    public R<?> appLoginOut(HttpServletRequest request) {
        return iXhpcAppUserUserService.appLoginOut(request);
    }

    /**
     * C端用户自动登录
     */
    @ApiOperation("C端用户自动登录")
    @PostMapping("/voluntaryLogin")
    public R<?> voluntaryLogin(@RequestBody Map<String, Object> map) {
        return iXhpcAppUserUserService.voluntaryLogin(map);
    }

    /**
     * app用户自动登录
     */
    @ApiOperation("app用户自动登录")
    @PostMapping("/appVoluntaryLogin")
    public R<?> appVoluntaryLogin(HttpServletRequest request,@RequestBody Map<String, Object> map) {
        return iXhpcAppUserUserService.appVoluntaryLogin(request,map);
    }

    /*
     * TODO 获取微信权限标识 openid ,session_key,unionid
     * @author fjd
     * @date 2020-06-24 10:07
     */
    @PostMapping("/jscode2session")
    @ApiOperation(value = "获取微信权限标识", notes = "jsCode")
    public R<?> jsCode(String jsCode, String encryptedData, String iv, String tenantId, String phoneCode) {
        if (StringUtils.isEmpty(jsCode)) {
            return R.fail(HttpStatus.NOT_NULL, "信息不完整");
        }
        encryptedData = encryptedData.replace(' ', '+');
        if ("".equals(tenantId) || null == tenantId) {
            tenantId = "000000";
        }
        R r = settingConfigService.settingConfig(1, tenantId);
        if (r != null && r.getCode() == 200) {

//            Map<String, Object> map = new HashMap<>(16);
//            map.put("openid", "ot6ul4nlSC5ZZOC4rTLS5hedFTGk");
//            if (phoneCode != null && !phoneCode.equals("")) {
//                System.out.println("phoneCode:" + phoneCode);
//                //小程序登录获取token
//                String accesToken = "123456";
//                //获取手机号
//                String phoneCode1 = getPhoneCode(phoneCode, accesToken);
//                if(phoneCode1 !=null &&!phoneCode1.equals("")){
//                    map.put("phone", phoneCode1);
//                }
//                logger.info("1111phone:"+ phoneCode1);
//            }
//
//            return R.ok(map);
            System.out.println("===========111========sessionKey:==============111=============");
            Map<String, Object> mapConfig = (Map<String, Object>) r.getData();
            String url = "https://api.weixin.qq.com/sns/jscode2session?appid=" + mapConfig.get("wxAppId").toString() + "&secret=" + mapConfig.get("wxAppSecret").toString() + "&js_code=" + jsCode + "&grant_type=authorization_code";
            String result = HttpUtils.get(url);
            JSONObject json = JSON.parseObject(result);
            logger.info("========222===========sessionKey:============222==============="+json.toString());
            if (null != json) {
                String openid = json.getString("openid");
                String sessionKey = json.getString("session_key");
                logger.info("========333===========sessionKey:============333===============");
                if (StringUtils.isEmpty(openid)) {
                    return R.fail(HttpStatus.ERROR_STATUS, "openid获取失败");
                }
                if (StringUtils.isEmpty(sessionKey)) {
                    return R.fail(HttpStatus.ERROR_STATUS, "openid获取失败");
                }
                Map<String, Object> map = new HashMap<>(16);
                map.put("openid", openid);
                if (phoneCode != null && !phoneCode.equals("")) {
                    System.out.println("phoneCode:" + phoneCode);
                    //小程序登录获取token
                    String accesToken = getAccesToken(mapConfig.get("wxAppId").toString(), mapConfig.get("wxAppSecret").toString());
                    //获取手机号
                    String phoneCode1 = getPhoneCode(phoneCode, accesToken);
                    if(phoneCode1 !=null &&!phoneCode1.equals("")){
                        map.put("phone", phoneCode1);
                    }
                    logger.info("======111==4444===========sessionKey:=======111=====444==============="+phoneCode1);
                }
//                JSONObject jsonObject = new JSONObject();
//                if ((!"".equals(encryptedData) && encryptedData != null) && (!"".equals(iv) && iv != null)) {
//                    jsonObject = getPhoneNumber(encryptedData, sessionKey, iv);
//                    if (jsonObject !=null) {
//                        map.put("name", jsonObject.get("nickName"));
//                        map.put("sex", jsonObject.get("gender"));
//                        map.put("avatar", jsonObject.get("avatarUrl"));
//                        map.put("phone", jsonObject.get("purePhoneNumber"));
//                    }
//                }
                return R.ok(map);
            }
        }
        return R.fail(HttpStatus.ERROR_STATUS, "openid获取失败");
    }

    @PostMapping("/jscodeSession")
    @ApiOperation(value = "获取微信权限标识", notes = "jsCode")
    public R<?> jscodeSession(String jsCode, String encryptedData, String iv, String tenantId, String phoneCode) {
        if (StringUtils.isEmpty(jsCode)) {
            return R.fail(HttpStatus.NOT_NULL, "信息不完整");
        }
        if ("".equals(tenantId) || null == tenantId) {
            tenantId = "000000";
        }
        R r = settingConfigService.settingConfig(1, tenantId);
        if (r != null && r.getCode() == 200) {
             System.out.println("========444===========sessionKey:============444===============");
            Map<String, Object> mapConfig = (Map<String, Object>) r.getData();
            String url = "https://api.weixin.qq.com/sns/jscode2session?appid=" + mapConfig.get("wxAppId").toString() + "&secret=" + mapConfig.get("wxAppSecret").toString() + "&js_code=" + jsCode + "&grant_type=authorization_code";
            String result = HttpUtils.get(url);
            JSONObject json = JSON.parseObject(result);
            logger.info("========555===========sessionKey:============5555==============="+json.toString());
            if (null != json) {
                String openid = json.getString("openid");
                redisService.setCacheObject("WXToken:" + openid, openid, 115L, TimeUnit.MINUTES);
                String sessionKey = json.getString("session_key");
                logger.info("========666===========sessionKey:============666==============="+sessionKey);
                logger.info("========666===========sessionKey:============666===============");
                if (StringUtils.isEmpty(openid)) {
                    return R.fail(HttpStatus.ERROR_STATUS, "openid获取失败");
                }
                if (StringUtils.isEmpty(sessionKey)) {
                    return R.fail(HttpStatus.ERROR_STATUS, "openid获取失败");
                }
                Map<String, Object> map = new HashMap<>(16);
                map.put("openid", openid);
                if (phoneCode != null && !phoneCode.equals("")) {
                    System.out.println("phoneCode:" + phoneCode);
                    //小程序登录获取token
                    String accesToken = getAccesToken(mapConfig.get("wxAppId").toString(), mapConfig.get("wxAppSecret").toString());
                    //获取手机号
                    String phoneCode1 = getPhoneCode(phoneCode, accesToken);
                    if(phoneCode1 !=null &&!phoneCode1.equals("")){
                        map.put("phone", phoneCode1);
                    }
                    logger.info("========666===========phoneCode1:============666==============="+phoneCode1);
                    map.put("type",1);
                    map.put("tenantId","000000");
                    return loginPhone(map);
                }
                return R.fail(HttpStatus.ERROR_STATUS, "请重新授权登录");
            }
        }
        return R.fail(HttpStatus.ERROR_STATUS, "请重新授权登录");
    }




    //小程序登录获取token
    @ApiOperation("微信小程序登录token")
    @GetMapping("/getAccesToken")
    public  String getAccesToken(String appid, String secret) {
        String captcha = redisService.getCacheObject("WXToken:" + appid);
        if (captcha == null || "".equals(captcha)) {
            logger.info("========777===========phoneCode1:============777===============");
            String url = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=" + appid + "&secret=" + secret;
            String result = HttpUtils.get(url);
            logger.info("========888===========phoneCode1:============888===============");
            JSONObject json = JSON.parseObject(result);
            String accessToken = json.getString("access_token");
            redisService.setCacheObject("WXToken:" + appid, accessToken, 115L, TimeUnit.MINUTES);
            return accessToken;
        }
        return captcha;
    }


    //小程序获取手机号
    @ApiOperation("小程序获取手机号")
    @GetMapping("/getPhoneCode")
    public String getPhoneCode(String code, String token) {
        //System.out.println("========888===========sessionKey:============888===============");
        String url = "https://api.weixin.qq.com/wxa/business/getuserphonenumber?access_token=" + token;
        Map<String, Object> map = new HashMap<>();
        map.put("code", code);
        JSONObject json = new JSONObject(map);
        String result = HttpUtils.post(url, json);
        //System.out.println("========999===========sessionKey:============999===============");
        JSONObject jsonObject = JSON.parseObject(result);
        String errmsg = jsonObject.getString("errmsg");
        if ("ok".equals(errmsg)) {
            String phoneInfo = jsonObject.getString("phone_info");
            JSONObject jsonPhone = JSON.parseObject(phoneInfo);
            String phoneNumber = jsonPhone.getString("phoneNumber");
            return phoneNumber;
        }
        return null;
    }

    /*
     * TODO 微信获取手机号
     * @author fjd
     * @date 2020-06-24 11:23
     */
    public JSONObject getPhoneNumber(String encryptedData, String sessionKey, String iv) {
        try {
            // 被加密的数据
            byte[] dataByte = Base64.decode(encryptedData);
            // 加密秘钥
            byte[] keyByte = Base64.decode(sessionKey);
            // 偏移量
            byte[] ivByte = Base64.decode(iv);
            // 如果密钥不足16位，那么就补足.  这个if 中的内容很重要
            int base = 16;
            if (keyByte.length % base != 0) {
                int groups = keyByte.length / base + (keyByte.length % base != 0 ? 1 : 0);
                byte[] temp = new byte[groups * base];
                Arrays.fill(temp, (byte) 0);
                System.arraycopy(keyByte, 0, temp, 0, keyByte.length);
                keyByte = temp;
            }
            // 初始化
            Security.addProvider(new BouncyCastleProvider());
            Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
            SecretKeySpec spec = new SecretKeySpec(keyByte, "AES");
            AlgorithmParameters parameters = AlgorithmParameters.getInstance("AES");
            parameters.init(new IvParameterSpec(ivByte));
            cipher.init(Cipher.DECRYPT_MODE, spec, parameters);// 初始化
            byte[] resultByte = cipher.doFinal(dataByte);
            if (null != resultByte && resultByte.length > 0) {
                String result = new String(resultByte, "UTF-8");
                return JSONObject.parseObject(result);
            }
        } catch (Exception e) {
        }
        return null;
    }

    /**
     * 支付宝授权
     */
    @ApiOperation("支付宝授权")
    @PostMapping("/alipayEmpower")
    public R<?> alipayEmpower(@RequestParam String code, String tenantId) throws Exception {
        if ("".equals(tenantId) || null == tenantId) {
            tenantId = "000000";
        }
        R r = settingConfigService.settingConfig(2, tenantId);
        if (r != null && r.getCode() == 200) {
            Map<String, Object> map = (Map<String, Object>) r.getData();
            /** 初始化 **/
            CertAlipayRequest certAlipayRequest = new CertAlipayRequest();
            /** 支付宝网关 **/
            certAlipayRequest.setServerUrl("https://openapi.alipay.com/gateway.do");
            /** 应用id，如何获取请参考：https://opensupport.alipay.com/support/helpcenter/190/201602493024 **/
            certAlipayRequest.setAppId(map.get("zfbAppId").toString());
            /** 应用私钥, 如何获取请参考：https://opensupport.alipay.com/support/helpcenter/207/201602471154?ant_source=antsupport  **/
            certAlipayRequest.setPrivateKey(map.get("zfbPrivateKey").toString());
            /** 应用公钥证书路径，下载后保存位置的绝对路径  **/
            certAlipayRequest.setCertPath(map.get("zfbAppCertPublicKey").toString());
            /** 支付宝公钥证书路径，下载后保存位置的绝对路径 **/
            certAlipayRequest.setAlipayPublicCertPath(map.get("zfbAlipayCertPublicKeyRsa").toString());
            /** 支付宝根证书路径，下载后保存位置的绝对路径 **/
            certAlipayRequest.setRootCertPath(map.get("zfbAlipayRootCert").toString());
            /** 设置签名类型 **/
            certAlipayRequest.setSignType("RSA2");
            /** 设置请求格式，固定值json **/
            certAlipayRequest.setFormat("json");
            /** 设置编码格式 **/
            certAlipayRequest.setCharset("UTF-8");
            AlipayClient alipayClient = new DefaultAlipayClient(certAlipayRequest);
            AlipaySystemOauthTokenRequest request = new AlipaySystemOauthTokenRequest();
            request.setGrantType("authorization_code");
            //  auth_code  前端授权后得到的授权码
            request.setCode(code);
            AlipaySystemOauthTokenResponse response = alipayClient.certificateExecute(request);
            System.out.println("response>>>>>>>>>>>>"+response.toString());
            //服务端请求返回，RSA2密钥和公钥证书请求方式不同，如当面付
            // RSA2密钥请求response = alipayClient.execute(request);
            // 公钥证书请求请求response = alipayClient.certificateExecute(request);
            if (response.isSuccess()) {
                System.out.println("调用成功");
            } else {
                return R.fail(500,"获取失败!");
            }
            return R.ok(response);
        }
        return R.fail(500,"获取失败!");
    }

    /**
     * 支付宝授权
     */
    @ApiOperation("支付宝授权手机号登录")
    @PostMapping("/alipayEmpowerPhone")
    public R<?> alipayEmpowerPhone(@RequestBody Map<String, Object> map) throws Exception {
        String openid = map.get("openid").toString();
        String tenantId = map.get("tenantId").toString();
        String response = map.get("response").toString();
        if ("".equals(tenantId) || null == tenantId) {
            tenantId = "000000";
        }
        if(response==null || "".equals(response)){
            return R.fail("获取失败");
        }
//        JSONObject jsonObject = JSONObject.parseObject(response);
//        String accessToken = jsonObject.getString("response");
        try {
            String encryptType = "AES";
            String decryptKey ="RK+OjbMPhWuSEsnAX4Yjuw==";
            String charset = "UTF-8";
            String plainData = AlipayEncrypt.decryptContent(response, encryptType, decryptKey, charset);
            JSONObject phone = JSON.parseObject(plainData);
            String mobile = phone.getString("mobile");
            Map maps = new HashMap();
            maps.put("phone", mobile);
            maps.put("openid", openid);
            maps.put("type",2);
            maps.put("tenantId",tenantId);
            return loginPhone(maps);
        } catch (AlipayApiException e) {
            //解密异常, 记录日志
            //throw new Exception("解密异常");
            e.printStackTrace();
        }


        return R.fail("获取手机号失败");
    }


    /**
     * 支付宝授权
     */
    @ApiOperation("支付宝授权")
    @PostMapping("/alipayEmpowerYu")
    public AjaxResult alipayEmpowerYu(@RequestParam String code) throws Exception {

        /** 初始化 **/
        CertAlipayRequest certAlipayRequest = new CertAlipayRequest();
        /** 支付宝网关 **/
        certAlipayRequest.setServerUrl("https://openapi.alipay.com/gateway.do");
        /** 应用id，如何获取请参考：https://opensupport.alipay.com/support/helpcenter/190/201602493024 **/
        certAlipayRequest.setAppId(environment.getProperty("ALIPAYAPPID"));
        /** 应用私钥, 如何获取请参考：https://opensupport.alipay.com/support/helpcenter/207/201602471154?ant_source=antsupport  **/
        certAlipayRequest.setPrivateKey(environment.getProperty("ALIPAYPRIVATEKEY"));
        /** 应用公钥证书路径，下载后保存位置的绝对路径  **/
        certAlipayRequest.setCertPath(environment.getProperty("CERTPATH"));
        /** 支付宝公钥证书路径，下载后保存位置的绝对路径 **/
        certAlipayRequest.setAlipayPublicCertPath(environment.getProperty("PUBLICCERTPATH"));
        /** 支付宝根证书路径，下载后保存位置的绝对路径 **/
        certAlipayRequest.setRootCertPath(environment.getProperty("ROOTCRETPATH"));
        /** 设置签名类型 **/
        certAlipayRequest.setSignType("RSA2");
        /** 设置请求格式，固定值json **/
        certAlipayRequest.setFormat("json");
        /** 设置编码格式 **/
        certAlipayRequest.setCharset("UTF-8");
        AlipayClient alipayClient = new DefaultAlipayClient(certAlipayRequest);
        AlipaySystemOauthTokenRequest request = new AlipaySystemOauthTokenRequest();
        request.setGrantType("authorization_code");
        //  auth_code  前端授权后得到的授权码
        request.setCode(code);
        AlipaySystemOauthTokenResponse response = alipayClient.certificateExecute(request);
        //服务端请求返回，RSA2密钥和公钥证书请求方式不同，如当面付
        // RSA2密钥请求response = alipayClient.execute(request);
        // 公钥证书请求请求response = alipayClient.certificateExecute(request);
        if (response.isSuccess()) {
            System.out.println("调用成功");
        } else {
            System.out.println("调用失败");
        }
        return AjaxResult.success(response);
    }


    /**
     * 注销账号
     */
    @ApiOperation("注销账号")
    @PostMapping("/logout")
    public R<?> logout(HttpServletRequest request, String phone, String code) {
        return iXhpcAppUserUserService.logout(request, phone, code);
    }


    /**
     * 设置小程序用户自动退款功能
     *
     * @param
     */
    @ApiOperation("设置小程序用户自动退款功能")
    @PostMapping("/updateIsRefund")
    public R<?> updateIsRefund(@RequestBody Map<String, Object> map) {
        if (map != null) {
            Long userId = Long.parseLong(map.get("userId").toString());
            Integer userType = Integer.parseInt(map.get("userType").toString());
            Integer isRefund = Integer.parseInt(map.get("isRefund").toString());
            return iXhpcAppUserUserService.updateIsRefund(userId, userType, isRefund);
        }
        return R.fail(HttpStatus.ERROR_STATUS, "修改失败");
    }

    /**
     * 设置小程序用户双枪并充功能
     * @param
     */
    @ApiOperation("设置小程序用户双枪并充功能")
    @PostMapping("/doubleGunCharging")
    public R<?> doubleGunCharging(@RequestBody Map<String, Object> map) {
        if (map != null) {
            Long userId = Long.parseLong(map.get("userId").toString());
            Integer userType = Integer.parseInt(map.get("userType").toString());
            Integer sunchaSwitch = Integer.parseInt(map.get("sunchaSwitch").toString());
            return iXhpcAppUserUserService.doubleGunCharging(userId, userType, sunchaSwitch);
        }
        return R.fail(HttpStatus.ERROR_STATUS, "修改失败");
    }


    /**
     * 设置小程序用户电池保护
     *
     * @param
     */
    @ApiOperation("设置小程序用户电池保护")
    @PostMapping("/batteryProtect")
    public R<?> batteryProtect(HttpServletRequest request, @RequestBody Map<String, Object> map) {
        if (map != null) {
            Integer soc = Integer.parseInt(map.get("soc").toString());
            Integer socProtect = Integer.parseInt(map.get("socProtect").toString());
            Integer userType = Integer.parseInt(map.get("userType").toString());
            return iXhpcAppUserUserService.batteryProtect(request, soc, socProtect, userType);
        }
        return R.fail(HttpStatus.ERROR_STATUS, "修改失败");
    }

    /**
     * 设置每小时运行一次获取微信token
     * @param
     */
    @Scheduled(cron = "0 0 0/1 * * ?")
    @GetMapping("/getAccesTokenYu")
    public void getAccesTokenYu() {
        System.out.println("===================设置每小时运行一次获取微信token=========================");
        getAccesToken("wxd0a48e00319ef8a7", "e26d9088b58e24af69411d5933cece47");
        System.out.println("===================设置每小时运行一次获取微信token=========================");
    }


    //微信消息开通
    @GetMapping("/getPushMessage")
    public String getPushMessage(@RequestParam Map<String, String> params)throws Exception {
        // 微信发送的请求中 会有四个参数
        // 微信加密签名，signature结合了开发者填写的 token 参数和请求中的 timestamp 参数、nonce参数。
        String signature = params.get("signature");
        // 随机字符串
        String echostr = params.get("echostr");
        // 时间戳
        String timestamp = params.get("timestamp");
        // 随机数
        String nonce = params.get("nonce");
        // 消息推送配置中的 Token(令牌)
        String token = "sichuanxianghuakejiyouxiangongsi";
        // 验证
        String msgSignature = WechatDecryptDataUtil.getSHA1(token, timestamp, nonce);
        // 验证失败
        if (!signature.equals(msgSignature)) {
            return "false";
        }
        // 验证成功 将 echostr 原格式返回 ，即可完成验证
        return echostr;

    }

    @ApiOperation("获取用户车牌号")
    @GetMapping("/getXhpcUserVehicleMessage")
    public R getXhpcUserVehicleMessage(Long userId, Integer source){
        return xhpcUserVehicleService.getXhpcUserVehicleMessage(userId, source);
    }

    @ApiOperation("添加车牌号/VIN码")
    @PostMapping("/addUserVehicle")
    public R addUserVehicle(@RequestBody XhpcUserVehicle xhpcUserVehicle){
        return xhpcUserVehicleService.addUserVehicle(xhpcUserVehicle);
    }

    //小程序用户车牌列表
    @ApiOperation("小程序用户车牌列表")
    @GetMapping("/getUserVehicleList")
    public TableDataInfo getUserVehicleList(HttpServletRequest request,Long appUserId,Integer source) {
        List<Map<String, Object>> list = xhpcUserVehicleService.getUserVehicleList(request,appUserId,source);
        return getDataTable(list);
    }

    @ApiOperation("阿里云自动识别行驶证")
    @GetMapping("/addUserVehicleUrl")
    public R addUserVehicleUrl(String url,Long appUserId,Integer source){
        try {

            //同一个用户一天只有10次机会
            Integer number = redisService.getCacheObject("vehicle:userId:"+appUserId+source);
            if(number !=null && number>10){
                return R.fail("今天开通VIN码自动识别已达到上线,请手动输入车牌号和VIN开通");
            }
            com.aliyun.ocr20191230.Client client = createClient(accessKeyId, accessKeySecret);
            URL urls = new URL(url);
            InputStream inputStream = urls.openConnection().getInputStream();
            com.aliyun.ocr20191230.models.RecognizeDrivingLicenseAdvanceRequest recognizeDrivingLicenseAdvanceRequest = new com.aliyun.ocr20191230.models.RecognizeDrivingLicenseAdvanceRequest()
                    .setImageURLObject(inputStream)
                    .setSide("face");
            com.aliyun.teautil.models.RuntimeOptions runtime = new com.aliyun.teautil.models.RuntimeOptions();
            RecognizeDrivingLicenseResponse response = client.recognizeDrivingLicenseAdvance(recognizeDrivingLicenseAdvanceRequest, runtime);
            if(response.getStatusCode()==200){
                RecognizeDrivingLicenseResponseBody.RecognizeDrivingLicenseResponseBodyDataFaceResult faceResult = response.getBody().getData().getFaceResult();

                XhpcUserVehicle xhpcUserVehicle=new XhpcUserVehicle();
                xhpcUserVehicle.setOwner(faceResult.getOwner());
                xhpcUserVehicle.setVehicleName(faceResult.getPlateNumber());
                xhpcUserVehicle.setEngineNumber(faceResult.getEngineNumber());
                xhpcUserVehicle.setAddress(faceResult.getAddress());
                xhpcUserVehicle.setVehicleType(faceResult.getVehicleType());
                xhpcUserVehicle.setModel(faceResult.getModel());
                xhpcUserVehicle.setRegisterDate(faceResult.getRegisterDate());
                xhpcUserVehicle.setLssueDate(faceResult.getRegisterDate());
                xhpcUserVehicle.setUseCharacter(faceResult.getUseCharacter());
                xhpcUserVehicle.setVinSpecCode(faceResult.getVin());
                xhpcUserVehicle.setAppUserId(appUserId);
                xhpcUserVehicle.setSource(source);
                xhpcUserVehicle.setDelFlag(1);

                xhpcUserVehicleService.addUserVehicle(xhpcUserVehicle);

                Map<String,Object> map =new HashMap<>();
                map.put("vinSpecCode",faceResult.getVin());
                map.put("vehicleName",faceResult.getPlateNumber());
                map.put("vehicleId",xhpcUserVehicle.getVehicleId());

                if(number==null){
                    redisService.setCacheObject("vehicle:userId:"+appUserId+source,1);
                }else{
                    redisService.setCacheObject("vehicle:userId:"+appUserId+source,number+1);
                }
                return R.ok(map);
            }else{
                System.out.println("=======1====请重新上传行驶证=========appUserId:"+appUserId+"====source:"+source+"=");
                return R.fail("请重新上传行驶证");
            }
        }catch (Exception e){
            e.printStackTrace();
        }
        System.out.println("=======2====请重新上传行驶证=========appUserId:"+appUserId+"====source:"+source+"=");
        return R.fail("请重新上传行驶证");
    }

    public static com.aliyun.ocr20191230.Client createClient(String accessKeyId, String accessKeySecret) throws Exception {
        com.aliyun.teaopenapi.models.Config config = new com.aliyun.teaopenapi.models.Config()
                .setAccessKeyId(accessKeyId)
                .setAccessKeySecret(accessKeySecret);
        // 访问的域名
        config.endpoint = "ocr.cn-shanghai.aliyuncs.com";
        return new com.aliyun.ocr20191230.Client(config);
    }

    //每天凌晨自动清除自动识别缓存
    @Scheduled(cron = "0 0 23 * * ? ")
    @GetMapping("/realtimeVehicleDedis")
    public R realtimeVehicleDedis() {
        logger.info("清除缓存>>>>>vehicle:userId:：");
        Collection<String> realtimeOrder = REDIS.keys("vehicle:userId:*");
        for (String okey : realtimeOrder) {
            redisService.deleteObject(okey);
        }
        return R.ok();
    }


    @ApiOperation("删除VIN或者车牌接口")
    @PostMapping("/deleteUserVehicleById")
    public R deleteUserVehicleById(@RequestBody XhpcUserVehicle xhpcUserVehicle){

        return xhpcUserVehicleService.deleteUserVehicleById(xhpcUserVehicle.getVehicleId());
    }


    @ApiOperation("默认车辆")
    @PostMapping("/defaultUserVehicle")
    public R defaultUserVehicle(@RequestBody XhpcUserVehicle xhpcUserVehicle){
        return xhpcUserVehicleService.defaultUserVehicle(xhpcUserVehicle.getVehicleId(),xhpcUserVehicle.getAppUserId(),xhpcUserVehicle.getSource());
    }

    @ApiOperation("开通VIN码")
    @PostMapping("/enlightenedUserVehicle")
    public R enlightenedUserVehicle(@RequestBody XhpcUserVehicle xhpcUserVehicle){
        return xhpcUserVehicleService.enlightenedUserVehicle(xhpcUserVehicle.getVehicleId(),xhpcUserVehicle.getAppUserId(),xhpcUserVehicle.getSource(),xhpcUserVehicle.getStatus());
    }

    @ApiOperation("获取邮箱验证码")
    @GetMapping("/emailCode")
    public R emailCode(HttpServletRequest request,String emailCode){
        String language = request.getHeader("language");
        if("".equals(emailCode) || emailCode ==null){
            if(language.equals(UserTypeUtil.LANGUAGE_ARA)){
                return R.fail(HttpStatus.NOT_NULL, "يجب ملء صندوق البريد");
            }else if(language.equals(UserTypeUtil.LANGUAGE_EN)){
                return R.fail(HttpStatus.NOT_NULL, "Email must be filled in");
            }else{
                return R.fail(HttpStatus.NOT_NULL, "邮箱必须填写");
            }
        }else{
            String random = getRandom();
            String key ="emailCode:"+emailCode;
            String token ="tokenEmailCode:"+emailCode;
            String cacheObject = REDIS.getCacheObject(token);
            if(language.equals(UserTypeUtil.LANGUAGE_ARA)){
                if (cacheObject != null) {
                    return R.fail("1012", "عملية متكررة ، يرجى المحاولة مرة أخرى في 1 دقيقة");
                }
                MailUtil.send(emailCode, "البريد الإلكتروني من United-Charger","【United-Charger】صندوق البريد رمز التحقق:"+random,  false, null);
                REDIS.setCacheObject(key, random, 300L, TimeUnit.SECONDS);
                REDIS.setCacheObject(token, random, 60L, TimeUnit.SECONDS);
                return R.ok(HttpStatus.NOT_NULL, "رمز التحقق تم إرسالها إلى صندوق البريد");
            }else if(language.equals(UserTypeUtil.LANGUAGE_EN)){
                if (cacheObject != null) {
                    return R.fail("1012", "Frequent operation, please retry in 1 minute");
                }
                MailUtil.send(emailCode, "Email from United-Charger", "【United-Charger】Email verification code:"+random, false, null);
                REDIS.setCacheObject(key, random, 300L, TimeUnit.SECONDS);
                REDIS.setCacheObject(token, random, 60L, TimeUnit.SECONDS);
                return R.ok(HttpStatus.NOT_NULL, "The verification code has been sent to the email. Please check");
            }else{

                if (cacheObject != null) {
                    return R.fail("1012", "操作频繁，请于1分钟后重试");
                }
                MailUtil.send(emailCode, "邮件来自United-Charger", "【United-Charger】邮箱验证码:"+random, false, null);
                REDIS.setCacheObject(key, random, 300L, TimeUnit.SECONDS);
                REDIS.setCacheObject(token, random, 60L, TimeUnit.SECONDS);
                return R.ok(HttpStatus.NOT_NULL, "验证码已发送邮箱请查看");
            }
        }
    }

    private String getRandom(){
        Random rnd = new Random();
        int i = rnd.nextInt(999999);
        if(i<100000){
            i=i+100000;
        }
        return i+"";
    }


}
