From f237a61c412870933f47316a011237cd538de9bc Mon Sep 17 00:00:00 2001 From: 无关风月 <443237572@qq.com> Date: 星期二, 20 八月 2024 09:07:02 +0800 Subject: [PATCH] 新增需求 --- guns-admin/src/main/java/com/stylefeng/guns/modular/api/SportsController.java | 745 +++++++++++++++++++++++++++++++++++++++++++++++++-------- 1 files changed, 639 insertions(+), 106 deletions(-) diff --git a/guns-admin/src/main/java/com/stylefeng/guns/modular/api/SportsController.java b/guns-admin/src/main/java/com/stylefeng/guns/modular/api/SportsController.java index ccf4d6b..4bb2ac5 100644 --- a/guns-admin/src/main/java/com/stylefeng/guns/modular/api/SportsController.java +++ b/guns-admin/src/main/java/com/stylefeng/guns/modular/api/SportsController.java @@ -1,12 +1,26 @@ package com.stylefeng.guns.modular.api; +import java.io.BufferedReader; +import java.io.ByteArrayInputStream; import java.io.PrintWriter; +import java.math.BigInteger; import java.math.RoundingMode; +import java.security.KeyFactory; import java.security.PrivilegedAction; +import java.security.PublicKey; +import java.security.cert.CertificateException; +import java.security.cert.CertificateFactory; +import java.security.cert.X509Certificate; +import java.security.interfaces.ECPublicKey; +import java.security.spec.X509EncodedKeySpec; import java.sql.Timestamp; import java.time.LocalTime; import java.util.Date; import com.alibaba.fastjson.JSONObject; +import com.auth0.jwt.JWT; +import com.auth0.jwt.algorithms.Algorithm; +import com.auth0.jwt.exceptions.SignatureVerificationException; +import com.auth0.jwt.interfaces.DecodedJWT; import com.baomidou.mybatisplus.mapper.EntityWrapper; import com.stylefeng.guns.modular.system.dto.AddUserWatchDTO; import com.stylefeng.guns.modular.system.model.*; @@ -16,6 +30,8 @@ import com.stylefeng.guns.modular.system.util.Page; import com.stylefeng.guns.modular.system.vo.*; import com.stylefeng.guns.modular.system.dto.CourseQuery; +import io.jsonwebtoken.Claims; +import io.jsonwebtoken.Jwts; import io.swagger.annotations.ApiImplicitParam; import io.swagger.annotations.ApiImplicitParams; import io.swagger.annotations.ApiModelProperty; @@ -86,6 +102,7 @@ return "LO" + sdf.format(new Date()) + UUIDUtil.getRandomCode(5); } + @Autowired private IRechargeService rechargeService; @PostMapping("/iospay") @@ -153,11 +170,32 @@ BigDecimal realMoney) throws Exception { AppUser appUser = appUserService.getAppUser(); + if (appUser == null){ + return ResultUtil.tokenErr("登录失效"); + } BaseWarpper baseWarpper = new BaseWarpper(); switch (buyType){ case 1: Course course = courseService.selectById(id); - BigDecimal amount = fitnessPositionService.selectById(course.getPositionId()).getAmount(); + FitnessPosition fitnessPosition = fitnessPositionService.selectById(course.getPositionId()); + BigDecimal amount = new BigDecimal(BigInteger.ZERO); + switch (course.getDifficulty()){ + case 1: + amount = fitnessPosition.getAmount(); + break; + case 2: + amount = fitnessPosition.getAmount2(); + break; + case 3: + amount = fitnessPosition.getAmount3(); + break; + case 4: + amount = fitnessPosition.getAmount4(); + break; + case 5: + amount = fitnessPosition.getAmount5(); + break; + } // 购买课程 OrderCourse orderCourse = new OrderCourse(); orderCourse.setCode(this.getOrderNum()); @@ -218,7 +256,68 @@ } return ResultUtil.success(); } + /** + * 购买套餐微信支付回调 + * + * @param request + * @param response + */ + @ResponseBody + @PostMapping("/base/testApple") + public void testApple(HttpServletRequest request, HttpServletResponse response) { + try { + Map<String, String> params = new HashMap<String, String>(); + System.err.println("请求"+request); + BufferedReader reader = request.getReader(); + String string1 = reader.toString(); + System.err.println("请求reader"+string1); + StringBuilder requestBody = new StringBuilder(); + String line; + while ((line = reader.readLine()) != null) { + requestBody.append(line); + } + System.err.println("全部请求体"+requestBody); + org.json.JSONObject jsonObject1 = new org.json.JSONObject(requestBody.toString()); + System.err.println("json串"+jsonObject1); + String o = jsonObject1.getString("signedPayload"); + JSONObject payload = verifyAndGet(o); + String notificationType = payload.get("notificationType").toString(); + JSONObject data = payload.getJSONObject("data"); + String signedTransactionInfo = data.get("signedTransactionInfo").toString(); + String environment = data.get("environment").toString(); + JSONObject transactionInfo = verifyAndGet(signedTransactionInfo); + String transactionId = transactionInfo.get("transactionId").toString(); + String originalTransactionId = transactionInfo.get("originalTransactionId").toString(); + String productId = transactionInfo.get("productId").toString(); + System.err.println("json串"+transactionInfo); + System.err.println("data"+data); + // 苹果流水号 + String string = transactionInfo.getString("originalTransactionId"); + System.err.println("苹果流水号"+string); + Recharge orderNumber = rechargeService.selectOne(new EntityWrapper<Recharge>() + .eq("orderNumber", string)); + if (orderNumber!=null){ + if (orderNumber.getState()!=2){ + // 进入 + orderNumber.setState(2); + orderNumber.setPayTime(new Date()); + rechargeService.updateById(orderNumber); + BigDecimal amount = orderNumber.getAmount(); + AppUser appUser = appUserService.selectById(orderNumber.getUserId()); + BigDecimal add = appUser.getBalance().add(amount); + appUser.setBalance(add); + appUserService.updateById(appUser); + } + } + PrintWriter out = response.getWriter(); + out.write("success"); + out.flush(); + out.close(); + } catch (Exception e) { + e.printStackTrace(); + } + } /** * 购买套餐微信支付回调 * @@ -246,6 +345,67 @@ order.setPayTime(new Date()); order.setPayType(1); orderService.updateById(order); + BigDecimal divisor = new BigDecimal("100"); + // 计算提成 + SysSet sysSet = sysSetService.selectById(1); + // 邀请人可获得被邀请人消费金额比例 + String people = sysSet.getPeople(); + // 团队长可获得团员消费金额比例 + String header = sysSet.getHeader(); + // 邀请人比例 + BigDecimal bigDecimal = new BigDecimal(people).divide(divisor); + // 获取金额 + BigDecimal multiply = order.getRealMoney().multiply(bigDecimal); + BigDecimal bigDecimal1 = multiply.setScale(2, BigDecimal.ROUND_DOWN); + // 如果使用了优惠券将优惠券修改为已消费 + if (order.getCouponId()!=null){ + CouponReceive couponReceive1 = couponReceiveService.selectById(order.getCouponId()); + couponReceive1.setState(2); + couponReceiveService.updateById(couponReceive1); + } + AppUser appUser = appUserService.selectById(order.getUserId()); + // 如果当前用户有邀请人 + if (appUser.getInviteUserId()!=null){ + if (StringUtils.hasLength(people)){ + Invite invite = new Invite(); + invite.setUserId(appUser.getId()); + invite.setInsertTime(new Date()); + invite.setAmount(bigDecimal1); + invite.setConsume(order.getRealMoney()); + invite.setGiftUserId(appUser.getInviteUserId()); + invite.setType(1); + inviteService.insert(invite); + // 给用户加余额 + AppUser appUser1 = appUserService.selectById(appUser.getInviteUserId()); + BigDecimal balance1 = appUser1.getBalance(); + BigDecimal add = balance1.add(bigDecimal1); + appUser1.setBalance(add); + appUserService.updateById(appUser1); + } + if (StringUtils.hasLength(header)){ + // 先判断当前用户有没有团队长 + if (appUserService.selectById(appUser.getInviteUserId()).getInviteUserId()!=null){ + // 有团队长 + BigDecimal bigDecimal2 = new BigDecimal(header).divide(divisor); + BigDecimal multiply1 = order.getRealMoney().multiply(bigDecimal2); + BigDecimal bigDecimal3 = multiply1.setScale(2, BigDecimal.ROUND_DOWN); + Invite invite = new Invite(); + invite.setUserId(appUser.getId()); + invite.setInsertTime(new Date()); + invite.setAmount(bigDecimal3); + invite.setConsume(order.getRealMoney()); + invite.setGiftUserId(appUserService.selectById(appUser.getInviteUserId()).getInviteUserId()); + invite.setType(2); + inviteService.insert(invite); + // 给用户加余额 + AppUser appUser1 = appUserService.selectById(appUserService.selectById(appUser.getInviteUserId()).getInviteUserId()); + BigDecimal balance1 = appUser1.getBalance(); + BigDecimal add = balance1.add(bigDecimal1); +// appUser1.setBalance(add); + appUserService.updateById(appUser1); + } + } + } PrintWriter out = response.getWriter(); out.write(result); out.flush(); @@ -282,6 +442,68 @@ orderCourse.setPayType(1); orderCourse.setPayTime(new Date()); orderCourseService.updateById(orderCourse); + // 如果使用了优惠券将优惠券修改为已消费 + if (orderCourse.getCouponId()!=null){ + CouponReceive couponReceive1 = couponReceiveService.selectById(orderCourse.getCouponId()); + couponReceive1.setState(2); + couponReceiveService.updateById(couponReceive1); + } + BigDecimal divisor = new BigDecimal("100"); + // 计算提成 + SysSet sysSet = sysSetService.selectById(1); + // 邀请人可获得被邀请人消费金额比例 + String people = sysSet.getPeople(); + // 团队长可获得团员消费金额比例 + String header = sysSet.getHeader(); + // 邀请人比例 + BigDecimal bigDecimal = new BigDecimal(people).divide(divisor); + // 获取金额 + BigDecimal multiply = orderCourse.getRealMoney().multiply(bigDecimal); + BigDecimal bigDecimal1 = multiply.setScale(2, BigDecimal.ROUND_DOWN); + + AppUser appUser = appUserService.selectById(orderCourse.getUserId()); + // 如果当前用户有邀请人 + if (appUser.getInviteUserId()!=null){ + if (StringUtils.hasLength(people)){ + Invite invite = new Invite(); + invite.setUserId(appUser.getId()); + invite.setInsertTime(new Date()); + invite.setAmount(bigDecimal1); + invite.setConsume(orderCourse.getRealMoney()); + invite.setGiftUserId(appUser.getInviteUserId()); + invite.setType(1); + inviteService.insert(invite); + // 给用户加余额 + AppUser appUser1 = appUserService.selectById(appUser.getInviteUserId()); + BigDecimal balance1 = appUser1.getBalance(); + BigDecimal add = balance1.add(bigDecimal1); + appUser1.setBalance(add); + appUserService.updateById(appUser1); + } + if (StringUtils.hasLength(header)){ + // 先判断当前用户有没有团队长 + if (appUserService.selectById(appUser.getInviteUserId()).getInviteUserId()!=null){ + // 有团队长 + BigDecimal bigDecimal2 = new BigDecimal(header).divide(divisor); + BigDecimal multiply1 = orderCourse.getRealMoney().multiply(bigDecimal2); + BigDecimal bigDecimal3 = multiply1.setScale(2, BigDecimal.ROUND_DOWN); + Invite invite = new Invite(); + invite.setUserId(appUser.getId()); + invite.setInsertTime(new Date()); + invite.setAmount(bigDecimal3); + invite.setConsume(orderCourse.getRealMoney()); + invite.setGiftUserId(appUserService.selectById(appUser.getInviteUserId()).getInviteUserId()); + invite.setType(2); + inviteService.insert(invite); + // 给用户加余额 + AppUser appUser1 = appUserService.selectById(appUserService.selectById(appUser.getInviteUserId()).getInviteUserId()); + BigDecimal balance1 = appUser1.getBalance(); + BigDecimal add = balance1.add(bigDecimal1); +// appUser1.setBalance(add); + appUserService.updateById(appUser1); + } + } + } PrintWriter out = response.getWriter(); out.write(result); out.flush(); @@ -320,7 +542,11 @@ recharge.setPayTime(new Date()); recharge.setPayType(1); rechargeService.updateById(recharge); - + AppUser appUser = appUserService.selectById(recharge.getUserId()); + BigDecimal balance = appUser.getBalance(); + BigDecimal add = balance.add(recharge.getAmount()); + appUser.setBalance(add); + appUserService.updateById(appUser); PrintWriter out = response.getWriter(); out.write(result); out.flush(); @@ -330,8 +556,90 @@ e.printStackTrace(); } } + @ResponseBody + @PostMapping("/base/applePayResult") + public void applePayResult(HttpServletRequest request, HttpServletResponse response) { + + } @Autowired private IInviteService inviteService; + @ResponseBody + @PostMapping("/base/sports/payApple") + @ApiOperation(value = "苹果支付补偿", tags = {"运动"}) + @ApiImplicitParams({ + @ApiImplicitParam(name = "Authorization", value = "Bearer eyJhbGciOiJIUzUxMiJ....", required = true, paramType = "header"), + @ApiImplicitParam(name = "id", value = "课程id或者套餐id", required = true), + @ApiImplicitParam(name = "buyType", value = "购买类型 1=购买课程 2=购买套餐 ", required = true), + @ApiImplicitParam(name = "transactionReceipt", value = "苹果账单"), + }) + public ResultUtil payApple( + Integer id, + Integer buyType, + String transactionReceipt) throws Exception { + AppUser appUser = appUserService.getAppUser(); + if (appUser == null){ + return ResultUtil.tokenErr("登录失效"); + } + switch (buyType){ + case 1: + Course orderCourse1 = courseService.selectById(id); + FitnessPosition fitnessPosition = fitnessPositionService.selectById(orderCourse1.getPositionId()); + switch (orderCourse1.getDifficulty()){ + case 1: + fitnessPosition.setAmount(fitnessPosition.getAppleAmount()); + break; + case 2: + fitnessPosition.setAmount(fitnessPosition.getAppleAmount2()); + break; + case 3: + fitnessPosition.setAmount(fitnessPosition.getAppleAmount3()); + break; + case 4: + fitnessPosition.setAmount(fitnessPosition.getAppleAmount4()); + break; + case 5: + fitnessPosition.setAmount(fitnessPosition.getAppleAmount5()); + break; + } + Boolean success1 = IosPalUtils.isSuccess(transactionReceipt); + if (success1){ + OrderCourse orderCourse = new OrderCourse(); + orderCourse.setCode(this.getOrderNum()); + orderCourse.setOrderNumber(this.getOrderNum()); + orderCourse.setUserId(appUser.getId()); + orderCourse.setPayTime(new Date()); + orderCourse.setInsertTime(new Date()); + orderCourse.setPayType(4); + orderCourse.setAmount(fitnessPosition.getAppleAmount()); + orderCourse.setCouponId(null); + orderCourse.setRealMoney(fitnessPosition.getAppleAmount()); + orderCourse.setState(2); + orderCourse.setCourseId(id); + orderCourseService.insert(orderCourse); + } + break; + case 2: + Package orderCourse2 = packageService.selectById(id); + Boolean success2 = IosPalUtils.isSuccess(transactionReceipt); + if (success2){ + Order orderCourse = new Order(); + orderCourse.setCode(this.getOrderNum()); + orderCourse.setOrderNumber(this.getOrderNum()); + orderCourse.setUserId(appUser.getId()); + orderCourse.setPayTime(new Date()); + orderCourse.setInsertTime(new Date()); + orderCourse.setPayType(4); + orderCourse.setAmount(orderCourse2.getAppleAmount()); + orderCourse.setCouponId(null); + orderCourse.setRealMoney(orderCourse2.getAppleAmount()); + orderCourse.setState(2); + orderCourse.setPackageId(id); + orderService.insert(orderCourse); + } + break; + } + return ResultUtil.success(); + } @ResponseBody @PostMapping("/base/sports/pay") @ApiOperation(value = "支付", tags = {"运动"}) @@ -351,26 +659,57 @@ String transactionIdentifier, BigDecimal orderMoney) throws Exception { AppUser appUser = appUserService.getAppUser(); - OrderCourse orderCourse = orderCourseService.selectOne(new EntityWrapper<OrderCourse>() - .eq("id",id) - .eq("userId",appUser.getId())); - Order order = orderService.selectOne(new EntityWrapper<Order>() - .eq("id",id) - .eq("userId",appUser.getId())); + if (appUser == null){ + return ResultUtil.tokenErr("登录失效"); + } + + switch (buyType){ + case 1: + OrderCourse orderCourse = orderCourseService.selectOne(new EntityWrapper<OrderCourse>() + .eq("id",id) + .eq("userId",appUser.getId())); +// if (orderCourse != null){ +// payType = orderCourse.getPayType(); +// } + break; + case 2: + Order order = orderService.selectOne(new EntityWrapper<Order>() + .eq("id",id) + .eq("userId",appUser.getId())); +// if (order!=null){ +// payType = order.getPayType(); +// } + break; + case 3: + Recharge recharge1 = rechargeService.selectOne(new EntityWrapper<Recharge>() + .eq("id",id) + .eq("userId",appUser.getId())); + if (recharge1 != null){ + if (payType == 4){ + recharge1.setPayType(3); + }else{ + recharge1.setPayType(payType); + } +// payType = recharge1.getPayType(); + recharge1.setOrderNumber(transactionIdentifier); + rechargeService.updateById(recharge1); + } + break; + } Recharge recharge1 = rechargeService.selectOne(new EntityWrapper<Recharge>() .eq("id",id) .eq("userId",appUser.getId())); - if (recharge1 != null){ - payType = recharge1.getPayType(); - }else if (order!=null){ - payType = order.getPayType(); - } else if (orderCourse != null){ - payType = orderCourse.getPayType(); - } + OrderCourse orderCourse = orderCourseService.selectOne(new EntityWrapper<OrderCourse>() + .eq("id",id) + .eq("userId",appUser.getId())); + Order order = orderService.selectOne(new EntityWrapper<Order>() + .eq("id",id) + .eq("userId",appUser.getId())); switch (payType){ case 1: switch (buyType){ case 1: + return payMoneyUtil.weixinpay ("购买课程下单支付", "", id + "_" +buyType+"_"+ @@ -378,6 +717,7 @@ orderCourse.getRealMoney().toString(), "/base/wxPayBuyCourse", "APP", ""); case 2: + return payMoneyUtil.weixinpay ("购买套餐下单支付", "", id + "_" +buyType+"_"+ @@ -385,6 +725,7 @@ order.getRealMoney().toString(), "/base/wxPayBuyPackage", "APP", ""); case 3: + return payMoneyUtil.weixinpay ("充值余额下单支付", "", id + "_" +buyType+"_"+ @@ -494,7 +835,7 @@ AppUser appUser1 = appUserService.selectById(appUserService.selectById(appUser.getInviteUserId()).getInviteUserId()); BigDecimal balance1 = appUser1.getBalance(); BigDecimal add = balance1.add(bigDecimal1); - appUser1.setBalance(add); +// appUser1.setBalance(add); appUserService.updateById(appUser1); } } @@ -565,7 +906,7 @@ AppUser appUser1 = appUserService.selectById(appUserService.selectById(appUser.getInviteUserId()).getInviteUserId()); BigDecimal balance5 = appUser1.getBalance(); BigDecimal add = balance5.add(bigDecimal3); - appUser1.setBalance(add); +// appUser1.setBalance(add); appUserService.updateById(appUser1); } } @@ -578,57 +919,39 @@ // 苹果支付 全部用余额来购买 如果余额不足 提示购买余额 case 1: // 购买课程 - BigDecimal realMoney = orderCourse.getRealMoney(); - if (appUser.getBalance().compareTo(realMoney)<0) { - return ResultUtil.error("余额不足"); + Boolean success = IosPalUtils.isSuccess(transactionReceipt); + if (success){ + // 购买成功 将支付状态修改为已支付 + orderCourse.setState(2); + orderCourse.setPayTime(new Date()); + orderCourse.setPayType(4); + orderCourseService.updateById(orderCourse); } break; case 2: - BigDecimal realMoney1 = order.getRealMoney(); - if (appUser.getBalance().compareTo(realMoney1)<0) { - return ResultUtil.error("余额不足"); + // 购买课程 + Boolean success1 = IosPalUtils.isSuccess(transactionReceipt); + if (success1){ + // 购买成功 将支付状态修改为已支付 + order.setState(2); + order.setPayTime(new Date()); + order.setPayType(4); + orderService.updateById(order); } break; + // todo 2.0ios取消余额 case 3: - recharge1.setState(2); - recharge1.setPayType(3); - rechargeService.updateById(recharge1); - BigDecimal amount = recharge1.getAmount(); - BigDecimal add = appUser.getBalance().add(amount); - appUser.setBalance(add); - appUserService.updateById(appUser); - break; + Boolean success3 = IosPalUtils.isSuccess(transactionReceipt); +// if (success3){ +// recharge1.setState(2); +// rechargeService.updateById(recharge1); +// BigDecimal amount = recharge1.getAmount(); +// BigDecimal add = appUser.getBalance().add(amount); +// appUser.setBalance(add); +// appUserService.updateById(appUser); +// break; +// } } -// if (StringUtils.hasLength(transactionReceipt)){ -// // 调用苹果 查询支付结果 -// String verifyResult = IosVerifyUtil.buyAppVerify(transactionReceipt, 0); -// if (verifyResult == null) { -// return ResultUtil.error("苹果验证失败,返回数据为空"); -// }else{ -// JSONObject appleReturn = JSONObject.parseObject(verifyResult); -// String states = appleReturn.getString("status"); -// //无数据则沙箱环境验证 -// if ("21007".equals(states)) { -// verifyResult = IosVerifyUtil.buyAppVerify(transactionReceipt, 0); -// System.err.println("沙盒环境,苹果平台返回JSON:" + verifyResult);; -// appleReturn = JSONObject.parseObject(verifyResult); -// states = appleReturn.getString("status"); -// } -// if (states.equals("0")) { -// String receipt1 = appleReturn.getString("receipt"); -// JSONObject returnJson = JSONObject.parseObject(receipt1); -// String inApp = returnJson.getString("in_app"); -// List<HashMap> inApps = JSONObject.parseArray(inApp, HashMap.class); -// if (inApps!=null) { -// // 判断交易列表有没有包含当前订单 -// } -// return ResultUtil.error("未能获取获取到交易列表"); -// } else { -// return ResultUtil.error("支付失败,错误码:" + states); -// } -// } -// } - break; } return ResultUtil.success(); @@ -718,7 +1041,7 @@ AppUser appUser1 = appUserService.selectById(appUserService.selectById(appUser.getInviteUserId()).getInviteUserId()); BigDecimal balance1 = appUser1.getBalance(); BigDecimal add = balance1.add(bigDecimal1); - appUser1.setBalance(add); +// appUser1.setBalance(add); appUserService.updateById(appUser1); } } @@ -814,7 +1137,7 @@ AppUser appUser1 = appUserService.selectById(appUserService.selectById(appUser.getInviteUserId()).getInviteUserId()); BigDecimal balance1 = appUser1.getBalance(); BigDecimal add = balance1.add(bigDecimal1); - appUser1.setBalance(add); +// appUser1.setBalance(add); appUserService.updateById(appUser1); } } @@ -878,6 +1201,10 @@ @ApiImplicitParam(value = "订单id", name = "orderId", dataType = "int", required = true), }) public ResultUtil<CouponVO> success(Integer orderId) { + AppUser appUser = appUserService.getAppUser(); + if (appUser == null){ + return ResultUtil.tokenErr("登录失效"); + } CouponVO couponVO = new CouponVO(); // 查询后台有没有配置首次下单赠送奖品 SysSet sysSet = sysSetService.selectById(1); @@ -1099,6 +1426,10 @@ @ApiImplicitParam(value = "课程id", name = "courseId", dataType = "int", required = true) }) public ResultUtil<BuyDetailVO> buyCourse(Integer courseId) { + AppUser appUser = appUserService.getAppUser(); + if (appUser == null){ + return ResultUtil.tokenErr("登录失效"); + } BuyDetailVO buyDetailVO = new BuyDetailVO(); buyDetailVO.setId(courseId); // 查询课程 @@ -1108,8 +1439,29 @@ FitnessPosition fitnessPosition = fitnessPositionService.selectById(positionId); FitnessType fitnessType = fitnessTypeService.selectById(fitnessPosition.getTypeId()); if (fitnessPosition!=null && fitnessType!=null){ - typeName.append(fitnessType.getName()+"|"+fitnessPosition.getName()); - buyDetailVO.setAmount(fitnessPosition.getAmount()); + typeName.append(fitnessType.getName()+"|"+fitnessPosition.getName()+"|H"+course.getDifficulty()); + switch (course.getDifficulty()){ + case 1: + buyDetailVO.setAmount(fitnessPosition.getAmount()); + buyDetailVO.setAppleAmount(fitnessPosition.getAppleAmount()); + break; + case 2: + buyDetailVO.setAmount(fitnessPosition.getAmount2()); + buyDetailVO.setAppleAmount(fitnessPosition.getAppleAmount2()); + break; + case 3: + buyDetailVO.setAmount(fitnessPosition.getAmount3()); + buyDetailVO.setAppleAmount(fitnessPosition.getAppleAmount3()); + break; + case 4: + buyDetailVO.setAmount(fitnessPosition.getAmount4()); + buyDetailVO.setAppleAmount(fitnessPosition.getAppleAmount4()); + break; + case 5: + buyDetailVO.setAmount(fitnessPosition.getAmount5()); + buyDetailVO.setAppleAmount(fitnessPosition.getAppleAmount5()); + break; + } } buyDetailVO.setTypeName(typeName.toString()); int size = courseService.selectList(new EntityWrapper<Course>() @@ -1119,7 +1471,7 @@ // 查询和这个课程同类型同部位的课程数量 buyDetailVO.setCount(size); // 查询可选套餐列表 查询包含当前购买部位的课程的套餐 - List<PackageListVO> packageListVOS = new ArrayList<PackageListVO>(); + List<PackageListVO> packageListVOS = new ArrayList<>(); List<Package> packages = packageService.selectList(new EntityWrapper<Package>() .eq("state", 1)); for (Package aPackage : packages) { @@ -1131,8 +1483,10 @@ packageListVO.setPackageName(aPackage.getName()); if (aPackage.getAmount()!=null){ packageListVO.setAmount(aPackage.getAmount()); + packageListVO.setAppleAmount(aPackage.getAppleAmount()); }else{ packageListVO.setAmount(aPackage.getTotal()); + packageListVO.setAmount(new BigDecimal(0)); } packageListVO.setPrice(aPackage.getPrice()); packageListVO.setIds(aPackage.getPositions()); @@ -1151,11 +1505,12 @@ FitnessPosition fitnessPosition1 = fitnessPositionService.selectById(Integer.valueOf(s)); FitnessType fitnessType1 = fitnessTypeService.selectById(fitnessPosition1.getTypeId()); if (fitnessPosition1!=null && fitnessType1!=null){ - temp.append(fitnessType1.getName()+"|"+fitnessPosition1.getName()); + temp.append(fitnessType1.getName()+"|"+fitnessPosition1.getName()+"|H"+course.getDifficulty()); } courseVO.setTypeName(temp.toString()); List<Course> courses = courseService.selectList(new EntityWrapper<Course>() .eq("state", 1) + .eq("difficulty", course.getDifficulty()) .eq("positionId", Integer.valueOf(s))); // Integer tem = 0; // for (Course cours : courses) { @@ -1171,7 +1526,6 @@ } buyDetailVO.setPackageListVOList(packageListVOS); // 查询可以使用的优惠券列表 - AppUser appUser = appUserService.getAppUser(); List<CouponReceive> couponReceives = couponReceiveService.selectList (new EntityWrapper<CouponReceive>() .eq("userId", appUser.getId()) @@ -1247,6 +1601,10 @@ @ApiImplicitParam(name = "Authorization", value = "Bearer eyJhbGciOiJIUzUxMiJ....", required = true, paramType = "header"), }) public ResultUtil<StartVO> riskInfo() { + AppUser appUser = appUserService.getAppUser(); + if (appUser == null){ + return ResultUtil.tokenErr("登录失效"); + } String riskInfo = sysSetService.selectById(1).getRiskInfo(); StartVO startVO = new StartVO(); startVO.setRiskInfo(riskInfo); @@ -1269,6 +1627,10 @@ @ApiImplicitParam(name = "courseId", value = "课程id", required = true) }) public ResultUtil<StartTrainVO> startTrain(Integer courseId) { + AppUser appUser = appUserService.getAppUser(); + if (appUser == null){ + return ResultUtil.tokenErr("登录失效"); + } StartTrainVO startTrainVO = new StartTrainVO(); // 根据课程id和用户id 查询用户上次播放位置 Integer id = appUserService.getAppUser().getId(); @@ -1286,6 +1648,11 @@ List<CourseVideo> courseVideos = courseVideoService.selectList(new EntityWrapper<CourseVideo>() .eq("courseId", courseId) .eq("isDelete", 0)); + for (CourseVideo courseVideo : courseVideos) { + String courseVideo1 = courseVideo.getCourseVideo(); + String replace = courseVideo1.replace("https://jkjianshen.obs.cn-north-4.myhuaweicloud.com/", "http://cdn.jkcyl.cn/"); + courseVideo.setCourseVideo(replace); + } int totalTime = courseVideos.stream() .mapToInt(CourseVideo::getTime) .sum(); @@ -1297,7 +1664,10 @@ startTrainVO.setBeforeTime(0); startTrainVO.setBeforeVideoId(courseVideos.get(0).getId()); startTrainVO.setRealTime(0); - startTrainVO.setCourseVideo(courseVideos.get(0).getCourseVideo()); + // 手动替换为cdn域名 + String courseVideo = courseVideos.get(0).getCourseVideo(); + String replace = courseVideo.replace("https://jkjianshen.obs.cn-north-4.myhuaweicloud.com/", "http://cdn.jkcyl.cn/"); + startTrainVO.setCourseVideo(replace); startTrainVO.setVideoName(courseVideos.get(0).getVideoName()); startTrainVO.setVideos(courseVideos); startTrainVO.setPosition("1/"+courseVideos.size()); @@ -1309,7 +1679,8 @@ CourseVideo courseVideo = courseVideoService.selectById(beforeVideoId); if (courseVideo!=null){ startTrainVO.setTime(courseVideo.getTime()); - startTrainVO.setCourseVideo(courseVideo.getCourseVideo()); + String replace = courseVideo.getCourseVideo().replace("https://jkjianshen.obs.cn-north-4.myhuaweicloud.com/", "http://cdn.jkcyl.cn/"); + startTrainVO.setCourseVideo(replace); startTrainVO.setVideoName(courseVideo.getVideoName()); startTrainVO.setBeforeTime(beforeTime); startTrainVO.setBeforeVideoId(beforeVideoId); @@ -1317,7 +1688,8 @@ }else{ // 如果为空 那么定位到课程下的第一条视频的0秒处 startTrainVO.setTime(courseVideos.get(0).getTime()); - startTrainVO.setCourseVideo(courseVideos.get(0).getCourseVideo()); + String replace = courseVideos.get(0).getCourseVideo().replace("https://jkjianshen.obs.cn-north-4.myhuaweicloud.com/", "http://cdn.jkcyl.cn/"); + startTrainVO.setCourseVideo(replace); startTrainVO.setVideoName(courseVideos.get(0).getVideoName()); startTrainVO.setBeforeTime(0); startTrainVO.setBeforeVideoId(courseVideos.get(0).getId()); @@ -1343,6 +1715,10 @@ @ApiImplicitParam(name = "Authorization", value = "Bearer eyJhbGciOiJIUzUxMiJ....", required = true, paramType = "header"), }) public ResultUtil exit(AddUserWatchDTO dto) { + AppUser appUser = appUserService.getAppUser(); + if (appUser == null){ + return ResultUtil.tokenErr("登录失效"); + } Integer id = appUserService.getAppUser().getId(); Integer courseId = dto.getCourseId(); UserWatch userWatches = userWatchService.selectOne(new EntityWrapper<UserWatch>() @@ -1377,6 +1753,10 @@ @ApiImplicitParam(name = "courseId", value = "课程id", required = true) }) public ResultUtil<CompeleteVO> clockIn(Integer courseId) { + AppUser appUser = appUserService.getAppUser(); + if (appUser == null){ + return ResultUtil.tokenErr("登录失效"); + } Integer isFree = courseService.selectById(courseId).getIsFree(); CompeleteVO compeleteVO = new CompeleteVO(); Integer id = appUserService.getAppUser().getId(); @@ -1385,7 +1765,6 @@ .eq("userId", id)); userWatches.setClockTime(new Date()); userWatchService.updateById(userWatches); - AppUser appUser = appUserService.getAppUser(); // 查询优惠券列表是否有打卡赠送 且未过期的优惠券 List<Coupon> coupons = couponService.selectList(new EntityWrapper<Coupon>() .eq("grantType", 1) @@ -1634,6 +2013,10 @@ @ApiImplicitParam(name = "courseId", value = "课程id", required = true) }) public ResultUtil<CompeleteVO> completeInfo(Integer courseId) { + AppUser appUser = appUserService.getAppUser(); + if (appUser == null){ + return ResultUtil.tokenErr("登录失效"); + } Date compeleteTime = appUserService.getAppUser().getCompeleteTime(); if (compeleteTime!=null){ Date date = new Date(); @@ -1641,13 +2024,11 @@ if (format.format(date).equals(format.format(compeleteTime))) { // 同一天那么不计算坚持运动天数 }else{ - AppUser appUser = appUserService.getAppUser(); appUser.setCompeleteTime(new Date()); appUser.setTime(appUser.getTime()+1); appUserService.updateById(appUser); } }else{ - AppUser appUser = appUserService.getAppUser(); appUser.setTime(appUser.getTime()+1); appUser.setCompeleteTime(new Date()); appUserService.updateById(appUser); @@ -1657,9 +2038,28 @@ .eq("courseId", courseId) .eq("userId", id)); if (userWatches!=null){ - // 打卡后 将观看记录初始化 + // 将观看记录初始化 userWatches.setBeforeTime(0); userWatches.setRealTime(0); + // 获取上次播放到的视频id +// Integer beforeVideoId = userWatches.getBeforeVideoId(); + List<CourseVideo> courseVideos = courseVideoService.selectList(new EntityWrapper<CourseVideo>() + .eq("courseId", courseId) + .eq("isDelete", 0)); +// int index = 0; +// for (CourseVideo courseVideo : courseVideos) { +// if (courseVideo.getId().equals(beforeVideoId)){ +// // 如果courseVieo不是最后一条数据 那么将courseVieo的下一条数据设置为beforeVideoId +// if (index<courseVideos.size()-1){ +// userWatches.setBeforeVideoId(courseVideos.get(index+1).getId()); +// }else{ +// // 如果courseVieo是最后一条数据 那么设置为从第一节开始播放 +// userWatches.setBeforeVideoId(courseVideos.get(0).getId()); +// } +// } +// index++; +// } + userWatches.setBeforeVideoId(courseVideos.get(0).getId()); userWatchService.updateById(userWatches); }else{ UserWatch userWatch = new UserWatch(); @@ -1674,7 +2074,7 @@ userWatch.setRealTime(0); userWatchService.insert(userWatch); } - AppUser appUser = appUserService.getAppUser(); + // 返回页面内容 Course course = courseService.selectById(courseId); CompeleteVO compeleteVO = new CompeleteVO(); @@ -1697,6 +2097,10 @@ @ApiImplicitParam(value = "课程id", name = "courseId", dataType = "int", required = true) }) public ResultUtil collectCourse(Integer courseId) { + AppUser appUser = appUserService.getAppUser(); + if (appUser == null){ + return ResultUtil.tokenErr("登录失效"); + } Integer id = appUserService.getAppUser().getId(); // 先判断用户是否收藏了该课程 UserCollect userCollect1 = collectService.selectOne(new EntityWrapper<UserCollect>() @@ -1724,6 +2128,12 @@ @ApiImplicitParam(value = "课程id", name = "courseId", dataType = "int", required = true) }) public ResultUtil<CourseDetailVO> courseDetail(Integer courseId) { + AppUser appUser = appUserService.getAppUser(); + if (appUser == null){ + return ResultUtil.tokenErr("登录失效"); + } + // 推荐课程3个 相同类型 相同难度 按sort排序 + Course course = courseService.selectById(courseId); Integer userId = appUserService.getAppUser().getId(); CourseDetailVO res = new CourseDetailVO(); List<Integer> list = new ArrayList<>(); @@ -1761,7 +2171,8 @@ if (res.getIsBuy()!=1){ for (Order aPackage : packages) { Integer packageId = aPackage.getPackageId(); - String positions = packageService.selectById(packageId).getPositions(); + Package aPackage1 = packageService.selectById(packageId); + String positions = aPackage1.getPositions(); if (StringUtils.hasLength(positions)){ String[] split = positions.split(","); // 通过部位ids 获取到课程ids @@ -1770,19 +2181,26 @@ .collect(Collectors.toList()); if (positionId.contains(courseId)){ res.setIsBuy(1); - break; + // todo 新增需求 套餐设置指定难度 需要再判断一次难度 +// Integer difficulty = course.getDifficulty(); +// if (difficulty.equals(aPackage1.getDifficulty())){ +// break; +// } } } } } + // 推荐课程3个 相同类型 相同难度 按sort排序 if (res.getIsBuy() != 1){ // 先查询出和这个课程同类型同部位 Course course1 = courseService.selectById(courseId); - // 相同的课程id + // 相同的课程id 部位和难度相同 List<Integer> positionId = courseService.selectList(new EntityWrapper<Course>() - .eq("positionId", course1.getPositionId())).stream().map(Course::getId).collect(Collectors.toList()); + .eq("positionId", course1.getPositionId()) + .eq("difficulty",course1.getDifficulty()) + ).stream().map(Course::getId).collect(Collectors.toList()); - // 查询下用户有没有购买其他相同部位和类型的课程 如果有 那么就算已购买 + // 查询下用户有没有购买其他相同部位和类型和难度的课程 如果有 那么就算已购买 // 查询用户已购买的课程 List<OrderCourse> orderCourses = orderCourseService.selectList(new EntityWrapper<OrderCourse>() .eq("userId", appUserService.getAppUser().getId()) @@ -1794,8 +2212,7 @@ } - // 推荐课程3个 相同类型 相同难度 按sort排序 - Course course = courseService.selectById(courseId); + Integer difficulty = course.getDifficulty(); Integer typeId = course.getTypeId(); List<String> strings = new ArrayList<>(); @@ -1814,6 +2231,10 @@ List<CourseVideo> courseVideos = courseVideoService.selectList(new EntityWrapper<CourseVideo>() .eq("courseId", courseId) .eq("isDelete", 0)); + for (CourseVideo courseVideo : courseVideos) { + String replace = courseVideo.getCourseVideo().replace("https://jkjianshen.obs.cn-north-4.myhuaweicloud.com/", "http://cdn.jkcyl.cn/"); + courseVideo.setCourseVideo(replace); + } res.setVideos(courseVideos); return ResultUtil.success(res); @@ -1828,6 +2249,10 @@ }) public ResultUtil<List<CourseList>> myCourse(CourseQuery req) { AppUser appUser = appUserService.getAppUser(); + if (appUser == null){ + return ResultUtil.tokenErr("登录失效"); + } + req.setUserId(appUser.getId()); if (StringUtils.hasLength(req.getTime())){ for (String s : req.getTime().split(",")) { @@ -1888,12 +2313,18 @@ List<Integer> list = new ArrayList<>(); // 根据套餐ids 查询课程ids for (Integer integer : collect) { - String positions = packageService.selectById(integer).getPositions(); + Package aPackage = packageService.selectById(integer); + String positions = aPackage.getPositions(); + String difficulty = aPackage.getDifficulty(); if (StringUtils.hasLength(positions)){ String[] split = positions.split(","); + // 难度ids + String[] split1 = difficulty.split(","); // 通过部位ids 获取到课程ids List<Integer> positionId = courseService.selectList(new EntityWrapper<Course>() - .in("positionId", split)).stream().map(Course::getId) + .in("positionId", split) + .in("difficulty", split1) + ).stream().map(Course::getId) .collect(Collectors.toList()); list.addAll(positionId); } @@ -1918,7 +2349,9 @@ // 和当前课程同类型同部位的课程 List<Integer> collect1 = courseService.selectList(new EntityWrapper<Course>() .eq("state", 1) - .eq("positionId", positionId)).stream().map(Course::getId).collect(Collectors.toList()); + .eq("positionId", positionId) + .eq("difficulty", course.getDifficulty()) + ).stream().map(Course::getId).collect(Collectors.toList()); if (collect1.size()>0){ list1.addAll(collect1); } @@ -1981,6 +2414,10 @@ @ApiImplicitParam(name = "Authorization", value = "Bearer eyJhbGciOiJIUzUxMiJ....", required = true, paramType = "header") }) public ResultUtil<List<CourseList>> courseSearch(CourseQuery req) { + AppUser appUser = appUserService.getAppUser(); + if (appUser == null){ + return ResultUtil.tokenErr("登录失效"); + } req.setPageNum((req.getPageNum() - 1) * req.getPageSize()); if (StringUtils.hasLength(req.getTime())){ for (String s : req.getTime().split(",")) { @@ -2044,6 +2481,10 @@ @ApiImplicitParam(name = "Authorization", value = "Bearer eyJhbGciOiJIUzUxMiJ....", required = true, paramType = "header") }) public ResultUtil<List<Banner>> getBanner() { + AppUser appUser = appUserService.getAppUser(); + if (appUser == null){ + return ResultUtil.tokenErr("登录失效"); + } List<String> strings = new ArrayList<>(); strings.add("sort"); List<Banner> state = bannerService.selectList(new EntityWrapper<Banner>() @@ -2059,6 +2500,9 @@ }) public ResultUtil<SearchList> getList() { AppUser appUser = appUserService.getAppUser(); + if (appUser == null){ + return ResultUtil.tokenErr("登录失效"); + } // 查询用户有哪些课程购买了的 List<OrderCourse> orderCourses = orderCourseService.selectList(new EntityWrapper<OrderCourse>() @@ -2080,17 +2524,29 @@ for (Order order1 : order) { for (String s : packageService.selectById(order1.getPackageId()) .getPositions().split(",")) { - List<Integer> positionId = courseService.selectList(new EntityWrapper<Course>() - .eq("positionId", s)).stream().map(Course::getId) + List<Integer> cId = courseService.selectList(new EntityWrapper<Course>() + .eq("positionId", s) + .eq("state",1)).stream().map(Course::getId) .collect(Collectors.toList()); - packages.addAll(positionId); + packages.addAll(cId); } } packages = packages.stream().distinct().collect(Collectors.toList()); } - course.addAll(packages); + if (packages.size()==0){ + packages.add(-1); + } + List<Integer> collect5 = courseService.selectList(new EntityWrapper<Course>() + .eq("state", 1) + .in("id", packages)).stream().map(Course::getId) + .collect(Collectors.toList()); + course.addAll(collect5); + if (course.isEmpty()){ + course.add(-1); + } // 所有用户的课程ids List<Integer> collect = course.stream().distinct().collect(Collectors.toList()); + // 查询包含的类型和部位 List<Integer> collect1 = courseService.selectList(new EntityWrapper<Course>() .in("id", collect).eq("state", 1)).stream().map(Course::getPositionId) @@ -2099,6 +2555,12 @@ .in("id", collect).eq("state", 1)).stream().map(Course::getTypeId) .collect(Collectors.toList()); List<String> strings = new ArrayList<>(); + for (Integer i : collect1) { + FitnessPosition fitnessPosition = fitnessPositionService.selectById(i); + if (!strings.contains(fitnessPosition.getName())){ + strings.add(fitnessPosition.getName()); + } + } List<FitnessPosition> fitnessPositions = new ArrayList<>(); List<DifficultyVO> d = new ArrayList<>(); List<DifficultyVO> t = new ArrayList<>(); @@ -2123,17 +2585,12 @@ for (FitnessPosition position : positions) { position.setIsUse(0); if (strings.contains(position.getName())){ - continue; + position.setIsUse(1); + fitnessPositions.add(position); }else{ - strings.add(position.getName()); fitnessPositions.add(position); } - for (Integer integer : collect1) { - if (position.getId().equals(integer)){ - position.setIsUse(1); - break; - } - } + } List<FitnessType> types = fitnessTypeService.selectList(new EntityWrapper<FitnessType>() .eq("isDelete", 0)); @@ -2153,7 +2610,7 @@ .eq("state", 1) .in("id", collect)); // 获取所有课程的时间 - List<String> collect4 = courses.stream().map(Course::getTime).distinct().collect(Collectors.toList()); + List<String> collect4 = courses.stream().map(Course::getTime).collect(Collectors.toList()); for (String s : collect4) { Integer integer = Integer.valueOf(s); if (integer>1200){ @@ -2176,7 +2633,7 @@ } } // 获取所有的难度 - List<Integer> collect3 = courses.stream().map(Course::getDifficulty).distinct().collect(Collectors.toList()); + List<Integer> collect3 = courses.stream().map(Course::getDifficulty).collect(Collectors.toList()); if (collect3.contains(1)){ DifficultyVO difficultyVO = new DifficultyVO(); difficultyVO.setIsUse(1); @@ -2245,15 +2702,91 @@ searchList.setDifficulty(d); searchList.setTime(t); - searchList.setFitnessPosition(fitnessPositions); + Map<String, FitnessPosition> resultMap = new HashMap<>(); + + for (FitnessPosition position : fitnessPositions) { + if (resultMap.containsKey(position.getName())) { + FitnessPosition existingPosition = resultMap.get(position.getName()); + if (existingPosition.getIsUse() == 0 && position.getIsUse() == 1) { + existingPosition.setIsUse(1); + } + } else { + resultMap.put(position.getName(), position); + } + } + List<FitnessPosition> resultPositions = new ArrayList<>(resultMap.values()); + searchList.setFitnessPosition(resultPositions); searchList.setFitnessType(types); return ResultUtil.success(searchList); } - public static void main(String[] args) throws Exception { - BigDecimal divisor = new BigDecimal("100"); - BigDecimal res = new BigDecimal("0.8"); - BigDecimal bigDecimal = res.divide(divisor); - System.err.println(bigDecimal); + public static void main(String[] args) { + String t= "{\"signedPayload\":\"eyJhbGciOiJFUzI1NiIsIng1YyI6WyJNSUlFTURDQ0E3YWdBd0lCQWdJUWZUbGZkMGZOdkZXdnpDMVlJQU5zWGpBS0JnZ3Foa2pPUFFRREF6QjFNVVF3UWdZRFZRUURERHRCY0hCc1pTQlhiM0pzWkhkcFpHVWdSR1YyWld4dmNHVnlJRkpsYkdGMGFXOXVjeUJEWlhKMGFXWnBZMkYwYVc5dUlFRjFkR2h2Y21sMGVURUxNQWtHQTFVRUN3d0NSell4RXpBUkJnTlZCQW9NQ2tGd2NHeGxJRWx1WXk0eEN6QUpCZ05WQkFZVEFsVlRNQjRYRFRJek1Ea3hNakU1TlRFMU0xb1hEVEkxTVRBeE1URTVOVEUxTWxvd2daSXhRREErQmdOVkJBTU1OMUJ5YjJRZ1JVTkRJRTFoWXlCQmNIQWdVM1J2Y21VZ1lXNWtJR2xVZFc1bGN5QlRkRzl5WlNCU1pXTmxhWEIwSUZOcFoyNXBibWN4TERBcUJnTlZCQXNNSTBGd2NHeGxJRmR2Y214a2QybGtaU0JFWlhabGJHOXdaWElnVW1Wc1lYUnBiMjV6TVJNd0VRWURWUVFLREFwQmNIQnNaU0JKYm1NdU1Rc3dDUVlEVlFRR0V3SlZVekJaTUJNR0J5cUdTTTQ5QWdFR0NDcUdTTTQ5QXdFSEEwSUFCRUZFWWUvSnFUcXlRdi9kdFhrYXVESENTY1YxMjlGWVJWLzB4aUIyNG5DUWt6UWYzYXNISk9OUjVyMFJBMGFMdko0MzJoeTFTWk1vdXZ5ZnBtMjZqWFNqZ2dJSU1JSUNCREFNQmdOVkhSTUJBZjhFQWpBQU1COEdBMVVkSXdRWU1CYUFGRDh2bENOUjAxREptaWc5N2JCODVjK2xrR0taTUhBR0NDc0dBUVVGQndFQkJHUXdZakF0QmdnckJnRUZCUWN3QW9ZaGFIUjBjRG92TDJObGNuUnpMbUZ3Y0d4bExtTnZiUzkzZDJSeVp6WXVaR1Z5TURFR0NDc0dBUVVGQnpBQmhpVm9kSFJ3T2k4dmIyTnpjQzVoY0hCc1pTNWpiMjB2YjJOemNEQXpMWGQzWkhKbk5qQXlNSUlCSGdZRFZSMGdCSUlCRlRDQ0FSRXdnZ0VOQmdvcWhraUc5Mk5rQlFZQk1JSCtNSUhEQmdnckJnRUZCUWNDQWpDQnRneUJzMUpsYkdsaGJtTmxJRzl1SUhSb2FYTWdZMlZ5ZEdsbWFXTmhkR1VnWW5rZ1lXNTVJSEJoY25SNUlHRnpjM1Z0WlhNZ1lXTmpaWEIwWVc1alpTQnZaaUIwYUdVZ2RHaGxiaUJoY0hCc2FXTmhZbXhsSUhOMFlXNWtZWEprSUhSbGNtMXpJR0Z1WkNCamIyNWthWFJwYjI1eklHOW1JSFZ6WlN3Z1kyVnlkR2xtYVdOaGRHVWdjRzlzYVdONUlHRnVaQ0JqWlhKMGFXWnBZMkYwYVc5dUlIQnlZV04wYVdObElITjBZWFJsYldWdWRITXVNRFlHQ0NzR0FRVUZCd0lCRmlwb2RIUndPaTh2ZDNkM0xtRndjR3hsTG1OdmJTOWpaWEowYVdacFkyRjBaV0YxZEdodmNtbDBlUzh3SFFZRFZSME9CQllFRkFNczhQanM2VmhXR1FsekUyWk9FK0dYNE9vL01BNEdBMVVkRHdFQi93UUVBd0lIZ0RBUUJnb3Foa2lHOTJOa0Jnc0JCQUlGQURBS0JnZ3Foa2pPUFFRREF3Tm9BREJsQWpFQTh5Uk5kc2twNTA2REZkUExnaExMSndBdjVKOGhCR0xhSThERXhkY1BYK2FCS2pqTzhlVW85S3BmcGNOWVVZNVlBakFQWG1NWEVaTCtRMDJhZHJtbXNoTnh6M05uS20rb3VRd1U3dkJUbjBMdmxNN3ZwczJZc2xWVGFtUllMNGFTczVrPSIsIk1JSURGakNDQXB5Z0F3SUJBZ0lVSXNHaFJ3cDBjMm52VTRZU3ljYWZQVGp6Yk5jd0NnWUlLb1pJemowRUF3TXdaekViTUJrR0ExVUVBd3dTUVhCd2JHVWdVbTl2ZENCRFFTQXRJRWN6TVNZd0pBWURWUVFMREIxQmNIQnNaU0JEWlhKMGFXWnBZMkYwYVc5dUlFRjFkR2h2Y21sMGVURVRNQkVHQTFVRUNnd0tRWEJ3YkdVZ1NXNWpMakVMTUFrR0ExVUVCaE1DVlZNd0hoY05NakV3TXpFM01qQXpOekV3V2hjTk16WXdNekU1TURBd01EQXdXakIxTVVRd1FnWURWUVFERER0QmNIQnNaU0JYYjNKc1pIZHBaR1VnUkdWMlpXeHZjR1Z5SUZKbGJHRjBhVzl1Y3lCRFpYSjBhV1pwWTJGMGFXOXVJRUYxZEdodmNtbDBlVEVMTUFrR0ExVUVDd3dDUnpZeEV6QVJCZ05WQkFvTUNrRndjR3hsSUVsdVl5NHhDekFKQmdOVkJBWVRBbFZUTUhZd0VBWUhLb1pJemowQ0FRWUZLNEVFQUNJRFlnQUVic1FLQzk0UHJsV21aWG5YZ3R4emRWSkw4VDBTR1luZ0RSR3BuZ24zTjZQVDhKTUViN0ZEaTRiQm1QaENuWjMvc3E2UEYvY0djS1hXc0w1dk90ZVJoeUo0NXgzQVNQN2NPQithYW85MGZjcHhTdi9FWkZibmlBYk5nWkdoSWhwSW80SDZNSUgzTUJJR0ExVWRFd0VCL3dRSU1BWUJBZjhDQVFBd0h3WURWUjBqQkJnd0ZvQVV1N0Rlb1ZnemlKcWtpcG5ldnIzcnI5ckxKS3N3UmdZSUt3WUJCUVVIQVFFRU9qQTRNRFlHQ0NzR0FRVUZCekFCaGlwb2RIUndPaTh2YjJOemNDNWhjSEJzWlM1amIyMHZiMk56Y0RBekxXRndjR3hsY205dmRHTmhaek13TndZRFZSMGZCREF3TGpBc29DcWdLSVltYUhSMGNEb3ZMMk55YkM1aGNIQnNaUzVqYjIwdllYQndiR1Z5YjI5MFkyRm5NeTVqY213d0hRWURWUjBPQkJZRUZEOHZsQ05SMDFESm1pZzk3YkI4NWMrbGtHS1pNQTRHQTFVZER3RUIvd1FFQXdJQkJqQVFCZ29xaGtpRzkyTmtCZ0lCQkFJRkFEQUtCZ2dxaGtqT1BRUURBd05vQURCbEFqQkFYaFNxNUl5S29nTUNQdHc0OTBCYUI2NzdDYUVHSlh1ZlFCL0VxWkdkNkNTamlDdE9udU1UYlhWWG14eGN4ZmtDTVFEVFNQeGFyWlh2TnJreFUzVGtVTUkzM3l6dkZWVlJUNHd4V0pDOTk0T3NkY1o0K1JHTnNZRHlSNWdtZHIwbkRHZz0iLCJNSUlDUXpDQ0FjbWdBd0lCQWdJSUxjWDhpTkxGUzVVd0NnWUlLb1pJemowRUF3TXdaekViTUJrR0ExVUVBd3dTUVhCd2JHVWdVbTl2ZENCRFFTQXRJRWN6TVNZd0pBWURWUVFMREIxQmNIQnNaU0JEWlhKMGFXWnBZMkYwYVc5dUlFRjFkR2h2Y21sMGVURVRNQkVHQTFVRUNnd0tRWEJ3YkdVZ1NXNWpMakVMTUFrR0ExVUVCaE1DVlZNd0hoY05NVFF3TkRNd01UZ3hPVEEyV2hjTk16a3dORE13TVRneE9UQTJXakJuTVJzd0dRWURWUVFEREJKQmNIQnNaU0JTYjI5MElFTkJJQzBnUnpNeEpqQWtCZ05WQkFzTUhVRndjR3hsSUVObGNuUnBabWxqWVhScGIyNGdRWFYwYUc5eWFYUjVNUk13RVFZRFZRUUtEQXBCY0hCc1pTQkpibU11TVFzd0NRWURWUVFHRXdKVlV6QjJNQkFHQnlxR1NNNDlBZ0VHQlN1QkJBQWlBMklBQkpqcEx6MUFjcVR0a3lKeWdSTWMzUkNWOGNXalRuSGNGQmJaRHVXbUJTcDNaSHRmVGpqVHV4eEV0WC8xSDdZeVlsM0o2WVJiVHpCUEVWb0EvVmhZREtYMUR5eE5CMGNUZGRxWGw1ZHZNVnp0SzUxN0lEdll1VlRaWHBta09sRUtNYU5DTUVBd0hRWURWUjBPQkJZRUZMdXczcUZZTTRpYXBJcVozcjY5NjYvYXl5U3JNQThHQTFVZEV3RUIvd1FGTUFNQkFmOHdEZ1lEVlIwUEFRSC9CQVFEQWdFR01Bb0dDQ3FHU000OUJBTURBMmdBTUdVQ01RQ0Q2Y0hFRmw0YVhUUVkyZTN2OUd3T0FFWkx1Tit5UmhIRkQvM21lb3locG12T3dnUFVuUFdUeG5TNGF0K3FJeFVDTUcxbWloREsxQTNVVDgyTlF6NjBpbU9sTTI3amJkb1h0MlFmeUZNbStZaGlkRGtMRjF2TFVhZ002QmdENTZLeUtBPT0iXX0.eyJub3RpZmljYXRpb25UeXBlIjoiT05FX1RJTUVfQ0hBUkdFIiwibm90aWZpY2F0aW9uVVVJRCI6IjhmMzFkZjhiLWJiNzMtNDY0NC05ODY3LWYwMzYzZWFiMjRkZSIsImRhdGEiOnsiYXBwQXBwbGVJZCI6NjQ5OTEyMzYyNywiYnVuZGxlSWQiOiJjb20uc2luYXRhLkpLRml0bmVzcyIsImJ1bmRsZVZlcnNpb24iOiIxMyIsImVudmlyb25tZW50IjoiU2FuZGJveCIsInNpZ25lZFRyYW5zYWN0aW9uSW5mbyI6ImV5SmhiR2NpT2lKRlV6STFOaUlzSW5nMVl5STZXeUpOU1VsRlRVUkRRMEUzWVdkQmQwbENRV2RKVVdaVWJHWmtNR1pPZGtaWGRucERNVmxKUVU1eldHcEJTMEpuWjNGb2EycFBVRkZSUkVGNlFqRk5WVkYzVVdkWlJGWlJVVVJFUkhSQ1kwaENjMXBUUWxoaU0wcHpXa2hrY0ZwSFZXZFNSMVl5V2xkNGRtTkhWbmxKUmtwc1lrZEdNR0ZYT1hWamVVSkVXbGhLTUdGWFduQlpNa1l3WVZjNWRVbEZSakZrUjJoMlkyMXNNR1ZVUlV4TlFXdEhRVEZWUlVOM2QwTlNlbGw0UlhwQlVrSm5UbFpDUVc5TlEydEdkMk5IZUd4SlJXeDFXWGswZUVONlFVcENaMDVXUWtGWlZFRnNWbFJOUWpSWVJGUkplazFFYTNoTmFrVTFUbFJGTVUweGIxaEVWRWt4VFZSQmVFMVVSVFZPVkVVeFRXeHZkMmRhU1hoUlJFRXJRbWRPVmtKQlRVMU9NVUo1WWpKUloxSlZUa1JKUlRGb1dYbENRbU5JUVdkVk0xSjJZMjFWWjFsWE5XdEpSMnhWWkZjMWJHTjVRbFJrUnpsNVdsTkNVMXBYVG14aFdFSXdTVVpPY0ZveU5YQmliV040VEVSQmNVSm5UbFpDUVhOTlNUQkdkMk5IZUd4SlJtUjJZMjE0YTJReWJHdGFVMEpGV2xoYWJHSkhPWGRhV0VsblZXMVdjMWxZVW5CaU1qVjZUVkpOZDBWUldVUldVVkZMUkVGd1FtTklRbk5hVTBKS1ltMU5kVTFSYzNkRFVWbEVWbEZSUjBWM1NsWlZla0phVFVKTlIwSjVjVWRUVFRRNVFXZEZSME5EY1VkVFRUUTVRWGRGU0VFd1NVRkNSVVpGV1dVdlNuRlVjWGxSZGk5a2RGaHJZWFZFU0VOVFkxWXhNamxHV1ZKV0x6QjRhVUl5Tkc1RFVXdDZVV1l6WVhOSVNrOU9ValZ5TUZKQk1HRk1ka28wTXpKb2VURlRXazF2ZFhaNVpuQnRNalpxV0ZOcVoyZEpTVTFKU1VOQ1JFRk5RbWRPVmtoU1RVSkJaamhGUVdwQlFVMUNPRWRCTVZWa1NYZFJXVTFDWVVGR1JEaDJiRU5PVWpBeFJFcHRhV2M1TjJKQ09EVmpLMnhyUjB0YVRVaEJSME5EYzBkQlVWVkdRbmRGUWtKSFVYZFpha0YwUW1kbmNrSm5SVVpDVVdOM1FXOVphR0ZJVWpCalJHOTJUREpPYkdOdVVucE1iVVozWTBkNGJFeHRUblppVXprelpESlNlVnA2V1hWYVIxWjVUVVJGUjBORGMwZEJVVlZHUW5wQlFtaHBWbTlrU0ZKM1QyazRkbUl5VG5walF6Vm9ZMGhDYzFwVE5XcGlNakIyWWpKT2VtTkVRWHBNV0dReldraEtiazVxUVhsTlNVbENTR2RaUkZaU01HZENTVWxDUmxSRFEwRlNSWGRuWjBWT1FtZHZjV2hyYVVjNU1rNXJRbEZaUWsxSlNDdE5TVWhFUW1kbmNrSm5SVVpDVVdORFFXcERRblJuZVVKek1VcHNZa2RzYUdKdFRteEpSemwxU1VoU2IyRllUV2RaTWxaNVpFZHNiV0ZYVG1oa1IxVm5XVzVyWjFsWE5UVkpTRUpvWTI1U05VbEhSbnBqTTFaMFdsaE5aMWxYVG1wYVdFSXdXVmMxYWxwVFFuWmFhVUl3WVVkVloyUkhhR3hpYVVKb1kwaENjMkZYVG1oWmJYaHNTVWhPTUZsWE5XdFpXRXByU1VoU2JHTnRNWHBKUjBaMVdrTkNhbUl5Tld0aFdGSndZakkxZWtsSE9XMUpTRlo2V2xOM1oxa3lWbmxrUjJ4dFlWZE9hR1JIVldkalJ6bHpZVmRPTlVsSFJuVmFRMEpxV2xoS01HRlhXbkJaTWtZd1lWYzVkVWxJUW5sWlYwNHdZVmRPYkVsSVRqQlpXRkpzWWxkV2RXUklUWFZOUkZsSFEwTnpSMEZSVlVaQ2QwbENSbWx3YjJSSVVuZFBhVGgyWkROa00weHRSbmRqUjNoc1RHMU9kbUpUT1dwYVdFb3dZVmRhY0ZreVJqQmFWMFl4WkVkb2RtTnRiREJsVXpoM1NGRlpSRlpTTUU5Q1FsbEZSa0ZOY3poUWFuTTJWbWhYUjFGc2VrVXlXazlGSzBkWU5FOXZMMDFCTkVkQk1WVmtSSGRGUWk5M1VVVkJkMGxJWjBSQlVVSm5iM0ZvYTJsSE9USk9hMEpuYzBKQ1FVbEdRVVJCUzBKblozRm9hMnBQVUZGUlJFRjNUbTlCUkVKc1FXcEZRVGg1VWs1a2MydHdOVEEyUkVaa1VFeG5hRXhNU25kQmRqVktPR2hDUjB4aFNUaEVSWGhrWTFCWUsyRkNTMnBxVHpobFZXODVTM0JtY0dOT1dWVlpOVmxCYWtGUVdHMU5XRVZhVEN0Uk1ESmhaSEp0YlhOb1RuaDZNMDV1UzIwcmIzVlJkMVUzZGtKVWJqQk1kbXhOTjNad2N6SlpjMnhXVkdGdFVsbE1OR0ZUY3pWclBTSXNJazFKU1VSR2FrTkRRWEI1WjBGM1NVSkJaMGxWU1hOSGFGSjNjREJqTW01MlZUUlpVM2xqWVdaUVZHcDZZazVqZDBObldVbExiMXBKZW1vd1JVRjNUWGRhZWtWaVRVSnJSMEV4VlVWQmQzZFRVVmhDZDJKSFZXZFZiVGwyWkVOQ1JGRlRRWFJKUldONlRWTlpkMHBCV1VSV1VWRk1SRUl4UW1OSVFuTmFVMEpFV2xoS01HRlhXbkJaTWtZd1lWYzVkVWxGUmpGa1IyaDJZMjFzTUdWVVJWUk5Ra1ZIUVRGVlJVTm5kMHRSV0VKM1lrZFZaMU5YTldwTWFrVk1UVUZyUjBFeFZVVkNhRTFEVmxaTmQwaG9ZMDVOYWtWM1RYcEZNMDFxUVhwT2VrVjNWMmhqVGsxNldYZE5la1UxVFVSQmQwMUVRWGRYYWtJeFRWVlJkMUZuV1VSV1VWRkVSRVIwUW1OSVFuTmFVMEpZWWpOS2MxcElaSEJhUjFWblVrZFdNbHBYZUhaalIxWjVTVVpLYkdKSFJqQmhWemwxWTNsQ1JGcFlTakJoVjFwd1dUSkdNR0ZYT1hWSlJVWXhaRWRvZG1OdGJEQmxWRVZNVFVGclIwRXhWVVZEZDNkRFVucFplRVY2UVZKQ1owNVdRa0Z2VFVOclJuZGpSM2hzU1VWc2RWbDVOSGhEZWtGS1FtZE9Wa0pCV1ZSQmJGWlVUVWhaZDBWQldVaExiMXBKZW1vd1EwRlJXVVpMTkVWRlFVTkpSRmxuUVVWaWMxRkxRemswVUhKc1YyMWFXRzVZWjNSNGVtUldTa3c0VkRCVFIxbHVaMFJTUjNCdVoyNHpUalpRVkRoS1RVVmlOMFpFYVRSaVFtMVFhRU51V2pNdmMzRTJVRVl2WTBkalMxaFhjMHcxZGs5MFpWSm9lVW8wTlhnelFWTlFOMk5QUWl0aFlXODVNR1pqY0hoVGRpOUZXa1ppYm1sQllrNW5Xa2RvU1dod1NXODBTRFpOU1VnelRVSkpSMEV4VldSRmQwVkNMM2RSU1UxQldVSkJaamhEUVZGQmQwaDNXVVJXVWpCcVFrSm5kMFp2UVZWMU4wUmxiMVpuZW1sS2NXdHBjRzVsZG5JemNuSTVja3hLUzNOM1VtZFpTVXQzV1VKQ1VWVklRVkZGUlU5cVFUUk5SRmxIUTBOelIwRlJWVVpDZWtGQ2FHbHdiMlJJVW5kUGFUaDJZakpPZW1ORE5XaGpTRUp6V2xNMWFtSXlNSFppTWs1NlkwUkJla3hYUm5kalIzaHNZMjA1ZG1SSFRtaGFlazEzVG5kWlJGWlNNR1pDUkVGM1RHcEJjMjlEY1dkTFNWbHRZVWhTTUdORWIzWk1NazU1WWtNMWFHTklRbk5hVXpWcVlqSXdkbGxZUW5kaVIxWjVZakk1TUZreVJtNU5lVFZxWTIxM2QwaFJXVVJXVWpCUFFrSlpSVVpFT0hac1EwNVNNREZFU20xcFp6azNZa0k0TldNcmJHdEhTMXBOUVRSSFFURlZaRVIzUlVJdmQxRkZRWGRKUWtKcVFWRkNaMjl4YUd0cFJ6a3lUbXRDWjBsQ1FrRkpSa0ZFUVV0Q1oyZHhhR3RxVDFCUlVVUkJkMDV2UVVSQ2JFRnFRa0ZZYUZOeE5VbDVTMjluVFVOUWRIYzBPVEJDWVVJMk56ZERZVVZIU2xoMVpsRkNMMFZ4V2tka05rTlRhbWxEZEU5dWRVMVVZbGhXV0cxNGVHTjRabXREVFZGRVZGTlFlR0Z5V2xoMlRuSnJlRlV6Vkd0VlRVa3pNM2w2ZGtaV1ZsSlVOSGQ0VjBwRE9UazBUM05rWTFvMEsxSkhUbk5aUkhsU05XZHRaSEl3YmtSSFp6MGlMQ0pOU1VsRFVYcERRMEZqYldkQmQwbENRV2RKU1V4aldEaHBUa3hHVXpWVmQwTm5XVWxMYjFwSmVtb3dSVUYzVFhkYWVrVmlUVUpyUjBFeFZVVkJkM2RUVVZoQ2QySkhWV2RWYlRsMlpFTkNSRkZUUVhSSlJXTjZUVk5aZDBwQldVUldVVkZNUkVJeFFtTklRbk5hVTBKRVdsaEtNR0ZYV25CWk1rWXdZVmM1ZFVsRlJqRmtSMmgyWTIxc01HVlVSVlJOUWtWSFFURlZSVU5uZDB0UldFSjNZa2RWWjFOWE5XcE1ha1ZNVFVGclIwRXhWVVZDYUUxRFZsWk5kMGhvWTA1TlZGRjNUa1JOZDAxVVozaFBWRUV5VjJoalRrMTZhM2RPUkUxM1RWUm5lRTlVUVRKWGFrSnVUVkp6ZDBkUldVUldVVkZFUkVKS1FtTklRbk5hVTBKVFlqSTVNRWxGVGtKSlF6Qm5VbnBOZUVwcVFXdENaMDVXUWtGelRVaFZSbmRqUjNoc1NVVk9iR051VW5CYWJXeHFXVmhTY0dJeU5HZFJXRll3WVVjNWVXRllValZOVWsxM1JWRlpSRlpSVVV0RVFYQkNZMGhDYzFwVFFrcGliVTExVFZGemQwTlJXVVJXVVZGSFJYZEtWbFY2UWpKTlFrRkhRbmx4UjFOTk5EbEJaMFZIUWxOMVFrSkJRV2xCTWtsQlFrcHFjRXg2TVVGamNWUjBhM2xLZVdkU1RXTXpVa05XT0dOWGFsUnVTR05HUW1KYVJIVlhiVUpUY0ROYVNIUm1WR3BxVkhWNGVFVjBXQzh4U0RkWmVWbHNNMG8yV1ZKaVZIcENVRVZXYjBFdlZtaFpSRXRZTVVSNWVFNUNNR05VWkdSeFdHdzFaSFpOVm5wMFN6VXhOMGxFZGxsMVZsUmFXSEJ0YTA5c1JVdE5ZVTVEVFVWQmQwaFJXVVJXVWpCUFFrSlpSVVpNZFhjemNVWlpUVFJwWVhCSmNWb3pjalk1TmpZdllYbDVVM0pOUVRoSFFURlZaRVYzUlVJdmQxRkdUVUZOUWtGbU9IZEVaMWxFVmxJd1VFRlJTQzlDUVZGRVFXZEZSMDFCYjBkRFEzRkhVMDAwT1VKQlRVUkJNbWRCVFVkVlEwMVJRMFEyWTBoRlJtdzBZVmhVVVZreVpUTjJPVWQzVDBGRldreDFUaXQ1VW1oSVJrUXZNMjFsYjNsb2NHMTJUM2RuVUZWdVVGZFVlRzVUTkdGMEszRkplRlZEVFVjeGJXbG9SRXN4UVROVlZEZ3lUbEY2TmpCcGJVOXNUVEkzYW1Ka2IxaDBNbEZtZVVaTmJTdFphR2xrUkd0TVJqRjJURlZoWjAwMlFtZEVOVFpMZVV0QlBUMGlYWDAuZXlKMGNtRnVjMkZqZEdsdmJrbGtJam9pTWpBd01EQXdNRFkyTXpRM05qY3lOaUlzSW05eWFXZHBibUZzVkhKaGJuTmhZM1JwYjI1SlpDSTZJakl3TURBd01EQTJOak0wTnpZM01qWWlMQ0ppZFc1a2JHVkpaQ0k2SW1OdmJTNXphVzVoZEdFdVNrdEdhWFJ1WlhOeklpd2ljSEp2WkhWamRFbGtJam9pWTI5dExtcHJabWwwYm1WemN5NWhMbkJ5YVdObExqRWlMQ0p3ZFhKamFHRnpaVVJoZEdVaU9qRTNNakUyTlRBM056SXdNREFzSW05eWFXZHBibUZzVUhWeVkyaGhjMlZFWVhSbElqb3hOekl4TmpVd056Y3lNREF3TENKeGRXRnVkR2wwZVNJNk1Td2lkSGx3WlNJNklrTnZibk4xYldGaWJHVWlMQ0pwYmtGd2NFOTNibVZ5YzJocGNGUjVjR1VpT2lKUVZWSkRTRUZUUlVRaUxDSnphV2R1WldSRVlYUmxJam94TnpJeE5qVXdOemt4TWpRM0xDSmxiblpwY205dWJXVnVkQ0k2SWxOaGJtUmliM2dpTENKMGNtRnVjMkZqZEdsdmJsSmxZWE52YmlJNklsQlZVa05JUVZORklpd2ljM1J2Y21WbWNtOXVkQ0k2SWtOSVRpSXNJbk4wYjNKbFpuSnZiblJKWkNJNklqRTBNelEyTlNJc0luQnlhV05sSWpvNU9EQXdNQ3dpWTNWeWNtVnVZM2tpT2lKRFRsa2lmUS5ES3JibWNYZkNGSDBadlJBNlZXWGkzLWN6cC03WHptTjhIM25PRUs4UnZxUFRXZ3VFYThqWUxhWHU5dHBLc1lQWlNvV0d4NHFXUy1nVXFMVFV1bXNlZyJ9LCJ2ZXJzaW9uIjoiMi4wIiwic2lnbmVkRGF0ZSI6MTcyMTY1MDc5MTI2OX0.imD544tZ0FLw4lPrcpRB279O_SpRab_6z5aUJRoPoe_3CzhT4pwonOmM74PYItQQwpMYwB79SCQaCVVLMsPV1w\"}"; + org.json.JSONObject jsonObject = new org.json.JSONObject(t); + System.err.println(jsonObject.getString("signedPayload")); } +// public static void main(String[] args) throws CertificateException { +// try { +// JSONObject payload = verifyAndGet("eyJhbGciOiJFUzI1NiIsIng1YyI6WyJNSUlFTURDQ0E3YWdBd0lCQWdJUWZUbGZkMGZOdkZXdnpDMVlJQU5zWGpBS0JnZ3Foa2pPUFFRREF6QjFNVVF3UWdZRFZRUURERHRCY0hCc1pTQlhiM0pzWkhkcFpHVWdSR1YyWld4dmNHVnlJRkpsYkdGMGFXOXVjeUJEWlhKMGFXWnBZMkYwYVc5dUlFRjFkR2h2Y21sMGVURUxNQWtHQTFVRUN3d0NSell4RXpBUkJnTlZCQW9NQ2tGd2NHeGxJRWx1WXk0eEN6QUpCZ05WQkFZVEFsVlRNQjRYRFRJek1Ea3hNakU1TlRFMU0xb1hEVEkxTVRBeE1URTVOVEUxTWxvd2daSXhRREErQmdOVkJBTU1OMUJ5YjJRZ1JVTkRJRTFoWXlCQmNIQWdVM1J2Y21VZ1lXNWtJR2xVZFc1bGN5QlRkRzl5WlNCU1pXTmxhWEIwSUZOcFoyNXBibWN4TERBcUJnTlZCQXNNSTBGd2NHeGxJRmR2Y214a2QybGtaU0JFWlhabGJHOXdaWElnVW1Wc1lYUnBiMjV6TVJNd0VRWURWUVFLREFwQmNIQnNaU0JKYm1NdU1Rc3dDUVlEVlFRR0V3SlZVekJaTUJNR0J5cUdTTTQ5QWdFR0NDcUdTTTQ5QXdFSEEwSUFCRUZFWWUvSnFUcXlRdi9kdFhrYXVESENTY1YxMjlGWVJWLzB4aUIyNG5DUWt6UWYzYXNISk9OUjVyMFJBMGFMdko0MzJoeTFTWk1vdXZ5ZnBtMjZqWFNqZ2dJSU1JSUNCREFNQmdOVkhSTUJBZjhFQWpBQU1COEdBMVVkSXdRWU1CYUFGRDh2bENOUjAxREptaWc5N2JCODVjK2xrR0taTUhBR0NDc0dBUVVGQndFQkJHUXdZakF0QmdnckJnRUZCUWN3QW9ZaGFIUjBjRG92TDJObGNuUnpMbUZ3Y0d4bExtTnZiUzkzZDJSeVp6WXVaR1Z5TURFR0NDc0dBUVVGQnpBQmhpVm9kSFJ3T2k4dmIyTnpjQzVoY0hCc1pTNWpiMjB2YjJOemNEQXpMWGQzWkhKbk5qQXlNSUlCSGdZRFZSMGdCSUlCRlRDQ0FSRXdnZ0VOQmdvcWhraUc5Mk5rQlFZQk1JSCtNSUhEQmdnckJnRUZCUWNDQWpDQnRneUJzMUpsYkdsaGJtTmxJRzl1SUhSb2FYTWdZMlZ5ZEdsbWFXTmhkR1VnWW5rZ1lXNTVJSEJoY25SNUlHRnpjM1Z0WlhNZ1lXTmpaWEIwWVc1alpTQnZaaUIwYUdVZ2RHaGxiaUJoY0hCc2FXTmhZbXhsSUhOMFlXNWtZWEprSUhSbGNtMXpJR0Z1WkNCamIyNWthWFJwYjI1eklHOW1JSFZ6WlN3Z1kyVnlkR2xtYVdOaGRHVWdjRzlzYVdONUlHRnVaQ0JqWlhKMGFXWnBZMkYwYVc5dUlIQnlZV04wYVdObElITjBZWFJsYldWdWRITXVNRFlHQ0NzR0FRVUZCd0lCRmlwb2RIUndPaTh2ZDNkM0xtRndjR3hsTG1OdmJTOWpaWEowYVdacFkyRjBaV0YxZEdodmNtbDBlUzh3SFFZRFZSME9CQllFRkFNczhQanM2VmhXR1FsekUyWk9FK0dYNE9vL01BNEdBMVVkRHdFQi93UUVBd0lIZ0RBUUJnb3Foa2lHOTJOa0Jnc0JCQUlGQURBS0JnZ3Foa2pPUFFRREF3Tm9BREJsQWpFQTh5Uk5kc2twNTA2REZkUExnaExMSndBdjVKOGhCR0xhSThERXhkY1BYK2FCS2pqTzhlVW85S3BmcGNOWVVZNVlBakFQWG1NWEVaTCtRMDJhZHJtbXNoTnh6M05uS20rb3VRd1U3dkJUbjBMdmxNN3ZwczJZc2xWVGFtUllMNGFTczVrPSIsIk1JSURGakNDQXB5Z0F3SUJBZ0lVSXNHaFJ3cDBjMm52VTRZU3ljYWZQVGp6Yk5jd0NnWUlLb1pJemowRUF3TXdaekViTUJrR0ExVUVBd3dTUVhCd2JHVWdVbTl2ZENCRFFTQXRJRWN6TVNZd0pBWURWUVFMREIxQmNIQnNaU0JEWlhKMGFXWnBZMkYwYVc5dUlFRjFkR2h2Y21sMGVURVRNQkVHQTFVRUNnd0tRWEJ3YkdVZ1NXNWpMakVMTUFrR0ExVUVCaE1DVlZNd0hoY05NakV3TXpFM01qQXpOekV3V2hjTk16WXdNekU1TURBd01EQXdXakIxTVVRd1FnWURWUVFERER0QmNIQnNaU0JYYjNKc1pIZHBaR1VnUkdWMlpXeHZjR1Z5SUZKbGJHRjBhVzl1Y3lCRFpYSjBhV1pwWTJGMGFXOXVJRUYxZEdodmNtbDBlVEVMTUFrR0ExVUVDd3dDUnpZeEV6QVJCZ05WQkFvTUNrRndjR3hsSUVsdVl5NHhDekFKQmdOVkJBWVRBbFZUTUhZd0VBWUhLb1pJemowQ0FRWUZLNEVFQUNJRFlnQUVic1FLQzk0UHJsV21aWG5YZ3R4emRWSkw4VDBTR1luZ0RSR3BuZ24zTjZQVDhKTUViN0ZEaTRiQm1QaENuWjMvc3E2UEYvY0djS1hXc0w1dk90ZVJoeUo0NXgzQVNQN2NPQithYW85MGZjcHhTdi9FWkZibmlBYk5nWkdoSWhwSW80SDZNSUgzTUJJR0ExVWRFd0VCL3dRSU1BWUJBZjhDQVFBd0h3WURWUjBqQkJnd0ZvQVV1N0Rlb1ZnemlKcWtpcG5ldnIzcnI5ckxKS3N3UmdZSUt3WUJCUVVIQVFFRU9qQTRNRFlHQ0NzR0FRVUZCekFCaGlwb2RIUndPaTh2YjJOemNDNWhjSEJzWlM1amIyMHZiMk56Y0RBekxXRndjR3hsY205dmRHTmhaek13TndZRFZSMGZCREF3TGpBc29DcWdLSVltYUhSMGNEb3ZMMk55YkM1aGNIQnNaUzVqYjIwdllYQndiR1Z5YjI5MFkyRm5NeTVqY213d0hRWURWUjBPQkJZRUZEOHZsQ05SMDFESm1pZzk3YkI4NWMrbGtHS1pNQTRHQTFVZER3RUIvd1FFQXdJQkJqQVFCZ29xaGtpRzkyTmtCZ0lCQkFJRkFEQUtCZ2dxaGtqT1BRUURBd05vQURCbEFqQkFYaFNxNUl5S29nTUNQdHc0OTBCYUI2NzdDYUVHSlh1ZlFCL0VxWkdkNkNTamlDdE9udU1UYlhWWG14eGN4ZmtDTVFEVFNQeGFyWlh2TnJreFUzVGtVTUkzM3l6dkZWVlJUNHd4V0pDOTk0T3NkY1o0K1JHTnNZRHlSNWdtZHIwbkRHZz0iLCJNSUlDUXpDQ0FjbWdBd0lCQWdJSUxjWDhpTkxGUzVVd0NnWUlLb1pJemowRUF3TXdaekViTUJrR0ExVUVBd3dTUVhCd2JHVWdVbTl2ZENCRFFTQXRJRWN6TVNZd0pBWURWUVFMREIxQmNIQnNaU0JEWlhKMGFXWnBZMkYwYVc5dUlFRjFkR2h2Y21sMGVURVRNQkVHQTFVRUNnd0tRWEJ3YkdVZ1NXNWpMakVMTUFrR0ExVUVCaE1DVlZNd0hoY05NVFF3TkRNd01UZ3hPVEEyV2hjTk16a3dORE13TVRneE9UQTJXakJuTVJzd0dRWURWUVFEREJKQmNIQnNaU0JTYjI5MElFTkJJQzBnUnpNeEpqQWtCZ05WQkFzTUhVRndjR3hsSUVObGNuUnBabWxqWVhScGIyNGdRWFYwYUc5eWFYUjVNUk13RVFZRFZRUUtEQXBCY0hCc1pTQkpibU11TVFzd0NRWURWUVFHRXdKVlV6QjJNQkFHQnlxR1NNNDlBZ0VHQlN1QkJBQWlBMklBQkpqcEx6MUFjcVR0a3lKeWdSTWMzUkNWOGNXalRuSGNGQmJaRHVXbUJTcDNaSHRmVGpqVHV4eEV0WC8xSDdZeVlsM0o2WVJiVHpCUEVWb0EvVmhZREtYMUR5eE5CMGNUZGRxWGw1ZHZNVnp0SzUxN0lEdll1VlRaWHBta09sRUtNYU5DTUVBd0hRWURWUjBPQkJZRUZMdXczcUZZTTRpYXBJcVozcjY5NjYvYXl5U3JNQThHQTFVZEV3RUIvd1FGTUFNQkFmOHdEZ1lEVlIwUEFRSC9CQVFEQWdFR01Bb0dDQ3FHU000OUJBTURBMmdBTUdVQ01RQ0Q2Y0hFRmw0YVhUUVkyZTN2OUd3T0FFWkx1Tit5UmhIRkQvM21lb3locG12T3dnUFVuUFdUeG5TNGF0K3FJeFVDTUcxbWloREsxQTNVVDgyTlF6NjBpbU9sTTI3amJkb1h0MlFmeUZNbStZaGlkRGtMRjF2TFVhZ002QmdENTZLeUtBPT0iXX0.eyJub3RpZmljYXRpb25UeXBlIjoiT05FX1RJTUVfQ0hBUkdFIiwibm90aWZpY2F0aW9uVVVJRCI6ImFkMGEyODJiLWI0ZmEtNGE5ZS05YTk3LWEzYjZiNTQ2NWQ1OCIsImRhdGEiOnsiYXBwQXBwbGVJZCI6NjQ5OTEyMzYyNywiYnVuZGxlSWQiOiJjb20uc2luYXRhLkpLRml0bmVzcyIsImJ1bmRsZVZlcnNpb24iOiIxMyIsImVudmlyb25tZW50IjoiU2FuZGJveCIsInNpZ25lZFRyYW5zYWN0aW9uSW5mbyI6ImV5SmhiR2NpT2lKRlV6STFOaUlzSW5nMVl5STZXeUpOU1VsRlRVUkRRMEUzWVdkQmQwbENRV2RKVVdaVWJHWmtNR1pPZGtaWGRucERNVmxKUVU1eldHcEJTMEpuWjNGb2EycFBVRkZSUkVGNlFqRk5WVkYzVVdkWlJGWlJVVVJFUkhSQ1kwaENjMXBUUWxoaU0wcHpXa2hrY0ZwSFZXZFNSMVl5V2xkNGRtTkhWbmxKUmtwc1lrZEdNR0ZYT1hWamVVSkVXbGhLTUdGWFduQlpNa1l3WVZjNWRVbEZSakZrUjJoMlkyMXNNR1ZVUlV4TlFXdEhRVEZWUlVOM2QwTlNlbGw0UlhwQlVrSm5UbFpDUVc5TlEydEdkMk5IZUd4SlJXeDFXWGswZUVONlFVcENaMDVXUWtGWlZFRnNWbFJOUWpSWVJGUkplazFFYTNoTmFrVTFUbFJGTVUweGIxaEVWRWt4VFZSQmVFMVVSVFZPVkVVeFRXeHZkMmRhU1hoUlJFRXJRbWRPVmtKQlRVMU9NVUo1WWpKUloxSlZUa1JKUlRGb1dYbENRbU5JUVdkVk0xSjJZMjFWWjFsWE5XdEpSMnhWWkZjMWJHTjVRbFJrUnpsNVdsTkNVMXBYVG14aFdFSXdTVVpPY0ZveU5YQmliV040VEVSQmNVSm5UbFpDUVhOTlNUQkdkMk5IZUd4SlJtUjJZMjE0YTJReWJHdGFVMEpGV2xoYWJHSkhPWGRhV0VsblZXMVdjMWxZVW5CaU1qVjZUVkpOZDBWUldVUldVVkZMUkVGd1FtTklRbk5hVTBKS1ltMU5kVTFSYzNkRFVWbEVWbEZSUjBWM1NsWlZla0phVFVKTlIwSjVjVWRUVFRRNVFXZEZSME5EY1VkVFRUUTVRWGRGU0VFd1NVRkNSVVpGV1dVdlNuRlVjWGxSZGk5a2RGaHJZWFZFU0VOVFkxWXhNamxHV1ZKV0x6QjRhVUl5Tkc1RFVXdDZVV1l6WVhOSVNrOU9ValZ5TUZKQk1HRk1ka28wTXpKb2VURlRXazF2ZFhaNVpuQnRNalpxV0ZOcVoyZEpTVTFKU1VOQ1JFRk5RbWRPVmtoU1RVSkJaamhGUVdwQlFVMUNPRWRCTVZWa1NYZFJXVTFDWVVGR1JEaDJiRU5PVWpBeFJFcHRhV2M1TjJKQ09EVmpLMnhyUjB0YVRVaEJSME5EYzBkQlVWVkdRbmRGUWtKSFVYZFpha0YwUW1kbmNrSm5SVVpDVVdOM1FXOVphR0ZJVWpCalJHOTJUREpPYkdOdVVucE1iVVozWTBkNGJFeHRUblppVXprelpESlNlVnA2V1hWYVIxWjVUVVJGUjBORGMwZEJVVlZHUW5wQlFtaHBWbTlrU0ZKM1QyazRkbUl5VG5walF6Vm9ZMGhDYzFwVE5XcGlNakIyWWpKT2VtTkVRWHBNV0dReldraEtiazVxUVhsTlNVbENTR2RaUkZaU01HZENTVWxDUmxSRFEwRlNSWGRuWjBWT1FtZHZjV2hyYVVjNU1rNXJRbEZaUWsxSlNDdE5TVWhFUW1kbmNrSm5SVVpDVVdORFFXcERRblJuZVVKek1VcHNZa2RzYUdKdFRteEpSemwxU1VoU2IyRllUV2RaTWxaNVpFZHNiV0ZYVG1oa1IxVm5XVzVyWjFsWE5UVkpTRUpvWTI1U05VbEhSbnBqTTFaMFdsaE5aMWxYVG1wYVdFSXdXVmMxYWxwVFFuWmFhVUl3WVVkVloyUkhhR3hpYVVKb1kwaENjMkZYVG1oWmJYaHNTVWhPTUZsWE5XdFpXRXByU1VoU2JHTnRNWHBKUjBaMVdrTkNhbUl5Tld0aFdGSndZakkxZWtsSE9XMUpTRlo2V2xOM1oxa3lWbmxrUjJ4dFlWZE9hR1JIVldkalJ6bHpZVmRPTlVsSFJuVmFRMEpxV2xoS01HRlhXbkJaTWtZd1lWYzVkVWxJUW5sWlYwNHdZVmRPYkVsSVRqQlpXRkpzWWxkV2RXUklUWFZOUkZsSFEwTnpSMEZSVlVaQ2QwbENSbWx3YjJSSVVuZFBhVGgyWkROa00weHRSbmRqUjNoc1RHMU9kbUpUT1dwYVdFb3dZVmRhY0ZreVJqQmFWMFl4WkVkb2RtTnRiREJsVXpoM1NGRlpSRlpTTUU5Q1FsbEZSa0ZOY3poUWFuTTJWbWhYUjFGc2VrVXlXazlGSzBkWU5FOXZMMDFCTkVkQk1WVmtSSGRGUWk5M1VVVkJkMGxJWjBSQlVVSm5iM0ZvYTJsSE9USk9hMEpuYzBKQ1FVbEdRVVJCUzBKblozRm9hMnBQVUZGUlJFRjNUbTlCUkVKc1FXcEZRVGg1VWs1a2MydHdOVEEyUkVaa1VFeG5hRXhNU25kQmRqVktPR2hDUjB4aFNUaEVSWGhrWTFCWUsyRkNTMnBxVHpobFZXODVTM0JtY0dOT1dWVlpOVmxCYWtGUVdHMU5XRVZhVEN0Uk1ESmhaSEp0YlhOb1RuaDZNMDV1UzIwcmIzVlJkMVUzZGtKVWJqQk1kbXhOTjNad2N6SlpjMnhXVkdGdFVsbE1OR0ZUY3pWclBTSXNJazFKU1VSR2FrTkRRWEI1WjBGM1NVSkJaMGxWU1hOSGFGSjNjREJqTW01MlZUUlpVM2xqWVdaUVZHcDZZazVqZDBObldVbExiMXBKZW1vd1JVRjNUWGRhZWtWaVRVSnJSMEV4VlVWQmQzZFRVVmhDZDJKSFZXZFZiVGwyWkVOQ1JGRlRRWFJKUldONlRWTlpkMHBCV1VSV1VWRk1SRUl4UW1OSVFuTmFVMEpFV2xoS01HRlhXbkJaTWtZd1lWYzVkVWxGUmpGa1IyaDJZMjFzTUdWVVJWUk5Ra1ZIUVRGVlJVTm5kMHRSV0VKM1lrZFZaMU5YTldwTWFrVk1UVUZyUjBFeFZVVkNhRTFEVmxaTmQwaG9ZMDVOYWtWM1RYcEZNMDFxUVhwT2VrVjNWMmhqVGsxNldYZE5la1UxVFVSQmQwMUVRWGRYYWtJeFRWVlJkMUZuV1VSV1VWRkVSRVIwUW1OSVFuTmFVMEpZWWpOS2MxcElaSEJhUjFWblVrZFdNbHBYZUhaalIxWjVTVVpLYkdKSFJqQmhWemwxWTNsQ1JGcFlTakJoVjFwd1dUSkdNR0ZYT1hWSlJVWXhaRWRvZG1OdGJEQmxWRVZNVFVGclIwRXhWVVZEZDNkRFVucFplRVY2UVZKQ1owNVdRa0Z2VFVOclJuZGpSM2hzU1VWc2RWbDVOSGhEZWtGS1FtZE9Wa0pCV1ZSQmJGWlVUVWhaZDBWQldVaExiMXBKZW1vd1EwRlJXVVpMTkVWRlFVTkpSRmxuUVVWaWMxRkxRemswVUhKc1YyMWFXRzVZWjNSNGVtUldTa3c0VkRCVFIxbHVaMFJTUjNCdVoyNHpUalpRVkRoS1RVVmlOMFpFYVRSaVFtMVFhRU51V2pNdmMzRTJVRVl2WTBkalMxaFhjMHcxZGs5MFpWSm9lVW8wTlhnelFWTlFOMk5QUWl0aFlXODVNR1pqY0hoVGRpOUZXa1ppYm1sQllrNW5Xa2RvU1dod1NXODBTRFpOU1VnelRVSkpSMEV4VldSRmQwVkNMM2RSU1UxQldVSkJaamhEUVZGQmQwaDNXVVJXVWpCcVFrSm5kMFp2UVZWMU4wUmxiMVpuZW1sS2NXdHBjRzVsZG5JemNuSTVja3hLUzNOM1VtZFpTVXQzV1VKQ1VWVklRVkZGUlU5cVFUUk5SRmxIUTBOelIwRlJWVVpDZWtGQ2FHbHdiMlJJVW5kUGFUaDJZakpPZW1ORE5XaGpTRUp6V2xNMWFtSXlNSFppTWs1NlkwUkJla3hYUm5kalIzaHNZMjA1ZG1SSFRtaGFlazEzVG5kWlJGWlNNR1pDUkVGM1RHcEJjMjlEY1dkTFNWbHRZVWhTTUdORWIzWk1NazU1WWtNMWFHTklRbk5hVXpWcVlqSXdkbGxZUW5kaVIxWjVZakk1TUZreVJtNU5lVFZxWTIxM2QwaFJXVVJXVWpCUFFrSlpSVVpFT0hac1EwNVNNREZFU20xcFp6azNZa0k0TldNcmJHdEhTMXBOUVRSSFFURlZaRVIzUlVJdmQxRkZRWGRKUWtKcVFWRkNaMjl4YUd0cFJ6a3lUbXRDWjBsQ1FrRkpSa0ZFUVV0Q1oyZHhhR3RxVDFCUlVVUkJkMDV2UVVSQ2JFRnFRa0ZZYUZOeE5VbDVTMjluVFVOUWRIYzBPVEJDWVVJMk56ZERZVVZIU2xoMVpsRkNMMFZ4V2tka05rTlRhbWxEZEU5dWRVMVVZbGhXV0cxNGVHTjRabXREVFZGRVZGTlFlR0Z5V2xoMlRuSnJlRlV6Vkd0VlRVa3pNM2w2ZGtaV1ZsSlVOSGQ0VjBwRE9UazBUM05rWTFvMEsxSkhUbk5aUkhsU05XZHRaSEl3YmtSSFp6MGlMQ0pOU1VsRFVYcERRMEZqYldkQmQwbENRV2RKU1V4aldEaHBUa3hHVXpWVmQwTm5XVWxMYjFwSmVtb3dSVUYzVFhkYWVrVmlUVUpyUjBFeFZVVkJkM2RUVVZoQ2QySkhWV2RWYlRsMlpFTkNSRkZUUVhSSlJXTjZUVk5aZDBwQldVUldVVkZNUkVJeFFtTklRbk5hVTBKRVdsaEtNR0ZYV25CWk1rWXdZVmM1ZFVsRlJqRmtSMmgyWTIxc01HVlVSVlJOUWtWSFFURlZSVU5uZDB0UldFSjNZa2RWWjFOWE5XcE1ha1ZNVFVGclIwRXhWVVZDYUUxRFZsWk5kMGhvWTA1TlZGRjNUa1JOZDAxVVozaFBWRUV5VjJoalRrMTZhM2RPUkUxM1RWUm5lRTlVUVRKWGFrSnVUVkp6ZDBkUldVUldVVkZFUkVKS1FtTklRbk5hVTBKVFlqSTVNRWxGVGtKSlF6Qm5VbnBOZUVwcVFXdENaMDVXUWtGelRVaFZSbmRqUjNoc1NVVk9iR051VW5CYWJXeHFXVmhTY0dJeU5HZFJXRll3WVVjNWVXRllValZOVWsxM1JWRlpSRlpSVVV0RVFYQkNZMGhDYzFwVFFrcGliVTExVFZGemQwTlJXVVJXVVZGSFJYZEtWbFY2UWpKTlFrRkhRbmx4UjFOTk5EbEJaMFZIUWxOMVFrSkJRV2xCTWtsQlFrcHFjRXg2TVVGamNWUjBhM2xLZVdkU1RXTXpVa05XT0dOWGFsUnVTR05HUW1KYVJIVlhiVUpUY0ROYVNIUm1WR3BxVkhWNGVFVjBXQzh4U0RkWmVWbHNNMG8yV1ZKaVZIcENVRVZXYjBFdlZtaFpSRXRZTVVSNWVFNUNNR05VWkdSeFdHdzFaSFpOVm5wMFN6VXhOMGxFZGxsMVZsUmFXSEJ0YTA5c1JVdE5ZVTVEVFVWQmQwaFJXVVJXVWpCUFFrSlpSVVpNZFhjemNVWlpUVFJwWVhCSmNWb3pjalk1TmpZdllYbDVVM0pOUVRoSFFURlZaRVYzUlVJdmQxRkdUVUZOUWtGbU9IZEVaMWxFVmxJd1VFRlJTQzlDUVZGRVFXZEZSMDFCYjBkRFEzRkhVMDAwT1VKQlRVUkJNbWRCVFVkVlEwMVJRMFEyWTBoRlJtdzBZVmhVVVZreVpUTjJPVWQzVDBGRldreDFUaXQ1VW1oSVJrUXZNMjFsYjNsb2NHMTJUM2RuVUZWdVVGZFVlRzVUTkdGMEszRkplRlZEVFVjeGJXbG9SRXN4UVROVlZEZ3lUbEY2TmpCcGJVOXNUVEkzYW1Ka2IxaDBNbEZtZVVaTmJTdFphR2xrUkd0TVJqRjJURlZoWjAwMlFtZEVOVFpMZVV0QlBUMGlYWDAuZXlKMGNtRnVjMkZqZEdsdmJrbGtJam9pTWpBd01EQXdNRFkyTXpNMU5ESXlPQ0lzSW05eWFXZHBibUZzVkhKaGJuTmhZM1JwYjI1SlpDSTZJakl3TURBd01EQTJOak16TlRReU1qZ2lMQ0ppZFc1a2JHVkpaQ0k2SW1OdmJTNXphVzVoZEdFdVNrdEdhWFJ1WlhOeklpd2ljSEp2WkhWamRFbGtJam9pWTI5dExtcHJabWwwYm1WemN5NWhMbkJ5YVdObExqRWlMQ0p3ZFhKamFHRnpaVVJoZEdVaU9qRTNNakUyTkRVNE1qWXdNREFzSW05eWFXZHBibUZzVUhWeVkyaGhjMlZFWVhSbElqb3hOekl4TmpRMU9ESTJNREF3TENKeGRXRnVkR2wwZVNJNk1Td2lkSGx3WlNJNklrTnZibk4xYldGaWJHVWlMQ0pwYmtGd2NFOTNibVZ5YzJocGNGUjVjR1VpT2lKUVZWSkRTRUZUUlVRaUxDSnphV2R1WldSRVlYUmxJam94TnpJeE5qUTFPRFF5TkRnNExDSmxiblpwY205dWJXVnVkQ0k2SWxOaGJtUmliM2dpTENKMGNtRnVjMkZqZEdsdmJsSmxZWE52YmlJNklsQlZVa05JUVZORklpd2ljM1J2Y21WbWNtOXVkQ0k2SWtOSVRpSXNJbk4wYjNKbFpuSnZiblJKWkNJNklqRTBNelEyTlNJc0luQnlhV05sSWpvNU9EQXdNQ3dpWTNWeWNtVnVZM2tpT2lKRFRsa2lmUS5nTC1UVThvRV9NY2Q5TGpQb2g0LWxuT3JZek04N1FOY1RxYXFqZ05KT3VSWHMxZGpKQ1VnSVR0Vmd5cWdvMXozVGpGc3BYd1RpYklQeVN1NFg3QUd5dyJ9LCJ2ZXJzaW9uIjoiMi4wIiwic2lnbmVkRGF0ZSI6MTcyMTY0NTg0MjUwNn0.bQeSZOF1IDCD--iN3i711ADUVwhrIoqCLklkBUHsebpFPgTH5TtAJjaeSFkmrqCXzZYLb_m-5acirt5xnWMubQ"); +// String notificationType = payload.get("notificationType").toString(); +// JSONObject data = payload.getJSONObject("data"); +// String signedTransactionInfo = data.get("signedTransactionInfo").toString(); +// String environment = data.get("environment").toString(); +// JSONObject transactionInfo = verifyAndGet(signedTransactionInfo); +// String transactionId = transactionInfo.get("transactionId").toString(); +// String originalTransactionId = transactionInfo.get("originalTransactionId").toString(); +// String productId = transactionInfo.get("productId").toString(); +// System.err.println("json串"+transactionInfo); +// System.err.println("data"+data); +// if ("DID_RENEW".equals(notificationType)) { +// // todo 处理订阅续期业务逻辑 +// +// } else if ("REFUND".equals(notificationType)) { +// // todo 处理退款业务逻辑 +// +// } else { +// } +// +// } catch (CertificateException e) { +// } +// +// +// } + public static JSONObject verifyAndGet(String jws) throws CertificateException { + DecodedJWT decodedJWT = JWT.decode(jws); + // 拿到 header 中 x5c 数组中第一个 + String header = new String(java.util.Base64.getDecoder().decode(decodedJWT.getHeader())); + String x5c = JSONObject.parseObject(header).getJSONArray("x5c").getString(0); + + // 获取公钥 + PublicKey publicKey = getPublicKeyByX5c(x5c); + + // 验证 token + Algorithm algorithm = Algorithm.ECDSA256((ECPublicKey) publicKey, null); + + try { + algorithm.verify(decodedJWT); + } catch (SignatureVerificationException e) { + throw new RuntimeException("签名验证失败"); + } + // 解析数据 + return JSONObject.parseObject(new String(java.util.Base64.getDecoder().decode(decodedJWT.getPayload()))); + } + + + /** + * 获取公钥 + * @param x5c + * @return + * @throws + */ + private static PublicKey getPublicKeyByX5c(String x5c) throws CertificateException { + byte[] x5c0Bytes = java.util.Base64.getDecoder().decode(x5c); + CertificateFactory fact = CertificateFactory.getInstance("X.509"); + X509Certificate cer = (X509Certificate) fact.generateCertificate(new ByteArrayInputStream(x5c0Bytes)); + return cer.getPublicKey(); + } + + + } -- Gitblit v1.7.1