From 61bbd595ee2bc3c67b40878894dcc07174c6eea6 Mon Sep 17 00:00:00 2001 From: 无关风月 <443237572@qq.com> Date: 星期二, 24 九月 2024 10:15:30 +0800 Subject: [PATCH] 玩湃微信商户分账 --- cloud-server-management/src/main/java/com/dsh/guns/modular/system/util/PayMoneyUtil.java | 283 +++ cloud-server-other/src/main/java/com/dsh/other/util/PayMoneyUtil.java | 190 ++ cloud-server-management/src/main/webapp/WEB-INF/view/system/operator/OperatorUser_proportionAuth_info.html | 4 cloud-server-management/src/main/java/com/dsh/course/mapper/CarInsuranceMapper.java | 2 cloud-server-account/src/main/java/com/dsh/account/feignclient/activity/model/PointsMerchandise.java | 2 cloud-server-management/src/main/resources/mapper/TOperatorAuthWxMapper.xml | 6 cloud-server-management/src/main/java/com/dsh/guns/modular/system/service/IOperatorAuthWxService.java | 12 cloud-server-management/src/main/java/com/dsh/guns/modular/system/util/HttpRequestUtil.java | 78 cloud-server-account/src/main/java/com/dsh/account/service/impl/TStudentServiceImpl.java | 96 + cloud-server-management/src/main/java/com/dsh/guns/modular/system/controller/util/HttpClientUtil.java | 270 +++ cloud-server-other/src/main/resources/mapper/SiteMapper.xml | 3 cloud-server-other/src/main/java/com/dsh/other/mapper/SiteMapper.java | 1 cloud-server-management/src/main/java/com/dsh/guns/modular/system/controller/util/MD5AndKL.java | 111 + cloud-server-management/src/main/java/com/dsh/guns/modular/system/service/TOperatorService.java | 2 cloud-server-management/src/main/java/com/dsh/guns/modular/system/service/impl/TOperatorServiceImpl.java | 17 cloud-server-course/src/main/java/com/dsh/course/service/impl/TCoursePackageServiceImpl.java | 97 + cloud-server-management/src/main/webapp/WEB-INF/view/system/operator/OperatorUser_proportionAuthWX.html | 305 +++ cloud-server-other/src/main/java/com/dsh/other/entity/TGameRecord.java | 13 cloud-server-management/src/main/webapp/WEB-INF/view/system/operator/Operator.html | 1 cloud-server-other/src/main/java/com/dsh/other/entity/SiteBooking.java | 17 cloud-server-competition/src/main/java/com/dsh/competition/service/impl/CompetitionServiceImpl.java | 102 + cloud-server-management/src/main/webapp/WEB-INF/view/system/operator/OperatorUser_proportionAuth_infoWX.html | 480 +++++ cloud-server-activity/src/main/java/com/dsh/activity/entity/PointsMerchandise.java | 7 cloud-server-account/src/main/java/com/dsh/account/model/dto/Coupon.java | 2 cloud-server-competition/src/main/java/com/dsh/competition/feignclient/other/StoreClient.java | 10 cloud-server-account/src/main/java/com/dsh/account/util/PayMoneyUtil.java | 127 + cloud-server-management/src/main/java/com/dsh/guns/modular/system/controller/code/OperatorUserController.java | 59 cloud-server-other/src/main/java/com/dsh/other/service/impl/SiteServiceImpl.java | 142 + cloud-server-course/src/main/java/com/dsh/course/service/impl/TCoursePackagePaymentServiceImpl.java | 115 + cloud-server-competition/src/main/java/com/dsh/competition/service/impl/PaymentCompetitionServiceImpl.java | 20 cloud-server-management/src/main/java/com/dsh/guns/modular/system/model/OperatorAuth.java | 59 cloud-server-account/src/main/java/com/dsh/account/feignclient/other/StoreClient.java | 12 cloud-server-management/src/main/webapp/static/modular/system/operator/operator_add.js | 52 cloud-server-management/src/main/java/com/dsh/course/feignClient/activity/model/PointsMerchandise.java | 7 cloud-server-management/src/main/webapp/WEB-INF/view/system/tShop/TShop.html | 2 cloud-server-account/src/main/java/com/dsh/account/feignclient/activity/model/UserCouponPayment.java | 3 cloud-server-management/src/main/webapp/WEB-INF/view/system/operator/Operator_wx.html | 81 cloud-server-course/src/main/java/com/dsh/course/util/PayMoneyUtil.java | 122 + cloud-server-management/src/main/java/com/dsh/guns/modular/system/util/TaskUtil.java | 135 + cloud-server-other/src/main/java/com/dsh/other/controller/SiteController.java | 34 cloud-server-management/src/main/java/com/dsh/guns/modular/system/controller/code/OperatorController.java | 711 +++++++ cloud-server-management/pom.xml | 24 cloud-server-management/src/main/java/com/dsh/guns/modular/system/controller/util/HttpResult.java | 32 cloud-server-management/src/main/java/com/dsh/guns/modular/system/util/WxUploadImgUtil.java | 95 + cloud-server-competition/src/main/java/com/dsh/competition/entity/PaymentCompetition.java | 22 cloud-server-competition/src/main/java/com/dsh/competition/util/PayMoneyUtil.java | 192 ++ cloud-server-management/src/main/resources/bootstrap.properties | 3 cloud-server-other/src/main/java/com/dsh/other/service/ISiteService.java | 1 cloud-server-management/src/main/java/com/dsh/guns/modular/system/service/impl/TOperatorAuthWxServiceImpl.java | 24 cloud-server-course/src/main/java/com/dsh/course/feignclient/other/StoreClient.java | 9 cloud-server-management/src/main/java/com/dsh/course/mapper/TOperatorAuthWxMapper.java | 20 cloud-server-management/src/main/java/com/dsh/guns/modular/system/model/TOperator.java | 10 cloud-server-management/src/main/webapp/static/modular/system/operator/operator.js | 15 cloud-server-other/src/main/java/com/dsh/other/controller/GameController.java | 49 cloud-server-management/src/main/java/com/dsh/guns/modular/system/util/WeChatUtil.java | 336 +- cloud-server-other/src/main/java/com/dsh/other/feignclient/StoreClient.java | 7 cloud-server-account/src/main/java/com/dsh/account/service/impl/TAppUserServiceImpl.java | 150 + cloud-server-management/src/main/java/com/dsh/guns/modular/system/controller/code/TGoodsController.java | 2 cloud-server-course/src/main/java/com/dsh/course/entity/CoursePackageOrder.java | 11 cloud-server-management/src/main/webapp/static/modular/system/operatorUser/operatorUser.js | 294 +++ cloud-server-management/src/main/java/com/dsh/guns/modular/system/service/impl/TOperatorUserServiceImpl.java | 5 cloud-server-competition/src/main/java/com/dsh/competition/controller/CompetitionController.java | 30 62 files changed, 4,716 insertions(+), 407 deletions(-) diff --git a/cloud-server-account/src/main/java/com/dsh/account/feignclient/activity/model/PointsMerchandise.java b/cloud-server-account/src/main/java/com/dsh/account/feignclient/activity/model/PointsMerchandise.java index 4abbdcc..87b87de 100644 --- a/cloud-server-account/src/main/java/com/dsh/account/feignclient/activity/model/PointsMerchandise.java +++ b/cloud-server-account/src/main/java/com/dsh/account/feignclient/activity/model/PointsMerchandise.java @@ -108,5 +108,7 @@ * 课包支付配置id */ private Integer coursePackageConfigId; + private Integer addUserId; + private Integer addType; } diff --git a/cloud-server-account/src/main/java/com/dsh/account/feignclient/activity/model/UserCouponPayment.java b/cloud-server-account/src/main/java/com/dsh/account/feignclient/activity/model/UserCouponPayment.java index 23a9b6f..0458295 100644 --- a/cloud-server-account/src/main/java/com/dsh/account/feignclient/activity/model/UserCouponPayment.java +++ b/cloud-server-account/src/main/java/com/dsh/account/feignclient/activity/model/UserCouponPayment.java @@ -61,4 +61,7 @@ */ @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8") private Date insertTime; + + // 是否微信分账 + private Integer isFenZhang; } diff --git a/cloud-server-account/src/main/java/com/dsh/account/feignclient/other/StoreClient.java b/cloud-server-account/src/main/java/com/dsh/account/feignclient/other/StoreClient.java index e3bb3b9..376aca4 100644 --- a/cloud-server-account/src/main/java/com/dsh/account/feignclient/other/StoreClient.java +++ b/cloud-server-account/src/main/java/com/dsh/account/feignclient/other/StoreClient.java @@ -12,13 +12,21 @@ @FeignClient(value = "mb-cloud-other") public interface StoreClient { - /** - * 根据运营商id获取对应运营商商户号 + * 根据运营商id获取对应运营商分账比例 返回格式: 微信分账比例,支付宝分账比例 + * @return + */ + @PostMapping("/base/getProportionByOperatorId") + String getProportionByOperatorId(Integer id); + /** + * 根据运营商id获取对应运营商支付宝商户号 * @return */ @PostMapping("/base/getSMIDByOperatorId") String getSMIDByOperatorId(Integer id); + // 根据运营商id获取微信商户号 + @PostMapping("/base/getmerchantNumberByOperatorId") + String getmerchantNumberByOperatorId(Integer id); @PostMapping("/store/queryByStoreId") OperatorUser queryByStoreId(Integer storeId); diff --git a/cloud-server-account/src/main/java/com/dsh/account/model/dto/Coupon.java b/cloud-server-account/src/main/java/com/dsh/account/model/dto/Coupon.java index 2fae339..5b1dcf5 100644 --- a/cloud-server-account/src/main/java/com/dsh/account/model/dto/Coupon.java +++ b/cloud-server-account/src/main/java/com/dsh/account/model/dto/Coupon.java @@ -57,6 +57,7 @@ * 限领数量 */ private Integer pickUpQuantity; + private Integer publisherType; /** * 开始时间 */ @@ -105,6 +106,7 @@ * 状态(1=正常,2=冻结,3=删除) */ private Integer state; + private Integer cityManagerId; /** * 添加时间 */ diff --git a/cloud-server-account/src/main/java/com/dsh/account/service/impl/TAppUserServiceImpl.java b/cloud-server-account/src/main/java/com/dsh/account/service/impl/TAppUserServiceImpl.java index 55afd69..d964181 100644 --- a/cloud-server-account/src/main/java/com/dsh/account/service/impl/TAppUserServiceImpl.java +++ b/cloud-server-account/src/main/java/com/dsh/account/service/impl/TAppUserServiceImpl.java @@ -157,6 +157,7 @@ @Resource private IntroduceRewardsClient introduceRewardsClient; + private String aliAppid = "2021004105665036";//支付宝appid private String appPrivateKey = "MIIEvwIBADANBgkqhkiG9w0BAQEFAASCBKkwggSlAgEAAoIBAQCi5i9nW/hGLJ3A06cZxTQdviFC7THpdSihoTYGLr9q006hu0V26ecBMY/o4w5bvIX0Ok/yofmZsVcCJpAPvbXL/uqVrIjnRRxXiaeBFThlxoBUTdunvbUSDYfzlEhJr5NvUKI6H6lz2niXlQGx4qy8Hau4ccWit9kM8jwUvsBVQoFgJA+xrjMvooA7YLopQtpOD+UJr5thApTSf1xrnr1W12yolTLEH15JmNV372cqXrYUuqnY0QsaPtxeqJUGAOcGdVLllQ7easEznP8DFBvDdHATcmp2SHNQDUEWN6MCVPbMgY06NQVqAXxqjTAYSVh+6TRu6bofPmpYC3TZB003AgMBAAECggEBAJAcR2+PA3NBYUYHeFrqBRMS8uX8ZR19kjZ7IgoSLTFaQsP9opRylPSPXhrPVBKAE5leRQAHn4MCSlESwHvMfxo7KFjFTFAc6dffZZpipYQUOc9bGampwJh58/3e/pyBgVMG6J23CPf/HJQtNFSkjd/V9+ayb/9l2dUEL3bC0fAZ/dbx8HsxdLw8wn3fLlWLj68hOMqa2deCZe3JdSVsPbeWqkh56FFsMLug0Nd+Ar4TgRl9/jnhXF0JWiD0LmPUYLhboY7EfUBzN4w1iYbDi1P+3zvoOYsiVKAXox9GMhQ2VzOO2UcSTuizSza2e98mGpabl/GpKmCz+RDFjtkX6eECgYEA2MyCij65eO3aGIm3FUe93DULRBYTfX8qJQSJq2WOWA3mmQlEW6L3O2B5/lG2h+8WmN6iLEs9eHpgycGYp7vAqgrANEn16ACVcuyx0scFtrZfZ+kmHMzFfiUWxJjVYk/6YngsGVBLdw6ueM42C8TTP67X9tU5TdVGoGWuqEj4W98CgYEAwFqwprXOch5Pqk/RPbb49r0Ou03K/UbciWnWWKzUhFFNS8MdlQPoDvQZbMwHLeWsa2VhaKITK3x5biLQb3U+0GLOn6lTvEyrEUH+ucREyLgVYTRAvwBPtnvlrzpyxPk2HnslQjju8WrvvLLBMKWUjlTrTOzhaHT21gz3pHMiOakCgYEAhLmfaXdBITGshb054sNLDtdCkGpbgEcrzAHdLps769iGxkYQHXHFngpQZUwtTUcoNGqIKknd1jZFrv7gsD+XkgKG7PwimehRlkwmCX5ilxtLiVgJRzRt6+5U5AMVD90a0tHzXYP0z2yjj73fBJF5KtGl0a10KZxaYrQdm1UhB00CgYBZZgzx/k9rtHC8LAqIj1CYhHejT92G53c6Gkl3vyOqN4sgKhfGmSEySfrDGPRBPZxr8ZtbIPCd5mUdberH0osWGMYFaJI1UsCy7aQwvGpniz7MhZeN7dweaOjwDs8mgtjHQ96mL4XGCDhR0BZ/wIURvZ/6iaGdhbbu9unlsWj3uQKBgQCmZYdsbbZkd3ev6f8rwyvMz+DrCQyYpY44cegBYuJgrZiQnL2fJioeN7ixX0UM48SfwsZEIrzshP/LGAwnc2MdjxKUl4jLN8SEe0NAjXOnz9Zaw740+aOmLpXcLWdP4uM2gIhWsvW1tEkQZCXmm7c9s/RsU8Pmzv+YL3+fSijOzA==";//支付宝开发者应用私钥 @@ -1407,7 +1408,12 @@ userCouponPaymentClient.addUserCouponPayment(userCouponPayment); try { if(exchangeType.getPayType() == 1){ - return weChatPaymentCoupon("购买优惠券", userCouponPayment); + String temp = "0"; + if (coupon.getPublisherType()!=null && coupon.getPublisherType() != 2){ + // 做分账 + temp = "1"; + } + return weChatPaymentCoupon("购买优惠券-"+temp, userCouponPayment); } if(exchangeType.getPayType() == 2){ return aliPaymentCoupon("购买优惠券", userCouponPayment); @@ -1417,8 +1423,6 @@ } } } - - System.out.println(exchangeType); try { SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmssSSS"); @@ -1629,9 +1633,9 @@ coursePackageOrder.setInsertTime(new Date()); coursePackageOrder.setOrderType(2); paymentClient.savePaymentCoursePackage(coursePackageOrder); - return WechatPayment(merchandise.getType(), merchandise.getCash().multiply(new BigDecimal(exchangeType.getStuIds().size())), code); - } else { - return WechatPayment(merchandise.getType(), merchandise.getCash().multiply(new BigDecimal(goodsNums)), code); + return WechatPayment(merchandise.getType(), merchandise.getCash().multiply(new BigDecimal(exchangeType.getStuIds().size())), code,merchandise.getId()); + } else if (merchandise.getType() == 1){ + return WechatPayment(merchandise.getType(), merchandise.getCash().multiply(new BigDecimal(goodsNums)), code,merchandise.getId()); } } catch (Exception e) { return ResultUtil.runErr(); @@ -1651,9 +1655,9 @@ case 1: try { if (merchandise.getType() == 2) { - return WechatPayment(merchandise.getType(), merchandise.getCash().multiply(new BigDecimal(exchangeType.getStuIds().size())), code); + return WechatPayment(merchandise.getType(), merchandise.getCash().multiply(new BigDecimal(exchangeType.getStuIds().size())), code,merchandise.getId()); } else { - return WechatPayment(merchandise.getType(), merchandise.getCash().multiply(new BigDecimal(goodsNums)), code); + return WechatPayment(merchandise.getType(), merchandise.getCash().multiply(new BigDecimal(goodsNums)), code,merchandise.getId()); } } catch (Exception e) { return ResultUtil.runErr(); @@ -1692,7 +1696,13 @@ public ResultUtil weChatPaymentCoupon(String body, UserCouponPayment userCouponPayment) throws Exception { String code = userCouponPayment.getCode(); Double cash = userCouponPayment.getCash(); - ResultUtil weixinpay = payMoneyUtil.weixinpay(body, "", code, cash.toString(), + Integer couponId = userCouponPayment.getCouponId(); + Coupon coupon = userConponClient.queryCouponById(couponId); + String temp ="0"; + if (coupon.getPublisherType()!=null&&coupon.getPublisherType()!=2){ + temp = "1"; + } + ResultUtil weixinpay = payMoneyUtil.weixinpay(body+"-"+temp, "", code, cash.toString(), "/base/coupon/weChatPaymentCouponCallback", "APP", ""); if (weixinpay.getCode() == 200) { new Thread(new Runnable() { @@ -1707,6 +1717,7 @@ Thread.sleep(wait); UserCouponPayment userCouponPayment1 = userCouponPaymentClient.getUserCouponPayment(code); if (userCouponPayment1.getStatus() == 2) { + break; } ResultUtil<Map<String, String>> resultUtil = payMoneyUtil.queryWXOrder(code, ""); @@ -1747,6 +1758,38 @@ TAppUser user = appUserService.getById(userCouponPayment1.getUserId()); user.setIntegral(user.getIntegral() - userCouponPayment1.getIntegral().intValue()); appUserService.updateById(user); + } + // 休眠两分钟后再调用分账接口 避免提示订单正在处理中 + Thread.sleep(120000); + if (coupon!=null){ + if (coupon.getPublisherType()!=null&&coupon.getPublisherType()!=2){ + if (coupon.getPublisherType() == 3){ + // 门店 向上查询运营商 + Store store = storeClient.queryStoreById(coupon.getCityManagerId()); + if (store.getOperatorId()==null || store.getOperatorId()==0){ + // 平台不分账 + break; + }else{ + // 根据运营商id获取对应运营商分账比例 返回格式: 微信分账比例,支付宝分账比例 + String proportionByOperatorId = storeClient.getProportionByOperatorId(store.getOperatorId()); + String[] split = proportionByOperatorId.split(","); + String s1 = split[0]; + if (!s1.equals("未设置")){ + BigDecimal bigDecimal = new BigDecimal(s1); + // 分账比例 + BigDecimal bigDecimal1 = bigDecimal.divide(new BigDecimal(100)).setScale(2); + // 微信商户号 + String s2 = storeClient.getmerchantNumberByOperatorId(store.getOperatorId()); + BigDecimal bigDecimal2 = new BigDecimal(cash); + ResultUtil fenzhang = payMoneyUtil.fenzhang(userCouponPayment1.getOrderNumber(), bigDecimal2.multiply(bigDecimal1), s2); + if (!fenzhang.getCode().equals(500)){ + System.err.println("分账失败 原因是:"+fenzhang.getMsg()); + } + + } + } + } + } } break; } @@ -2080,9 +2123,39 @@ } - private ResultUtil WechatPayment(Integer type, BigDecimal cash, String code) throws Exception { + private ResultUtil WechatPayment(Integer type, BigDecimal cash, String code,Integer id) throws Exception { String name = (type == 1 ? "购买实体商品" : type == 2 ? "报名运动营": type == 3 ? "购买门票" : "购买优惠券"); - ResultUtil weixinpay = payMoneyUtil.weixinpay(name, "", code, cash.toString(), + PointsMerchandise pointsMerchandise = mcClient.selectPointsMerchandiseById(id); + // 分账表示 0否1是 + String temp = "0"; + switch (type){ + case 1: + temp = "0"; + break; + case 2: + // 判断课包属于平台还是运营商 + CoursePackage coursePackage = cpageClient.queryCoursePackageById(pointsMerchandise.getCoursePackageId()); + Store store = storeClient.queryStoreById(coursePackage.getStoreId()); + if (store.getOperatorId() ==null || store.getOperatorId() == 0){ + // 平台课包 不分账 + }else{ + temp = "1"; + } + break; + case 3: + List<Integer> integers = mcsClient.queryPointMerStoreIds(pointsMerchandise.getId()); + if (!integers.isEmpty()){ + Store store1 = storeClient.queryStoreById(integers.get(0)); + if (store1.getOperatorId() ==null || store1.getOperatorId() == 0){ + // 平台门票 不分账 + }else{ + temp = "1"; + } + } + // 查询门票指定的门店 属于平台还是运营商 + break; + } + ResultUtil weixinpay = payMoneyUtil.weixinpay(name+"-"+temp, "", code, cash.toString(), "/base/pointMer/exchangeGoodPaymentWeChatCallback", "APP", ""); if (weixinpay.getCode() == 200) { new Thread(new Runnable() { @@ -2097,6 +2170,8 @@ Thread.sleep(wait); UserPointsMerchandise userPointsMerchandise = mcClient.queryUserPointMerchaseByCode(code).get(0); if (userPointsMerchandise.getPayStatus() == 2) { + + break; } ResultUtil<Map<String, String>> resultUtil = payMoneyUtil.queryWXOrder(code, ""); @@ -2147,6 +2222,59 @@ paymentClient.addCoursePackageOrderStudent(addCoursePackageOrderStudent); } } + // 休眠两分钟后再调用分账接口 避免提示订单正在处理中 + Thread.sleep(120000); + // 分账表示 0否1是 + String temp = "0"; + // 运营商id + Integer operatorId = 0; + switch (type){ + case 1: + temp = "0"; + break; + case 2: + // 判断课包属于平台还是运营商 + CoursePackage coursePackage = cpageClient.queryCoursePackageById(pointsMerchandise.getCoursePackageId()); + Store store = storeClient.queryStoreById(coursePackage.getStoreId()); + if (store.getOperatorId() ==null || store.getOperatorId() == 0){ + // 平台课包 不分账 + }else{ + temp = "1"; + operatorId = store.getOperatorId(); + } + break; + case 3: + List<Integer> integers = mcsClient.queryPointMerStoreIds(pointsMerchandise.getId()); + if (!integers.isEmpty()){ + Store store1 = storeClient.queryStoreById(integers.get(0)); + if (store1.getOperatorId() ==null || store1.getOperatorId() == 0){ + // 平台门票 不分账 + }else{ + temp = "1"; + operatorId = store1.getOperatorId(); + } + } + // 查询门票指定的门店 属于平台还是运营商 + break; + } + if (operatorId != 0) { + // 根据运营商id获取对应运营商分账比例 返回格式: 微信分账比例,支付宝分账比例 + String proportionByOperatorId = storeClient.getProportionByOperatorId(operatorId); + String[] split = proportionByOperatorId.split(","); + String s1 = split[0]; + if (!s1.equals("未设置")){ + BigDecimal bigDecimal = new BigDecimal(s1); + // 分账比例 + BigDecimal bigDecimal1 = bigDecimal.divide(new BigDecimal(100)).setScale(2); + // 微信商户号 + String s2 = storeClient.getmerchantNumberByOperatorId(operatorId); + + ResultUtil fenzhang = payMoneyUtil.fenzhang(transaction_id, cash.multiply(bigDecimal1), s2); + if (!fenzhang.getCode().equals(500)){ + System.err.println("分账失败 原因是:"+fenzhang.getMsg()); + } + } + } break; } if ("USERPAYING".equals(s) || "NOTPAY".equals(s)) { diff --git a/cloud-server-account/src/main/java/com/dsh/account/service/impl/TStudentServiceImpl.java b/cloud-server-account/src/main/java/com/dsh/account/service/impl/TStudentServiceImpl.java index 9219575..8b8a57b 100644 --- a/cloud-server-account/src/main/java/com/dsh/account/service/impl/TStudentServiceImpl.java +++ b/cloud-server-account/src/main/java/com/dsh/account/service/impl/TStudentServiceImpl.java @@ -1,5 +1,9 @@ package com.dsh.account.service.impl; +import com.alipay.api.AlipayClient; +import com.alipay.api.DefaultAlipayClient; +import com.alipay.api.request.AlipayTradeOrderSettleRequest; +import com.alipay.api.response.AlipayTradeOrderSettleResponse; import com.alipay.api.response.AlipayTradeQueryResponse; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; @@ -394,7 +398,7 @@ try { switch (request.getPayType()) { case 1: - return WeChatPayment(code, request.getPayAmount(), hour); + return WeChatPayment(code, request.getPayAmount(), hour,request.getLessonId()); case 2: return AlipayPayment(code, request.getPayAmount(), hour); case 3: @@ -419,8 +423,19 @@ } - public ResultUtil WeChatPayment(String code, BigDecimal amount, Integer hour) throws Exception { - ResultUtil weixinpay = payMoneyUtil.weixinpay("课包续费", "", code, amount.toString(), + public ResultUtil WeChatPayment(String code, BigDecimal amount, Integer hour,Integer lessonId) throws Exception { + // 判断这个课包是属于哪个运营商的 + CoursePackage coursePackage = coursePackageClient.queryCoursePackageById(lessonId); + Integer storeId = coursePackage.getStoreId(); + Store store = storeClient.queryStoreById(storeId); + // 是否分账 0否1是 + int isFenZhang= 1; + String merchantNumber = ""; + if (store.getOperatorId()==null || store.getOperatorId()==0){ + // 平台 + isFenZhang = 0; + } + ResultUtil weixinpay = payMoneyUtil.weixinpay("课包续费"+"-"+isFenZhang, "", code, amount.toString(), "/base/coursePackage/wechatPaymentCallback", "APP", ""); if (weixinpay.getCode() == 200) { new Thread(new Runnable() { @@ -462,6 +477,26 @@ coursePackagePayment.setLaveClassHours(hour); coursePackagePayment.setOrderNumber(transaction_id); couPayClient.updatePaymentCoursePackage(coursePackagePayment); + if (store.getOperatorId()!=null && store.getOperatorId()!=0){ + // 休眠两分钟后再调用分账接口 避免提示订单正在处理中 + Thread.sleep(120000); + // 根据运营商id获取对应运营商分账比例 返回格式: 微信分账比例,支付宝分账比例 + String proportionByOperatorId = storeClient.getProportionByOperatorId(store.getOperatorId()); + String[] split = proportionByOperatorId.split(","); + String s1 = split[0]; + if (!s1.equals("未设置")){ + BigDecimal bigDecimal = new BigDecimal(s1); + // 分账比例 + BigDecimal bigDecimal1 = bigDecimal.divide(new BigDecimal(100)).setScale(2); + // 微信商户号 + String s2 = storeClient.getmerchantNumberByOperatorId(store.getOperatorId()); + + ResultUtil fenzhang = payMoneyUtil.fenzhang(transaction_id, amount.multiply(bigDecimal1), s2); + if (!fenzhang.getCode().equals(500)){ + System.err.println("分账失败 原因是:"+fenzhang.getMsg()); + } + } + } break; } if ("USERPAYING".equals(s) || "NOTPAY".equals(s)) { @@ -542,14 +577,19 @@ Integer storeId = coursePackage.getStoreId(); Store store = storeClient.queryStoreById(storeId); String smid1= ""; - if (store.getOperatorId()==null){ + if (store.getOperatorId()==null || store.getOperatorId() == 0){ // 平台 smid1 = smid; + // 属于平台 不做资金冻结 不做分账处理 + payMoneyUtil.confirm(smid1,code,tradeNo,amount.toString()); }else{ String smidByOperatorId = storeClient.getSMIDByOperatorId(store.getOperatorId()); smid1 = smidByOperatorId; + payMoneyUtil.confirm1(smid1,code,tradeNo,amount.toString()); + // 分账处理 + extracted(store.getOperatorId(), amount, tradeNo); } - payMoneyUtil.confirm(smid1,code,tradeNo,amount.toString()); + break; } if ("WAIT_BUYER_PAY".equals(tradeStatus)) { @@ -565,7 +605,51 @@ } return alipay; } - + private void extracted(Integer operatorId, BigDecimal coursePackageOrder1, String tradeNo) throws Exception { + // 分账 + AlipayClient alipayClient = new DefaultAlipayClient("https://openapi.alipay.com/gateway.do", + "2021004105665036", + "MIIEvwIBADANBgkqhkiG9w0BAQEFAASCBKkwggSlAgEAAoIBAQCi5i9nW/hGLJ3A06cZxTQdviFC7THpdSihoTYGLr9q006hu0V26ecBMY/o4w5bvIX0Ok/yofmZsVcCJpAPvbXL/uqVrIjnRRxXiaeBFThlxoBUTdunvbUSDYfzlEhJr5NvUKI6H6lz2niXlQGx4qy8Hau4ccWit9kM8jwUvsBVQoFgJA+xrjMvooA7YLopQtpOD+UJr5thApTSf1xrnr1W12yolTLEH15JmNV372cqXrYUuqnY0QsaPtxeqJUGAOcGdVLllQ7easEznP8DFBvDdHATcmp2SHNQDUEWN6MCVPbMgY06NQVqAXxqjTAYSVh+6TRu6bofPmpYC3TZB003AgMBAAECggEBAJAcR2+PA3NBYUYHeFrqBRMS8uX8ZR19kjZ7IgoSLTFaQsP9opRylPSPXhrPVBKAE5leRQAHn4MCSlESwHvMfxo7KFjFTFAc6dffZZpipYQUOc9bGampwJh58/3e/pyBgVMG6J23CPf/HJQtNFSkjd/V9+ayb/9l2dUEL3bC0fAZ/dbx8HsxdLw8wn3fLlWLj68hOMqa2deCZe3JdSVsPbeWqkh56FFsMLug0Nd+Ar4TgRl9/jnhXF0JWiD0LmPUYLhboY7EfUBzN4w1iYbDi1P+3zvoOYsiVKAXox9GMhQ2VzOO2UcSTuizSza2e98mGpabl/GpKmCz+RDFjtkX6eECgYEA2MyCij65eO3aGIm3FUe93DULRBYTfX8qJQSJq2WOWA3mmQlEW6L3O2B5/lG2h+8WmN6iLEs9eHpgycGYp7vAqgrANEn16ACVcuyx0scFtrZfZ+kmHMzFfiUWxJjVYk/6YngsGVBLdw6ueM42C8TTP67X9tU5TdVGoGWuqEj4W98CgYEAwFqwprXOch5Pqk/RPbb49r0Ou03K/UbciWnWWKzUhFFNS8MdlQPoDvQZbMwHLeWsa2VhaKITK3x5biLQb3U+0GLOn6lTvEyrEUH+ucREyLgVYTRAvwBPtnvlrzpyxPk2HnslQjju8WrvvLLBMKWUjlTrTOzhaHT21gz3pHMiOakCgYEAhLmfaXdBITGshb054sNLDtdCkGpbgEcrzAHdLps769iGxkYQHXHFngpQZUwtTUcoNGqIKknd1jZFrv7gsD+XkgKG7PwimehRlkwmCX5ilxtLiVgJRzRt6+5U5AMVD90a0tHzXYP0z2yjj73fBJF5KtGl0a10KZxaYrQdm1UhB00CgYBZZgzx/k9rtHC8LAqIj1CYhHejT92G53c6Gkl3vyOqN4sgKhfGmSEySfrDGPRBPZxr8ZtbIPCd5mUdberH0osWGMYFaJI1UsCy7aQwvGpniz7MhZeN7dweaOjwDs8mgtjHQ96mL4XGCDhR0BZ/wIURvZ/6iaGdhbbu9unlsWj3uQKBgQCmZYdsbbZkd3ev6f8rwyvMz+DrCQyYpY44cegBYuJgrZiQnL2fJioeN7ixX0UM48SfwsZEIrzshP/LGAwnc2MdjxKUl4jLN8SEe0NAjXOnz9Zaw740+aOmLpXcLWdP4uM2gIhWsvW1tEkQZCXmm7c9s/RsU8Pmzv+YL3+fSijOzA==", + "json", "GBK", + "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAmu8n/4yTHWbn7VOrNc9OsLtDL1bEQ8gC1dHkj8Wy5z0mkaOsjJRIG/28ze12M0V8jdCKuuDr5Z1OPKiqf+XO3ypguEh+mYUVMBM/cZodDFQfTY1TKLWjvQCuaqlA+QUTCK6f7T7stsgyQ1o9Jj0rXZDz6PM4QHSTzjrLIBaeqM5WIBvH+fy/X+QG5Utd+/UT0kc0JyvuKhZ65yVUd/C9VcwJJAPliRsAQNrqYterwAJ9zvw9tF11wj9W0XgJ8Ccu4x3gR1vrlLRJJo/OA97RmxPQ+5hSacWQZCUd1dwiBq+YCrKVHGTj14izRHXrLc0yBlRXo7tBOIqcy3IsvKVthQIDAQAB", + "RSA2"); + AlipayTradeOrderSettleRequest request = new AlipayTradeOrderSettleRequest(); + String randomCode = UUIDUtil.getRandomCode(16); + String proportionByOperatorId1 = storeClient.getProportionByOperatorId(operatorId); + // 支付宝分账比例 + String s1 = proportionByOperatorId1.split(",")[1]; + double i = Double.parseDouble(s1); + double v = i * 0.01; + BigDecimal bigDecimal1 = new BigDecimal(String.valueOf(v)); + // 分账金额 + BigDecimal bigDecimal2 = coursePackageOrder1.multiply(bigDecimal1).setScale(2, RoundingMode.DOWN); + request.setBizContent("{" + + " \"out_request_no\":\"" + randomCode + "\"," + + " \"trade_no\":\"" + tradeNo + "\"," + + " \"royalty_parameters\":[" + + " {" + + " \"royalty_type\":\"transfer\"," + + " \"trans_out\":\"" + storeClient.getSMIDByOperatorId(operatorId)+ "\"," + + " \"trans_out_type\":\"userId\"," + + " \"trans_in_type\":\"userId\"," + + " \"trans_in\":\"" + smid + "\"," + + " \"amount\":" + bigDecimal2 + "," + + " \"desc\":\"平台服务费\"," + + " \"royalty_scene\":\"平台服务费\"," + + " }" + + " ]," + + " \"extend_params\":{" + + " \"royalty_finish\":\"true\"" + + " }," + + " \"royalty_mode\":\"async\"" + + "}"); + AlipayTradeOrderSettleResponse response = alipayClient.execute(request); + if (response.isSuccess()) { + System.out.println("调用成功"); + } else { + System.out.println("调用失败"); + } + } public int PlaypaiGoldPayment(String code, ClasspaymentRequest request) { PlayPaiGoldCoursePackage paiGoldCoursePackage = new PlayPaiGoldCoursePackage(); paiGoldCoursePackage.setCoursePackageId(request.getLessonId()); diff --git a/cloud-server-account/src/main/java/com/dsh/account/util/PayMoneyUtil.java b/cloud-server-account/src/main/java/com/dsh/account/util/PayMoneyUtil.java index 9922615..7802c17 100644 --- a/cloud-server-account/src/main/java/com/dsh/account/util/PayMoneyUtil.java +++ b/cloud-server-account/src/main/java/com/dsh/account/util/PayMoneyUtil.java @@ -36,6 +36,7 @@ import org.springframework.http.HttpHeaders; import org.springframework.http.MediaType; import org.springframework.stereotype.Component; +import org.springframework.util.StringUtils; import javax.annotation.Resource; import javax.crypto.BadPaddingException; @@ -88,6 +89,78 @@ private String certPath = "/usr/playpai/cert/weixin/apiclient_cert.p12";//微信证书 + + + /** + * 发起分账 + * @param order 微信订单号 + * @return + */ + public ResultUtil fenzhang(String order,BigDecimal amount,String merchantNumber) throws Exception { + Map<String, Object> map = new HashMap<>(); + map.put("mch_id", mchId); + map.put("appid", appid); + String nonce_str = UUIDUtil.getRandomCode(16); + map.put("nonce_str", nonce_str); + map.put("transaction_id", order); + // 将这个字符串使用json格式拼接起来 + Map<String, Object> body = new HashMap<>(); + body.put("type", "MERCHANT_ID"); + body.put("account", merchantNumber); + body.put("amount", amount); + body.put("description", "订单分账"); + JSONObject jsonObject = new JSONObject(body); + String jsonString = jsonObject.toString(); + map.put("receiver",jsonString); + String s = this.weixinSignature(map); + map.put("sign", s); + String url = "https://api.mch.weixin.qq.com/secapi/pay/profitsharing"; + //设置请求头 + HttpHeaders headers = new HttpHeaders(); + headers.setContentType(MediaType.APPLICATION_XML); + StringBuffer xmlString = new StringBuffer(); + Set<String> strings = map.keySet(); + String[] keys = {}; + keys = strings.toArray(keys); + Arrays.sort(keys); + xmlString.append("<xml>"); + for (int l = 0; l < keys.length; l++) { + xmlString.append("<" + keys[l] + ">" + map.get(keys[l]) + "</" + keys[l] + ">"); + } + xmlString.append("</xml>"); + + Map<String, String> map1 = null; + String body1 = null; + try { + body1 = HttpClientUtil.pushHttpsRequsetXml(url, xmlString.toString(), new HashMap<>(), mchId, certPath, "PKCS12"); + } catch (Exception e) { + e.printStackTrace(); + } + System.err.println("分账请求"+body1); + //将结果xml解析成map + body1 = body1.replaceAll("<!\\[CDATA\\[", ""); + body1 = body1.replaceAll("]]>", ""); + try { + map1 = this.xmlToMap(body1, "UTF-8"); + } catch (UnsupportedEncodingException e) { + e.printStackTrace(); + } catch (DocumentException e) { + e.printStackTrace(); + } + String return_code = map1.get("return_code"); + if ("SUCCESS".equals(return_code)) { + String result_code = map1.get("result_code"); + if ("SUCCESS".equals(result_code)) { + return ResultUtil.success(); + } else { +// System.err.println(map1.get("err_code_des")); + return ResultUtil.error(map1.get("err_code_des")); + } + } else { +// System.err.println(map1.get("return_msg") + appid + "----" + mchId); + return ResultUtil.error(map1.get("return_msg"), new JSONObject()); + } + } /** * 支付宝支付 @@ -300,7 +373,47 @@ return ResultUtil.error("出现问题啦"); } } - + // 资金冻结 做分账处理 + public ResultUtil confirm1(String smid,String code, String outTradeNo, String amount) { + AlipayClient alipayClient = new DefaultAlipayClient("https://openapi.alipay.com/gateway.do", + aliAppid, + appPrivateKey, + "json", + "GBK", + alipay_public_key, + "RSA2"); + AlipayTradeSettleConfirmRequest request = new AlipayTradeSettleConfirmRequest(); + request.setBizContent("{" + + " \"out_request_no\":\""+code+"\"," + + " \"trade_no\":\""+outTradeNo+"\"," + + " \"settle_info\":{" + + " \"settle_detail_infos\":[" + + " {" + + " \"trans_in_type\":\"defaultSettle\"," + + " \"settle_entity_id\":\""+smid+"\"," + + " \"settle_entity_type\":\"SecondMerchant\"," + + " \"amount\":"+amount+"," + + " }" + + " ]" + + " }," + + " \"extend_params\":{" + + " \"royalty_freeze\":\"true\"" + + " }" + + "}"); + AlipayTradeSettleConfirmResponse response = null; + try { + response = alipayClient.execute(request); + } catch (AlipayApiException e) { + e.printStackTrace(); + } + if(response.isSuccess()){ + System.out.println("调用成功"); + return ResultUtil.success(); + } else { + System.out.println("调用失败"); + return ResultUtil.error("出现问题啦"); + } + } /** * 支付成功后的回调处理逻辑 * @@ -412,7 +525,17 @@ map.put("appid", appid); map.put("mch_id", mchId); map.put("nonce_str", nonce_str); - map.put("body", body); + String temp = ""; + if (body.split("-").length>1){ + temp = body.split("-")[1]; + map.put("body", body.split("-")[0]); + }else{ + map.put("body", body); + } + if (StringUtils.hasLength(temp) && temp.equals("1")){ + // 添加分账标识 + map.put("profit_sharing", "Y"); + } map.put("attach", attach);//存储订单id map.put("out_trade_no", out_trade_no);//存储的订单code map.put("total_fee", i); diff --git a/cloud-server-activity/src/main/java/com/dsh/activity/entity/PointsMerchandise.java b/cloud-server-activity/src/main/java/com/dsh/activity/entity/PointsMerchandise.java index 6b30671..3d7cd93 100644 --- a/cloud-server-activity/src/main/java/com/dsh/activity/entity/PointsMerchandise.java +++ b/cloud-server-activity/src/main/java/com/dsh/activity/entity/PointsMerchandise.java @@ -175,7 +175,12 @@ // 已兑换数量 @TableField(exist = false) private Integer pickUpQuantity4; - + // 添加人id 判断是平台添加还是运营商添加 用于判断分账 + @TableField("addUserId") + private Integer addUserId; + // 添加人类型 1平台2运营商3门店 用于判断分账 + @TableField("addType") + private Integer addType; @Override protected Serializable pkVal() { return this.id; diff --git a/cloud-server-competition/src/main/java/com/dsh/competition/controller/CompetitionController.java b/cloud-server-competition/src/main/java/com/dsh/competition/controller/CompetitionController.java index 82f7bde..db27a44 100644 --- a/cloud-server-competition/src/main/java/com/dsh/competition/controller/CompetitionController.java +++ b/cloud-server-competition/src/main/java/com/dsh/competition/controller/CompetitionController.java @@ -25,16 +25,14 @@ import com.dsh.competition.service.IParticipantService; import com.dsh.competition.service.IPaymentCompetitionService; import com.dsh.competition.service.UserCompetitionService; -import com.dsh.competition.util.PayMoneyUtil; -import com.dsh.competition.util.ResultUtil; -import com.dsh.competition.util.TokenUtil; -import com.dsh.competition.util.ToolUtil; +import com.dsh.competition.util.*; import io.swagger.annotations.ApiImplicitParam; import io.swagger.annotations.ApiImplicitParams; import io.swagger.annotations.ApiOperation; import lombok.Synchronized; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.util.StringUtils; import org.springframework.web.bind.annotation.*; import javax.annotation.Resource; @@ -42,6 +40,7 @@ import javax.servlet.http.HttpServletResponse; import java.io.OutputStream; import java.io.PrintWriter; +import java.math.BigDecimal; import java.text.DateFormat; import java.text.SimpleDateFormat; import java.util.*; @@ -804,6 +803,29 @@ String payOrderNo = paymentCompetition.getPayOrderNo(); if (paymentCompetition.getPayType() == 1) {//微信支付 + if (StringUtils.hasLength(paymentCompetition.getFenzhangNo())){ + // 是分账订单 如果分账金额不为0 那么回退分账金额 + if (paymentCompetition.getFenzhangAmount()!=null && paymentCompetition.getFenzhangAmount().compareTo(BigDecimal.ZERO)>0){ + String randomCode = UUIDUtil.getRandomCode(16); + String randomCode1 = UUIDUtil.getRandomCode(16); + if (competition.getOperatorId()!=null && competition.getOperatorId()!=0){ + // 微信商户号 + String s2 =storeClient.getmerchantNumberByOperatorId(competition.getOperatorId()); + ResultUtil resultUtil = payMoneyUtil.fenzhangRefund(paymentCompetition.getFenzhangNo(), paymentCompetition.getFenzhangAmount(), s2, randomCode, randomCode1); + if (!resultUtil.getCode().equals(500)){ + System.err.println("分账回退失败 原因是:"+resultUtil.getMsg()); + }else{ + paymentCompetition.setFenzhangRefundNo(resultUtil.getMsg()); + paymentCompetitionService.updateById(paymentCompetition); + } + + } + } + } + + + + Map<String, String> map = payMoneyUtil.wxRefund(payOrderNo, code, amount.toString(), amount.toString(), "/base/competition/weChatCancelPaymentCompetitionCallback"); String return_code = map.get("return_code"); diff --git a/cloud-server-competition/src/main/java/com/dsh/competition/entity/PaymentCompetition.java b/cloud-server-competition/src/main/java/com/dsh/competition/entity/PaymentCompetition.java index 6b4a225..8498834 100644 --- a/cloud-server-competition/src/main/java/com/dsh/competition/entity/PaymentCompetition.java +++ b/cloud-server-competition/src/main/java/com/dsh/competition/entity/PaymentCompetition.java @@ -7,6 +7,7 @@ import com.fasterxml.jackson.annotation.JsonFormat; import lombok.Data; +import java.math.BigDecimal; import java.util.Date; /** @@ -62,6 +63,26 @@ @TableField("payOrderNo") private String payOrderNo; /** + * 分账流水号 + */ + @TableField("fenzhangNo") + private String fenzhangNo; + /** + * 分账业务号 存值表明已分账 未存表明未分账 + */ + @TableField("fenzhangOrderNo") + private String fenzhangOrderNo; + /** + * 分账金额 + */ + @TableField("fenzhangAmount") + private BigDecimal fenzhangAmount; + /** + * 分账回退流水号 + */ + @TableField("fenzhangRefundNo") + private String fenzhangRefundNo; + /** * 退款时间 */ @TableField("refundTime") @@ -71,6 +92,7 @@ */ @TableField("refundOrderNo") private String refundOrderNo; + /** * 状态(1=正常,2=冻结,3=删除) */ diff --git a/cloud-server-competition/src/main/java/com/dsh/competition/feignclient/other/StoreClient.java b/cloud-server-competition/src/main/java/com/dsh/competition/feignclient/other/StoreClient.java index 9e9a07d..8fe6d08 100644 --- a/cloud-server-competition/src/main/java/com/dsh/competition/feignclient/other/StoreClient.java +++ b/cloud-server-competition/src/main/java/com/dsh/competition/feignclient/other/StoreClient.java @@ -14,12 +14,20 @@ @FeignClient("mb-cloud-other") public interface StoreClient { /** + * 根据运营商id获取对应运营商分账比例 返回格式: 微信分账比例,支付宝分账比例 + * @return + */ + @PostMapping("/base/getProportionByOperatorId") + String getProportionByOperatorId(Integer id); + /** * 根据运营商id获取对应运营商商户号 * @return */ @PostMapping("/base/getSMIDByOperatorId") String getSMIDByOperatorId(Integer id); - + // 根据运营商id获取微信商户号 + @PostMapping("/base/getmerchantNumberByOperatorId") + String getmerchantNumberByOperatorId(Integer id); /** * 根据名称模糊搜索门店 * diff --git a/cloud-server-competition/src/main/java/com/dsh/competition/service/impl/CompetitionServiceImpl.java b/cloud-server-competition/src/main/java/com/dsh/competition/service/impl/CompetitionServiceImpl.java index 9159174..413b0f5 100644 --- a/cloud-server-competition/src/main/java/com/dsh/competition/service/impl/CompetitionServiceImpl.java +++ b/cloud-server-competition/src/main/java/com/dsh/competition/service/impl/CompetitionServiceImpl.java @@ -297,20 +297,26 @@ userCompetitionService.save(userCompetition); } if (paymentCompetitionVo.getPayType() == 1) {//微信 - return weChatPaymentCompetition(code, money); + Competition byId = competitionService.getById(paymentCompetitionVo.getId()); + Integer operatorId = byId.getOperatorId(); + int temp = 0; + if (operatorId!=null && operatorId != 0){ + temp =1; + } + return weChatPaymentCompetition(code, money,temp,operatorId); } if (paymentCompetitionVo.getPayType() == 2) {//支付宝 // 判断当前赛事属于哪个运营商 Competition byId = competitionService.getById(paymentCompetitionVo.getId()); Integer operatorId = byId.getOperatorId(); - if (operatorId == null ){ + if (operatorId == null || operatorId == 0 ){ // 说明是平台 - return aliPaymentCompetition(smid,code, money); + return aliPaymentCompetition(operatorId,smid,code, money); } // 获取该运营商的商户号 String smid = storeClient.getSMIDByOperatorId(operatorId); - return aliPaymentCompetition(smid,code, money); + return aliPaymentCompetition(operatorId,smid,code, money); } if (paymentCompetitionVo.getPayType() == 3) {//玩湃币 appUser.setPlayPaiCoins(appUser.getPlayPaiCoins() - money.intValue()); @@ -365,8 +371,8 @@ * @return * @throws Exception */ - public ResultUtil weChatPaymentCompetition(String code, BigDecimal money) throws Exception { - ResultUtil weixinpay = payMoneyUtil.weixinpay("报名赛事", "", code, money.toString(), + public ResultUtil weChatPaymentCompetition(String code, BigDecimal money,Integer isFenZhang,Integer operatorId) throws Exception { + ResultUtil weixinpay = payMoneyUtil.weixinpay("报名赛事"+"-"+isFenZhang, "", code, money.toString(), "/base/competition/weChatPaymentCompetitionCallback", "APP", ""); if (weixinpay.getCode() == 200) { new Thread(new Runnable() { @@ -414,6 +420,31 @@ Competition competition = cttService.getById(paymentCompetition.getCompetitionId()); competition.setApplicantsNumber(competition.getApplicantsNumber() + 1); cttService.updateById(competition); + if (operatorId!=null && operatorId!=0){ + // 休眠两分钟后再调用分账接口 避免提示订单正在处理中 + Thread.sleep(120000); + // 根据运营商id获取对应运营商分账比例 返回格式: 微信分账比例,支付宝分账比例 + String proportionByOperatorId = storeClient.getProportionByOperatorId(operatorId); + String[] split = proportionByOperatorId.split(","); + String s1 = split[0]; + if (!s1.equals("未设置")){ + BigDecimal bigDecimal = new BigDecimal(s1); + // 分账比例 + BigDecimal bigDecimal1 = bigDecimal.divide(new BigDecimal(100)).setScale(2); + // 微信商户号 + String s2 = storeClient.getmerchantNumberByOperatorId(operatorId); + String nonce_str = UUIDUtil.getRandomCode(16); + paymentCompetition.setFenzhangOrderNo(nonce_str); + ResultUtil fenzhang = payMoneyUtil.fenzhang(transaction_id, money.multiply(bigDecimal1), s2,nonce_str); + if (!fenzhang.getCode().equals(500)){ + System.err.println("分账失败 原因是:"+fenzhang.getMsg()); + }else{ + paymentCompetition.setFenzhangNo(fenzhang.getMsg()); + paymentCompetition.setFenzhangAmount(money.multiply(bigDecimal1)); + paymentCompetitionService.updateById(paymentCompetition); + } + } + } break; } if ("USERPAYING".equals(s) || "NOTPAY".equals(s)) { @@ -439,7 +470,7 @@ * @return * @throws Exception */ - public ResultUtil aliPaymentCompetition(String smid,String code, BigDecimal money) throws Exception { + public ResultUtil aliPaymentCompetition(Integer operatorId,String smid,String code, BigDecimal money) throws Exception { ResultUtil alipay = payMoneyUtil.alipay (smid,"报名赛事", "", "", code, money.toString(), "/base/competition/aliPaymentCompetitionCallback"); if (alipay.getCode() == 200) { @@ -491,6 +522,16 @@ // 结算资金到商户账号 payMoneyUtil.confirm(smid,code,tradeNo,money.toString()); + if (operatorId == null || operatorId == 0){ + // 属于平台的赛事 资金不做冻结 不做分账处理 + payMoneyUtil.confirm1(smid,code,tradeNo,money.toString()); + }else{ + // 资金冻结 + payMoneyUtil.confirm(smid,code,tradeNo,money.toString()); + // 分账处理 + extracted(operatorId, money, tradeNo); + } + // 结算资金到商户账号 //分账 // moneyOut(tradeNo, tradeNo,code); break; @@ -508,7 +549,52 @@ } return alipay; } - + private void extracted(Integer operatorId, BigDecimal money, String tradeNo) throws Exception { + // 分账 + AlipayClient alipayClient = new DefaultAlipayClient("https://openapi.alipay.com/gateway.do", + "2021004105665036", + "MIIEvwIBADANBgkqhkiG9w0BAQEFAASCBKkwggSlAgEAAoIBAQCi5i9nW/hGLJ3A06cZxTQdviFC7THpdSihoTYGLr9q006hu0V26ecBMY/o4w5bvIX0Ok/yofmZsVcCJpAPvbXL/uqVrIjnRRxXiaeBFThlxoBUTdunvbUSDYfzlEhJr5NvUKI6H6lz2niXlQGx4qy8Hau4ccWit9kM8jwUvsBVQoFgJA+xrjMvooA7YLopQtpOD+UJr5thApTSf1xrnr1W12yolTLEH15JmNV372cqXrYUuqnY0QsaPtxeqJUGAOcGdVLllQ7easEznP8DFBvDdHATcmp2SHNQDUEWN6MCVPbMgY06NQVqAXxqjTAYSVh+6TRu6bofPmpYC3TZB003AgMBAAECggEBAJAcR2+PA3NBYUYHeFrqBRMS8uX8ZR19kjZ7IgoSLTFaQsP9opRylPSPXhrPVBKAE5leRQAHn4MCSlESwHvMfxo7KFjFTFAc6dffZZpipYQUOc9bGampwJh58/3e/pyBgVMG6J23CPf/HJQtNFSkjd/V9+ayb/9l2dUEL3bC0fAZ/dbx8HsxdLw8wn3fLlWLj68hOMqa2deCZe3JdSVsPbeWqkh56FFsMLug0Nd+Ar4TgRl9/jnhXF0JWiD0LmPUYLhboY7EfUBzN4w1iYbDi1P+3zvoOYsiVKAXox9GMhQ2VzOO2UcSTuizSza2e98mGpabl/GpKmCz+RDFjtkX6eECgYEA2MyCij65eO3aGIm3FUe93DULRBYTfX8qJQSJq2WOWA3mmQlEW6L3O2B5/lG2h+8WmN6iLEs9eHpgycGYp7vAqgrANEn16ACVcuyx0scFtrZfZ+kmHMzFfiUWxJjVYk/6YngsGVBLdw6ueM42C8TTP67X9tU5TdVGoGWuqEj4W98CgYEAwFqwprXOch5Pqk/RPbb49r0Ou03K/UbciWnWWKzUhFFNS8MdlQPoDvQZbMwHLeWsa2VhaKITK3x5biLQb3U+0GLOn6lTvEyrEUH+ucREyLgVYTRAvwBPtnvlrzpyxPk2HnslQjju8WrvvLLBMKWUjlTrTOzhaHT21gz3pHMiOakCgYEAhLmfaXdBITGshb054sNLDtdCkGpbgEcrzAHdLps769iGxkYQHXHFngpQZUwtTUcoNGqIKknd1jZFrv7gsD+XkgKG7PwimehRlkwmCX5ilxtLiVgJRzRt6+5U5AMVD90a0tHzXYP0z2yjj73fBJF5KtGl0a10KZxaYrQdm1UhB00CgYBZZgzx/k9rtHC8LAqIj1CYhHejT92G53c6Gkl3vyOqN4sgKhfGmSEySfrDGPRBPZxr8ZtbIPCd5mUdberH0osWGMYFaJI1UsCy7aQwvGpniz7MhZeN7dweaOjwDs8mgtjHQ96mL4XGCDhR0BZ/wIURvZ/6iaGdhbbu9unlsWj3uQKBgQCmZYdsbbZkd3ev6f8rwyvMz+DrCQyYpY44cegBYuJgrZiQnL2fJioeN7ixX0UM48SfwsZEIrzshP/LGAwnc2MdjxKUl4jLN8SEe0NAjXOnz9Zaw740+aOmLpXcLWdP4uM2gIhWsvW1tEkQZCXmm7c9s/RsU8Pmzv+YL3+fSijOzA==", + "json", "GBK", + "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAmu8n/4yTHWbn7VOrNc9OsLtDL1bEQ8gC1dHkj8Wy5z0mkaOsjJRIG/28ze12M0V8jdCKuuDr5Z1OPKiqf+XO3ypguEh+mYUVMBM/cZodDFQfTY1TKLWjvQCuaqlA+QUTCK6f7T7stsgyQ1o9Jj0rXZDz6PM4QHSTzjrLIBaeqM5WIBvH+fy/X+QG5Utd+/UT0kc0JyvuKhZ65yVUd/C9VcwJJAPliRsAQNrqYterwAJ9zvw9tF11wj9W0XgJ8Ccu4x3gR1vrlLRJJo/OA97RmxPQ+5hSacWQZCUd1dwiBq+YCrKVHGTj14izRHXrLc0yBlRXo7tBOIqcy3IsvKVthQIDAQAB", + "RSA2"); + AlipayTradeOrderSettleRequest request = new AlipayTradeOrderSettleRequest(); + String randomCode = UUIDUtil.getRandomCode(16); + String proportionByOperatorId = storeClient.getProportionByOperatorId(operatorId); + // 支付宝分账比例 + String s1 = proportionByOperatorId.split(",")[1]; + double i = Double.parseDouble(s1); + double v = i * 0.01; + BigDecimal bigDecimal1 = new BigDecimal(String.valueOf(v)); + BigDecimal cashPayment = money; + // 分账金额 + BigDecimal bigDecimal2 = cashPayment.multiply(bigDecimal1).setScale(2, RoundingMode.DOWN); + request.setBizContent("{" + + " \"out_request_no\":\"" + randomCode + "\"," + + " \"trade_no\":\"" + tradeNo + "\"," + + " \"royalty_parameters\":[" + + " {" + + " \"royalty_type\":\"transfer\"," + + " \"trans_out\":\"" + storeClient.getSMIDByOperatorId(operatorId) + "\"," + + " \"trans_out_type\":\"userId\"," + + " \"trans_in_type\":\"userId\"," + + " \"trans_in\":\"" + smid + "\"," + + " \"amount\":" + bigDecimal2 + "," + + " \"desc\":\"平台服务费\"," + + " \"royalty_scene\":\"平台服务费\"," + + " }" + + " ]," + + " \"extend_params\":{" + + " \"royalty_finish\":\"true\"" + + " }," + + " \"royalty_mode\":\"async\"" + + "}"); + AlipayTradeOrderSettleResponse response = alipayClient.execute(request); + if (response.isSuccess()) { + System.out.println("调用成功"); + } else { + System.out.println("调用失败"); + } + } // @Autowired //private IPaymentCompetitionService paymentCompetitionService; diff --git a/cloud-server-competition/src/main/java/com/dsh/competition/service/impl/PaymentCompetitionServiceImpl.java b/cloud-server-competition/src/main/java/com/dsh/competition/service/impl/PaymentCompetitionServiceImpl.java index 60b0405..1b12afa 100644 --- a/cloud-server-competition/src/main/java/com/dsh/competition/service/impl/PaymentCompetitionServiceImpl.java +++ b/cloud-server-competition/src/main/java/com/dsh/competition/service/impl/PaymentCompetitionServiceImpl.java @@ -48,6 +48,7 @@ @Resource private StoreClient storeClient; + @Autowired private UserCompetitionService userCompetitionService; @@ -248,6 +249,25 @@ String payOrderNo = paymentCompetition.getPayOrderNo(); if (paymentCompetition.getPayType() == 1) {//微信支付 + if (StringUtils.hasLength(paymentCompetition.getFenzhangNo())){ + // 是分账订单 如果分账金额不为0 那么回退分账金额 + if (paymentCompetition.getFenzhangAmount()!=null && paymentCompetition.getFenzhangAmount().compareTo(BigDecimal.ZERO)>0){ + String randomCode = UUIDUtil.getRandomCode(16); + String randomCode1 = UUIDUtil.getRandomCode(16); + if (competition.getOperatorId()!=null && competition.getOperatorId()!=0){ + // 微信商户号 + String s2 =storeClient.getmerchantNumberByOperatorId(competition.getOperatorId()); + ResultUtil resultUtil = payMoneyUtil.fenzhangRefund(paymentCompetition.getFenzhangNo(), paymentCompetition.getFenzhangAmount(), s2, randomCode, randomCode1); + if (!resultUtil.getCode().equals(500)){ + System.err.println("分账回退失败 原因是:"+resultUtil.getMsg()); + }else{ + paymentCompetition.setFenzhangRefundNo(resultUtil.getMsg()); + paymentCompetitionMapper.updateById(paymentCompetition); + } + + } + } + } Map<String, String> map = payMoneyUtil.wxRefund(payOrderNo, code, amount.toString(), amount.toString(), "/base/competition/weChatCancelPaymentCompetitionCallback"); String return_code = map.get("return_code"); diff --git a/cloud-server-competition/src/main/java/com/dsh/competition/util/PayMoneyUtil.java b/cloud-server-competition/src/main/java/com/dsh/competition/util/PayMoneyUtil.java index e53be28..ec1574d 100644 --- a/cloud-server-competition/src/main/java/com/dsh/competition/util/PayMoneyUtil.java +++ b/cloud-server-competition/src/main/java/com/dsh/competition/util/PayMoneyUtil.java @@ -19,6 +19,7 @@ import org.springframework.http.HttpHeaders; import org.springframework.http.MediaType; import org.springframework.stereotype.Component; +import org.springframework.util.StringUtils; import javax.crypto.BadPaddingException; import javax.crypto.Cipher; @@ -320,6 +321,47 @@ " ]" + " }," + " \"extend_params\":{" + + " \"royalty_freeze\":\"true\"" + + " }" + + "}"); + AlipayTradeSettleConfirmResponse response = null; + try { + response = alipayClient.execute(request); + } catch (AlipayApiException e) { + e.printStackTrace(); + } + if(response.isSuccess()){ + System.out.println("调用成功"); + return ResultUtil.success(); + } else { + System.out.println("调用失败"); + return ResultUtil.error("出现问题啦"); + } + } + // 属于平台的运营商 因为无需分账不冻结资金 + public ResultUtil confirm1(String smid,String code, String outTradeNo, String amount) { + AlipayClient alipayClient = new DefaultAlipayClient("https://openapi.alipay.com/gateway.do", + aliAppid, + appPrivateKey, + "json", + "GBK", + alipay_public_key, + "RSA2"); + AlipayTradeSettleConfirmRequest request = new AlipayTradeSettleConfirmRequest(); + request.setBizContent("{" + + " \"out_request_no\":\""+code+"\"," + + " \"trade_no\":\""+outTradeNo+"\"," + + " \"settle_info\":{" + + " \"settle_detail_infos\":[" + + " {" + + " \"trans_in_type\":\"defaultSettle\"," + + " \"settle_entity_id\":\""+smid+"\"," + + " \"settle_entity_type\":\"SecondMerchant\"," + + " \"amount\":"+amount+"," + + " }" + + " ]" + + " }," + + " \"extend_params\":{" + " \"royalty_freeze\":\"false\"" + " }" + "}"); @@ -337,7 +379,6 @@ return ResultUtil.error("出现问题啦"); } } - /** * 微信统一下单 * @@ -362,13 +403,24 @@ map.put("appid", appid); map.put("mch_id", mchId); map.put("nonce_str", nonce_str); - map.put("body", body); + String temp = ""; + if (body.split("-").length>1){ + temp = body.split("-")[1]; + map.put("body", body.split("-")[0]); + }else{ + map.put("body", body); + } + if (StringUtils.hasLength(temp) && temp.equals("1")){ + // 添加分账标识 + map.put("profit_sharing", "Y"); + } map.put("attach", attach);//存储订单id map.put("out_trade_no", out_trade_no);//存储的订单code map.put("total_fee", i); map.put("spbill_create_ip", hostAddress); map.put("notify_url", callbackPath + notify_url); map.put("trade_type", tradeType); + if ("JSAPI".equals(tradeType)) { map.put("openid", openId); } @@ -453,6 +505,76 @@ } } + /** + * 发起分账 + * @param order 微信订单号 + * @return + */ + public ResultUtil fenzhang(String order,BigDecimal amount,String merchantNumber,String nonceStr ) throws Exception { + Map<String, Object> map = new HashMap<>(); + map.put("mch_id", mchId); + map.put("appid", appid); + map.put("nonce_str", nonceStr); + map.put("transaction_id", order); + // 将这个字符串使用json格式拼接起来 + Map<String, Object> body = new HashMap<>(); + body.put("type", "MERCHANT_ID"); + body.put("account", merchantNumber); + body.put("amount", amount); + body.put("description", "订单分账"); + JSONObject jsonObject = new JSONObject(body); + String jsonString = jsonObject.toString(); + map.put("receiver",jsonString); + String s = this.weixinSignature(map); + map.put("sign", s); + String url = "https://api.mch.weixin.qq.com/secapi/pay/profitsharing"; + //设置请求头 + HttpHeaders headers = new HttpHeaders(); + headers.setContentType(MediaType.APPLICATION_XML); + StringBuffer xmlString = new StringBuffer(); + Set<String> strings = map.keySet(); + String[] keys = {}; + keys = strings.toArray(keys); + Arrays.sort(keys); + xmlString.append("<xml>"); + for (int l = 0; l < keys.length; l++) { + xmlString.append("<" + keys[l] + ">" + map.get(keys[l]) + "</" + keys[l] + ">"); + } + xmlString.append("</xml>"); + + Map<String, String> map1 = null; + String body1 = null; + try { + body1 = HttpClientUtil.pushHttpsRequsetXml(url, xmlString.toString(), new HashMap<>(), mchId, certPath, "PKCS12"); + } catch (Exception e) { + e.printStackTrace(); + } + System.err.println("分账请求"+body1); + //将结果xml解析成map + body1 = body1.replaceAll("<!\\[CDATA\\[", ""); + body1 = body1.replaceAll("]]>", ""); + try { + map1 = this.xmlToMap(body1, "UTF-8"); + } catch (UnsupportedEncodingException e) { + e.printStackTrace(); + } catch (DocumentException e) { + e.printStackTrace(); + } + String return_code = map1.get("return_code"); + if ("SUCCESS".equals(return_code)) { + String result_code = map1.get("result_code"); + if ("SUCCESS".equals(result_code)) { + + return ResultUtil.success(map1.get("order_id")); + } else { +// System.err.println(map1.get("err_code_des")); + return ResultUtil.error(map1.get("err_code_des")); + } + } else { +// System.err.println(map1.get("return_msg") + appid + "----" + mchId); + return ResultUtil.error(map1.get("return_msg"), new JSONObject()); + } + } /** * 微信支付成功后的回调处理 @@ -694,7 +816,73 @@ return map2; } } + /** + * 发起分账回退 + * @param order 微信订单号 + * @return + */ + public ResultUtil fenzhangRefund(String order,BigDecimal amount,String merchantNumber, + String nonce_str, + String fenzhangRefundNo) throws Exception { + Map<String, Object> map = new HashMap<>(); + map.put("mch_id", mchId); + map.put("appid", appid); + map.put("nonce_str", nonce_str); + map.put("order_id", order); + map.put("out_return_no", fenzhangRefundNo); + map.put("return_account_type", "MERCHANT_ID"); + map.put("return_account", merchantNumber); + map.put("return_amount", amount); + map.put("description", "用户退款"); + String s = this.weixinSignature(map); + map.put("sign", s); + String url = "https://api.mch.weixin.qq.com/secapi/pay/profitsharingreturn"; + //设置请求头 + HttpHeaders headers = new HttpHeaders(); + headers.setContentType(MediaType.APPLICATION_XML); + StringBuffer xmlString = new StringBuffer(); + Set<String> strings = map.keySet(); + String[] keys = {}; + keys = strings.toArray(keys); + Arrays.sort(keys); + xmlString.append("<xml>"); + for (int l = 0; l < keys.length; l++) { + xmlString.append("<" + keys[l] + ">" + map.get(keys[l]) + "</" + keys[l] + ">"); + } + xmlString.append("</xml>"); + Map<String, String> map1 = null; + String body1 = null; + try { + body1 = HttpClientUtil.pushHttpsRequsetXml(url, xmlString.toString(), new HashMap<>(), mchId, certPath, "PKCS12"); + } catch (Exception e) { + e.printStackTrace(); + } + System.err.println("分账金额回退"+body1); + //将结果xml解析成map + body1 = body1.replaceAll("<!\\[CDATA\\[", ""); + body1 = body1.replaceAll("]]>", ""); + try { + map1 = this.xmlToMap(body1, "UTF-8"); + } catch (UnsupportedEncodingException e) { + e.printStackTrace(); + } catch (DocumentException e) { + e.printStackTrace(); + } + String return_code = map1.get("return_code"); + if ("SUCCESS".equals(return_code)) { + String result_code = map1.get("result_code"); + if ("SUCCESS".equals(result_code)) { + return ResultUtil.success(map1.get("return_no")); + } else { +// System.err.println(map1.get("err_code_des")); + return ResultUtil.error(map1.get("err_code_des")); + } + } else { +// System.err.println(map1.get("return_msg") + appid + "----" + mchId); + return ResultUtil.error(map1.get("return_msg"), new JSONObject()); + } + } /** * 微信退款成功后的回调处理 diff --git a/cloud-server-course/src/main/java/com/dsh/course/entity/CoursePackageOrder.java b/cloud-server-course/src/main/java/com/dsh/course/entity/CoursePackageOrder.java index 15072c0..9820879 100644 --- a/cloud-server-course/src/main/java/com/dsh/course/entity/CoursePackageOrder.java +++ b/cloud-server-course/src/main/java/com/dsh/course/entity/CoursePackageOrder.java @@ -120,7 +120,16 @@ */ @TableField("orderType") private Integer orderType; - + /** + * 分账流水号 + */ + @TableField("fenzhangNo") + private String fenzhangNo; + /** + * 分账业务号 存值表明已分账 未存表明未分账 + */ + @TableField("fenzhangOrderNo") + private String fenzhangOrderNo; @TableField(exist = false) private Integer type; } diff --git a/cloud-server-course/src/main/java/com/dsh/course/feignclient/other/StoreClient.java b/cloud-server-course/src/main/java/com/dsh/course/feignclient/other/StoreClient.java index 33df8b0..fb0e5d4 100644 --- a/cloud-server-course/src/main/java/com/dsh/course/feignclient/other/StoreClient.java +++ b/cloud-server-course/src/main/java/com/dsh/course/feignclient/other/StoreClient.java @@ -15,6 +15,12 @@ */ @FeignClient("mb-cloud-other") public interface StoreClient { + /** + * 根据运营商id获取对应运营商分账比例 返回格式: 微信分账比例,支付宝分账比例 + * @return + */ + @PostMapping("/base/getProportionByOperatorId") + String getProportionByOperatorId(Integer id); /** * 根据运营商id获取对应运营商商户号 @@ -22,6 +28,9 @@ */ @PostMapping("/base/getSMIDByOperatorId") String getSMIDByOperatorId(Integer id); + // 根据运营商id获取微信商户号 + @PostMapping("/base/getmerchantNumberByOperatorId") + String getmerchantNumberByOperatorId(Integer id); /** * 根据名称模糊搜索门店 * diff --git a/cloud-server-course/src/main/java/com/dsh/course/service/impl/TCoursePackagePaymentServiceImpl.java b/cloud-server-course/src/main/java/com/dsh/course/service/impl/TCoursePackagePaymentServiceImpl.java index 4a0b2a2..f842961 100644 --- a/cloud-server-course/src/main/java/com/dsh/course/service/impl/TCoursePackagePaymentServiceImpl.java +++ b/cloud-server-course/src/main/java/com/dsh/course/service/impl/TCoursePackagePaymentServiceImpl.java @@ -871,7 +871,7 @@ } } try { - return WeChatPayment(code, money); + return WeChatPayment(code, money,request.getLessonId()); } catch (Exception e) { return ResultUtil.runErr(); } @@ -902,9 +902,18 @@ return ResultUtil.success(); } - - public ResultUtil WeChatPayment(String code, BigDecimal request) throws Exception { - ResultUtil weixinpay = payMoneyUtil.weixinpay("课包续费", "", code, request.toString(), + public ResultUtil WeChatPayment(String code, BigDecimal request,Integer coursePackageId) throws Exception { + TCoursePackage byId = coursePackageService.getById(coursePackageId); + Integer storeId = byId.getStoreId(); + Store store = storeClient.queryStoreById(storeId); + // 是否分账 0否1是 + int isFenZhang= 1; + String merchantNumber = ""; + if (store.getOperatorId()==null || store.getOperatorId()==0){ + // 平台 + isFenZhang = 0; + } + ResultUtil weixinpay = payMoneyUtil.weixinpay("课包续费"+"-"+isFenZhang, "", code, request.toString(), "/base/coursePackage/wechatRegisteredCoursesCallback", "APP", ""); if (weixinpay.getCode() == 200) { String finalCode = code; @@ -955,6 +964,27 @@ .eq("classHours", coursePackageOrder1.getClassHours()) ); coursePackageService.addCoursePackageOrderStudent(coursePackageOrder1.getId(), coursePackagePaymentConfig); + if (store.getOperatorId()!=null && store.getOperatorId()!=0){ + // 休眠两分钟后再调用分账接口 避免提示订单正在处理中 + Thread.sleep(120000); + // 根据运营商id获取对应运营商分账比例 返回格式: 微信分账比例,支付宝分账比例 + String proportionByOperatorId = storeClient.getProportionByOperatorId(store.getOperatorId()); + String[] split = proportionByOperatorId.split(","); + String s1 = split[0]; + if (!s1.equals("未设置")){ + BigDecimal bigDecimal = new BigDecimal(s1); + // 分账比例 + BigDecimal bigDecimal1 = bigDecimal.divide(new BigDecimal(100)).setScale(2); + // 微信商户号 + String s2 = storeClient.getmerchantNumberByOperatorId(store.getOperatorId()); + String nonce_str = UUIDUtil.getRandomCode(16); + + ResultUtil fenzhang = payMoneyUtil.fenzhang(transaction_id, request.multiply(bigDecimal1), s2,nonce_str); + if (!fenzhang.getCode().equals(500)){ + System.err.println("分账失败 原因是:"+fenzhang.getMsg()); + } + } + } break; } if ("USERPAYING".equals(s) || "NOTPAY".equals(s)) { @@ -972,7 +1002,23 @@ } private String smid = "2088330203191220";//平台支付宝商户号 + public static void main(String[] args) { + BigDecimal bigDecimal = new BigDecimal("100"); + + + String s = "1"; + double v = Double.parseDouble(s); + double v1 = v * 0.01; + + BigDecimal bigDecimal1 = new BigDecimal(String.valueOf(v1)); + BigDecimal multiply = bigDecimal1.multiply(bigDecimal); + System.err.println(v); + System.err.println(v1); + System.err.println(multiply); + } public ResultUtil AlipayPayment(String code, BigDecimal request) { + // 二级商户商户号 + String smidUser; TCoursePackagePaymentMapper baseMapper1 = this.baseMapper; TCoursePackagePayment coursePackagePayment = baseMapper1.getCoursePackagePaymentByCode(code); // 判断这个课包属于哪个门店 属于哪个运营商 根据运营商 id 获取对应的商户号 @@ -1033,13 +1079,17 @@ TCoursePackage byId = coursePackageService.getById(coursePackageId); Store store = storeClient.queryStoreById(byId.getStoreId()); if (store.getOperatorId() == null ){ - // 说明是平台的门店 - payMoneyUtil.confirm(smid,code,tradeNo,request.toString()); + // 说明是平台的门店 无需冻结资金 不走分账 + payMoneyUtil.confirm1(smid,code,tradeNo,request.toString()); }else if (store.getOperatorId() == 0){ - payMoneyUtil.confirm(smid,code,tradeNo,request.toString()); + // 说明是平台的门店 + payMoneyUtil.confirm1(smid,code,tradeNo,request.toString()); + // 发起分账 + extracted(store, coursePackageOrder1, tradeNo); }else{ - String smid = storeClient.getSMIDByOperatorId(store.getOperatorId()); - payMoneyUtil.confirm(smid,code,tradeNo,request.toString()); + payMoneyUtil.confirm(storeClient.getSMIDByOperatorId(store.getOperatorId()),code,tradeNo,request.toString()); + // 发起分账 + extracted(store, coursePackageOrder1, tradeNo); } break; } @@ -1057,6 +1107,53 @@ return alipay; } + private void extracted(Store store, CoursePackageOrder coursePackageOrder1, String tradeNo) throws Exception { + // 分账 + AlipayClient alipayClient = new DefaultAlipayClient("https://openapi.alipay.com/gateway.do", + "2021004105665036", + "MIIEvwIBADANBgkqhkiG9w0BAQEFAASCBKkwggSlAgEAAoIBAQCi5i9nW/hGLJ3A06cZxTQdviFC7THpdSihoTYGLr9q006hu0V26ecBMY/o4w5bvIX0Ok/yofmZsVcCJpAPvbXL/uqVrIjnRRxXiaeBFThlxoBUTdunvbUSDYfzlEhJr5NvUKI6H6lz2niXlQGx4qy8Hau4ccWit9kM8jwUvsBVQoFgJA+xrjMvooA7YLopQtpOD+UJr5thApTSf1xrnr1W12yolTLEH15JmNV372cqXrYUuqnY0QsaPtxeqJUGAOcGdVLllQ7easEznP8DFBvDdHATcmp2SHNQDUEWN6MCVPbMgY06NQVqAXxqjTAYSVh+6TRu6bofPmpYC3TZB003AgMBAAECggEBAJAcR2+PA3NBYUYHeFrqBRMS8uX8ZR19kjZ7IgoSLTFaQsP9opRylPSPXhrPVBKAE5leRQAHn4MCSlESwHvMfxo7KFjFTFAc6dffZZpipYQUOc9bGampwJh58/3e/pyBgVMG6J23CPf/HJQtNFSkjd/V9+ayb/9l2dUEL3bC0fAZ/dbx8HsxdLw8wn3fLlWLj68hOMqa2deCZe3JdSVsPbeWqkh56FFsMLug0Nd+Ar4TgRl9/jnhXF0JWiD0LmPUYLhboY7EfUBzN4w1iYbDi1P+3zvoOYsiVKAXox9GMhQ2VzOO2UcSTuizSza2e98mGpabl/GpKmCz+RDFjtkX6eECgYEA2MyCij65eO3aGIm3FUe93DULRBYTfX8qJQSJq2WOWA3mmQlEW6L3O2B5/lG2h+8WmN6iLEs9eHpgycGYp7vAqgrANEn16ACVcuyx0scFtrZfZ+kmHMzFfiUWxJjVYk/6YngsGVBLdw6ueM42C8TTP67X9tU5TdVGoGWuqEj4W98CgYEAwFqwprXOch5Pqk/RPbb49r0Ou03K/UbciWnWWKzUhFFNS8MdlQPoDvQZbMwHLeWsa2VhaKITK3x5biLQb3U+0GLOn6lTvEyrEUH+ucREyLgVYTRAvwBPtnvlrzpyxPk2HnslQjju8WrvvLLBMKWUjlTrTOzhaHT21gz3pHMiOakCgYEAhLmfaXdBITGshb054sNLDtdCkGpbgEcrzAHdLps769iGxkYQHXHFngpQZUwtTUcoNGqIKknd1jZFrv7gsD+XkgKG7PwimehRlkwmCX5ilxtLiVgJRzRt6+5U5AMVD90a0tHzXYP0z2yjj73fBJF5KtGl0a10KZxaYrQdm1UhB00CgYBZZgzx/k9rtHC8LAqIj1CYhHejT92G53c6Gkl3vyOqN4sgKhfGmSEySfrDGPRBPZxr8ZtbIPCd5mUdberH0osWGMYFaJI1UsCy7aQwvGpniz7MhZeN7dweaOjwDs8mgtjHQ96mL4XGCDhR0BZ/wIURvZ/6iaGdhbbu9unlsWj3uQKBgQCmZYdsbbZkd3ev6f8rwyvMz+DrCQyYpY44cegBYuJgrZiQnL2fJioeN7ixX0UM48SfwsZEIrzshP/LGAwnc2MdjxKUl4jLN8SEe0NAjXOnz9Zaw740+aOmLpXcLWdP4uM2gIhWsvW1tEkQZCXmm7c9s/RsU8Pmzv+YL3+fSijOzA==", + "json", "GBK", + "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAmu8n/4yTHWbn7VOrNc9OsLtDL1bEQ8gC1dHkj8Wy5z0mkaOsjJRIG/28ze12M0V8jdCKuuDr5Z1OPKiqf+XO3ypguEh+mYUVMBM/cZodDFQfTY1TKLWjvQCuaqlA+QUTCK6f7T7stsgyQ1o9Jj0rXZDz6PM4QHSTzjrLIBaeqM5WIBvH+fy/X+QG5Utd+/UT0kc0JyvuKhZ65yVUd/C9VcwJJAPliRsAQNrqYterwAJ9zvw9tF11wj9W0XgJ8Ccu4x3gR1vrlLRJJo/OA97RmxPQ+5hSacWQZCUd1dwiBq+YCrKVHGTj14izRHXrLc0yBlRXo7tBOIqcy3IsvKVthQIDAQAB", + "RSA2"); + AlipayTradeOrderSettleRequest request = new AlipayTradeOrderSettleRequest(); + String randomCode = UUIDUtil.getRandomCode(16); + String proportionByOperatorId = storeClient.getProportionByOperatorId(store.getOperatorId()); + // 支付宝分账比例 + String s1 = proportionByOperatorId.split(",")[1]; + double i = Double.parseDouble(s1); + double v = i * 0.01; + BigDecimal bigDecimal1 = new BigDecimal(String.valueOf(v)); + BigDecimal cashPayment = coursePackageOrder1.getCashPayment(); + // 分账金额 + BigDecimal bigDecimal2 = cashPayment.multiply(bigDecimal1).setScale(2, RoundingMode.DOWN); + request.setBizContent("{" + + " \"out_request_no\":\"" + randomCode + "\"," + + " \"trade_no\":\"" + tradeNo + "\"," + + " \"royalty_parameters\":[" + + " {" + + " \"royalty_type\":\"transfer\"," + + " \"trans_out\":\"" + storeClient.getSMIDByOperatorId(store.getOperatorId()) + "\"," + + " \"trans_out_type\":\"userId\"," + + " \"trans_in_type\":\"userId\"," + + " \"trans_in\":\"" + smid + "\"," + + " \"amount\":" + bigDecimal2 + "," + + " \"desc\":\"平台服务费\"," + + " \"royalty_scene\":\"平台服务费\"," + + " }" + + " ]," + + " \"extend_params\":{" + + " \"royalty_finish\":\"true\"" + + " }," + + " \"royalty_mode\":\"async\"" + + "}"); + AlipayTradeOrderSettleResponse response = alipayClient.execute(request); + if (response.isSuccess()) { + System.out.println("调用成功"); + } else { + System.out.println("调用失败"); + } + } + public ResultUtil PlaypaiGoldPayment(AppUser appUser, String code, Integer wpGold) { TCoursePackagePayment packagePayment = this.baseMapper.selectOne(new QueryWrapper<TCoursePackagePayment>() .eq("code", code)); diff --git a/cloud-server-course/src/main/java/com/dsh/course/service/impl/TCoursePackageServiceImpl.java b/cloud-server-course/src/main/java/com/dsh/course/service/impl/TCoursePackageServiceImpl.java index c4e2001..6a4790d 100644 --- a/cloud-server-course/src/main/java/com/dsh/course/service/impl/TCoursePackageServiceImpl.java +++ b/cloud-server-course/src/main/java/com/dsh/course/service/impl/TCoursePackageServiceImpl.java @@ -942,8 +942,16 @@ coursePackageOrder.setPayUserId(uid); coursePackageOrderService.updateById(coursePackageOrder); } - - ResultUtil weixinpay = payMoneyUtil.weixinpay("报名运动营", coursePackagePaymentConfig.getId().toString(), code, paymentPrice.toString(), + TCoursePackage byId = coursePackageService.getById(paymentCourseVo.getId()); + Integer storeId = byId.getStoreId(); + Store store = storeClient.queryStoreById(storeId); + // 是否分账 0否1是 + int isFenZhang= 1; + if (store.getOperatorId()==null || store.getOperatorId()==0){ + // 平台 + isFenZhang = 0; + } + ResultUtil weixinpay = payMoneyUtil.weixinpay("报名运动营"+"-"+isFenZhang, coursePackagePaymentConfig.getId().toString(), code, paymentPrice.toString(), "/base/course/weChatPaymentCourseCallback", "APP", ""); if (weixinpay.getCode() == 200) { String finalCode = code; @@ -989,7 +997,36 @@ coursePackageOrderService.updateById(coursePackageOrder1); //修改课时有效期 addCoursePackageOrderStudent(coursePackageOrder1.getId(), coursePackagePaymentConfig); + if (store.getOperatorId()!=null && store.getOperatorId()!=0){ + // 休眠两分钟后再调用分账接口 避免提示订单正在处理中 + Thread.sleep(120000); + // 根据运营商id获取对应运营商分账比例 返回格式: 微信分账比例,支付宝分账比例 + String proportionByOperatorId = storeClient.getProportionByOperatorId(store.getOperatorId()); + String[] split = proportionByOperatorId.split(","); + String s1 = split[0]; + if (!s1.equals("未设置")){ + BigDecimal bigDecimal = new BigDecimal(s1); + // 分账比例 + BigDecimal bigDecimal1 = bigDecimal.divide(new BigDecimal(100)).setScale(2); + // 微信商户号 + String s2 = storeClient.getmerchantNumberByOperatorId(store.getOperatorId()); + BigDecimal bigDecimal2 = new BigDecimal(paymentPrice); + String nonce_str = UUIDUtil.getRandomCode(16); + ResultUtil fenzhang = payMoneyUtil.fenzhang(transaction_id, bigDecimal2.multiply(bigDecimal1), s2,nonce_str); + if (!fenzhang.getCode().equals(500)){ + System.err.println("分账失败 原因是:"+fenzhang.getMsg()); + }else{ + coursePackageOrder1.setFenzhangNo(fenzhang.getMsg()); + coursePackageOrder1.setFenzhangOrderNo(nonce_str); + coursePackageOrderService.updateById(coursePackageOrder1); + } + } + } + + + break; + } if ("USERPAYING".equals(s) || "NOTPAY".equals(s)) { num++; @@ -1115,18 +1152,21 @@ Integer operatorId = store.getOperatorId(); if (operatorId==null){ String smid ="2088330203191220"; - // 说明是平台的 - payMoneyUtil.confirm(smid,finalCode,tradeNo,paymentPrice.toString()); + // 说明是平台的 不走分账 +// payMoneyUtil.confirm(smid,finalCode,tradeNo,paymentPrice.toString()); + payMoneyUtil.confirm1(smid,finalCode,tradeNo,paymentPrice.toString()); break; }else if (operatorId==0){ String smid ="2088330203191220"; // 说明是平台的 - payMoneyUtil.confirm(smid,finalCode,tradeNo,paymentPrice.toString()); + payMoneyUtil.confirm1(smid,finalCode,tradeNo,paymentPrice.toString()); break; }else{ // 当前课程不属于门店 查询这个课程属于哪个门店 属于哪个运营商 String smidByOperatorId = storeClient.getSMIDByOperatorId(operatorId); payMoneyUtil.confirm(smidByOperatorId,finalCode,tradeNo,paymentPrice.toString()); + // 分账处理 + extracted(store, coursePackageOrder1, tradeNo); break; } } @@ -1144,7 +1184,52 @@ return alipay; } - + private void extracted(Store store, CoursePackageOrder coursePackageOrder1, String tradeNo) throws Exception { + // 分账 + AlipayClient alipayClient = new DefaultAlipayClient("https://openapi.alipay.com/gateway.do", + "2021004105665036", + "MIIEvwIBADANBgkqhkiG9w0BAQEFAASCBKkwggSlAgEAAoIBAQCi5i9nW/hGLJ3A06cZxTQdviFC7THpdSihoTYGLr9q006hu0V26ecBMY/o4w5bvIX0Ok/yofmZsVcCJpAPvbXL/uqVrIjnRRxXiaeBFThlxoBUTdunvbUSDYfzlEhJr5NvUKI6H6lz2niXlQGx4qy8Hau4ccWit9kM8jwUvsBVQoFgJA+xrjMvooA7YLopQtpOD+UJr5thApTSf1xrnr1W12yolTLEH15JmNV372cqXrYUuqnY0QsaPtxeqJUGAOcGdVLllQ7easEznP8DFBvDdHATcmp2SHNQDUEWN6MCVPbMgY06NQVqAXxqjTAYSVh+6TRu6bofPmpYC3TZB003AgMBAAECggEBAJAcR2+PA3NBYUYHeFrqBRMS8uX8ZR19kjZ7IgoSLTFaQsP9opRylPSPXhrPVBKAE5leRQAHn4MCSlESwHvMfxo7KFjFTFAc6dffZZpipYQUOc9bGampwJh58/3e/pyBgVMG6J23CPf/HJQtNFSkjd/V9+ayb/9l2dUEL3bC0fAZ/dbx8HsxdLw8wn3fLlWLj68hOMqa2deCZe3JdSVsPbeWqkh56FFsMLug0Nd+Ar4TgRl9/jnhXF0JWiD0LmPUYLhboY7EfUBzN4w1iYbDi1P+3zvoOYsiVKAXox9GMhQ2VzOO2UcSTuizSza2e98mGpabl/GpKmCz+RDFjtkX6eECgYEA2MyCij65eO3aGIm3FUe93DULRBYTfX8qJQSJq2WOWA3mmQlEW6L3O2B5/lG2h+8WmN6iLEs9eHpgycGYp7vAqgrANEn16ACVcuyx0scFtrZfZ+kmHMzFfiUWxJjVYk/6YngsGVBLdw6ueM42C8TTP67X9tU5TdVGoGWuqEj4W98CgYEAwFqwprXOch5Pqk/RPbb49r0Ou03K/UbciWnWWKzUhFFNS8MdlQPoDvQZbMwHLeWsa2VhaKITK3x5biLQb3U+0GLOn6lTvEyrEUH+ucREyLgVYTRAvwBPtnvlrzpyxPk2HnslQjju8WrvvLLBMKWUjlTrTOzhaHT21gz3pHMiOakCgYEAhLmfaXdBITGshb054sNLDtdCkGpbgEcrzAHdLps769iGxkYQHXHFngpQZUwtTUcoNGqIKknd1jZFrv7gsD+XkgKG7PwimehRlkwmCX5ilxtLiVgJRzRt6+5U5AMVD90a0tHzXYP0z2yjj73fBJF5KtGl0a10KZxaYrQdm1UhB00CgYBZZgzx/k9rtHC8LAqIj1CYhHejT92G53c6Gkl3vyOqN4sgKhfGmSEySfrDGPRBPZxr8ZtbIPCd5mUdberH0osWGMYFaJI1UsCy7aQwvGpniz7MhZeN7dweaOjwDs8mgtjHQ96mL4XGCDhR0BZ/wIURvZ/6iaGdhbbu9unlsWj3uQKBgQCmZYdsbbZkd3ev6f8rwyvMz+DrCQyYpY44cegBYuJgrZiQnL2fJioeN7ixX0UM48SfwsZEIrzshP/LGAwnc2MdjxKUl4jLN8SEe0NAjXOnz9Zaw740+aOmLpXcLWdP4uM2gIhWsvW1tEkQZCXmm7c9s/RsU8Pmzv+YL3+fSijOzA==", + "json", "GBK", + "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAmu8n/4yTHWbn7VOrNc9OsLtDL1bEQ8gC1dHkj8Wy5z0mkaOsjJRIG/28ze12M0V8jdCKuuDr5Z1OPKiqf+XO3ypguEh+mYUVMBM/cZodDFQfTY1TKLWjvQCuaqlA+QUTCK6f7T7stsgyQ1o9Jj0rXZDz6PM4QHSTzjrLIBaeqM5WIBvH+fy/X+QG5Utd+/UT0kc0JyvuKhZ65yVUd/C9VcwJJAPliRsAQNrqYterwAJ9zvw9tF11wj9W0XgJ8Ccu4x3gR1vrlLRJJo/OA97RmxPQ+5hSacWQZCUd1dwiBq+YCrKVHGTj14izRHXrLc0yBlRXo7tBOIqcy3IsvKVthQIDAQAB", + "RSA2"); + AlipayTradeOrderSettleRequest request = new AlipayTradeOrderSettleRequest(); + String randomCode = UUIDUtil.getRandomCode(16); + String proportionByOperatorId = storeClient.getProportionByOperatorId(store.getOperatorId()); + // 支付宝分账比例 + String s1 = proportionByOperatorId.split(",")[1]; + double i = Double.parseDouble(s1); + double v = i * 0.01; + BigDecimal bigDecimal1 = new BigDecimal(String.valueOf(v)); + BigDecimal cashPayment = coursePackageOrder1.getCashPayment(); + // 分账金额 + BigDecimal bigDecimal2 = cashPayment.multiply(bigDecimal1).setScale(2, RoundingMode.DOWN); + request.setBizContent("{" + + " \"out_request_no\":\"" + randomCode + "\"," + + " \"trade_no\":\"" + tradeNo + "\"," + + " \"royalty_parameters\":[" + + " {" + + " \"royalty_type\":\"transfer\"," + + " \"trans_out\":\"" + storeClient.getSMIDByOperatorId(store.getOperatorId()) + "\"," + + " \"trans_out_type\":\"userId\"," + + " \"trans_in_type\":\"userId\"," + + " \"trans_in\":\"" + smid + "\"," + + " \"amount\":" + bigDecimal2 + "," + + " \"desc\":\"平台服务费\"," + + " \"royalty_scene\":\"平台服务费\"," + + " }" + + " ]," + + " \"extend_params\":{" + + " \"royalty_finish\":\"true\"" + + " }," + + " \"royalty_mode\":\"async\"" + + "}"); + AlipayTradeOrderSettleResponse response = alipayClient.execute(request); + if (response.isSuccess()) { + System.out.println("调用成功"); + } else { + System.out.println("调用失败"); + } + } //分账 public void moneyOut(String outNum, String tradeNo,String code) throws AlipayApiException { AlipayClient alipayClient = new DefaultAlipayClient("https://openapi.alipay.com/gateway.do", aliAppid, appPrivateKey, "json", "UTF-8", alipay_public_key, "RSA2"); diff --git a/cloud-server-course/src/main/java/com/dsh/course/util/PayMoneyUtil.java b/cloud-server-course/src/main/java/com/dsh/course/util/PayMoneyUtil.java index 742f9e5..8756908 100644 --- a/cloud-server-course/src/main/java/com/dsh/course/util/PayMoneyUtil.java +++ b/cloud-server-course/src/main/java/com/dsh/course/util/PayMoneyUtil.java @@ -20,6 +20,7 @@ import org.springframework.http.HttpHeaders; import org.springframework.http.MediaType; import org.springframework.stereotype.Component; +import org.springframework.util.StringUtils; import javax.crypto.BadPaddingException; import javax.crypto.Cipher; @@ -95,6 +96,47 @@ " }," + " \"extend_params\":{" + " \"royalty_freeze\":\"true\"" + + " }" + + "}"); + AlipayTradeSettleConfirmResponse response = null; + try { + response = alipayClient.execute(request); + } catch (AlipayApiException e) { + e.printStackTrace(); + } + if(response.isSuccess()){ + System.out.println("调用成功"); + return ResultUtil.success(); + } else { + System.out.println("调用失败"); + return ResultUtil.error("出现问题啦"); + } + } + // 属于平台的运营商 因为无需分账不冻结资金 + public ResultUtil confirm1(String smid,String code, String outTradeNo, String amount) { + AlipayClient alipayClient = new DefaultAlipayClient("https://openapi.alipay.com/gateway.do", + aliAppid, + appPrivateKey, + "json", + "GBK", + alipay_public_key, + "RSA2"); + AlipayTradeSettleConfirmRequest request = new AlipayTradeSettleConfirmRequest(); + request.setBizContent("{" + + " \"out_request_no\":\""+code+"\"," + + " \"trade_no\":\""+outTradeNo+"\"," + + " \"settle_info\":{" + + " \"settle_detail_infos\":[" + + " {" + + " \"trans_in_type\":\"defaultSettle\"," + + " \"settle_entity_id\":\""+smid+"\"," + + " \"settle_entity_type\":\"SecondMerchant\"," + + " \"amount\":"+amount+"," + + " }" + + " ]" + + " }," + + " \"extend_params\":{" + + " \"royalty_freeze\":\"false\"" + " }" + "}"); AlipayTradeSettleConfirmResponse response = null; @@ -353,7 +395,17 @@ map.put("appid", appid); map.put("mch_id", mchId); map.put("nonce_str", nonce_str); - map.put("body", body); + String temp = ""; + if (body.split("-").length>1){ + temp = body.split("-")[1]; + map.put("body", body.split("-")[0]); + }else{ + map.put("body", body); + } + if (StringUtils.hasLength(temp) && temp.equals("1")){ + // 添加分账标识 + map.put("profit_sharing", "Y"); + } map.put("attach", attach);//存储订单id map.put("out_trade_no", out_trade_no);//存储的订单code map.put("total_fee", i); @@ -443,7 +495,75 @@ return ResultUtil.error(map1.get("return_msg"), new JSONObject()); } } + /** + * 发起分账 + * @param order 微信订单号 + * @return + */ + public ResultUtil fenzhang(String order,BigDecimal amount,String merchantNumber,String nonceStr) throws Exception { + Map<String, Object> map = new HashMap<>(); + map.put("mch_id", mchId); + map.put("appid", appid); + map.put("nonce_str", nonceStr); + map.put("transaction_id", order); + // 将这个字符串使用json格式拼接起来 + Map<String, Object> body = new HashMap<>(); + body.put("type", "MERCHANT_ID"); + body.put("account", merchantNumber); + body.put("amount", amount); + body.put("description", "订单分账"); + JSONObject jsonObject = new JSONObject(body); + String jsonString = jsonObject.toString(); + map.put("receiver",jsonString); + String s = this.weixinSignature(map); + map.put("sign", s); + String url = "https://api.mch.weixin.qq.com/secapi/pay/profitsharing"; + //设置请求头 + HttpHeaders headers = new HttpHeaders(); + headers.setContentType(MediaType.APPLICATION_XML); + StringBuffer xmlString = new StringBuffer(); + Set<String> strings = map.keySet(); + String[] keys = {}; + keys = strings.toArray(keys); + Arrays.sort(keys); + xmlString.append("<xml>"); + for (int l = 0; l < keys.length; l++) { + xmlString.append("<" + keys[l] + ">" + map.get(keys[l]) + "</" + keys[l] + ">"); + } + xmlString.append("</xml>"); + Map<String, String> map1 = null; + String body1 = null; + try { + body1 = HttpClientUtil.pushHttpsRequsetXml(url, xmlString.toString(), new HashMap<>(), mchId, certPath, "PKCS12"); + } catch (Exception e) { + e.printStackTrace(); + } + System.err.println("分账请求"+body1); + //将结果xml解析成map + body1 = body1.replaceAll("<!\\[CDATA\\[", ""); + body1 = body1.replaceAll("]]>", ""); + try { + map1 = this.xmlToMap(body1, "UTF-8"); + } catch (UnsupportedEncodingException e) { + e.printStackTrace(); + } catch (DocumentException e) { + e.printStackTrace(); + } + String return_code = map1.get("return_code"); + if ("SUCCESS".equals(return_code)) { + String result_code = map1.get("result_code"); + if ("SUCCESS".equals(result_code)) { + return ResultUtil.success(); + } else { +// System.err.println(map1.get("err_code_des")); + return ResultUtil.error(map1.get("err_code_des")); + } + } else { +// System.err.println(map1.get("return_msg") + appid + "----" + mchId); + return ResultUtil.error(map1.get("return_msg"), new JSONObject()); + } + } /** * 微信支付成功后的回调处理 diff --git a/cloud-server-management/pom.xml b/cloud-server-management/pom.xml index 8568baa..ba20e3f 100644 --- a/cloud-server-management/pom.xml +++ b/cloud-server-management/pom.xml @@ -14,6 +14,18 @@ <name>管理后台</name> <description>管理后台</description> <dependencies> + <!--微信商户认证图片上传--> + <dependency> + <groupId>com.github.wechatpay-apiv3</groupId> + <artifactId>wechatpay-java</artifactId> + <version>0.2.12</version> + </dependency> + <dependency> + <groupId>com.github.wechatpay-apiv3</groupId> + <artifactId>wechatpay-apache-httpclient</artifactId> + <version>0.4.9</version> + </dependency> + <dependency> <groupId>org.springframework</groupId> <artifactId>spring-test</artifactId> @@ -80,8 +92,8 @@ </dependency> <dependency> - <groupId>cn.mb.cloud</groupId> - <artifactId>mb-cloud-common-sentinel</artifactId> + <groupId>cn.mb.cloud</groupId> + <artifactId>mb-cloud-common-sentinel</artifactId> </dependency> <dependency> @@ -170,9 +182,9 @@ <classifier>jdk15</classifier> </dependency> <dependency> - <groupId>com.baomidou</groupId> - <artifactId>kaptcha-spring-boot-starter</artifactId> - <version>1.1.0</version> + <groupId>com.baomidou</groupId> + <artifactId>kaptcha-spring-boot-starter</artifactId> + <version>1.1.0</version> </dependency> <dependency> <groupId>io.jsonwebtoken</groupId> @@ -342,4 +354,4 @@ </repositories> -</project> +</project> \ No newline at end of file diff --git a/cloud-server-management/src/main/java/com/dsh/course/feignClient/activity/model/PointsMerchandise.java b/cloud-server-management/src/main/java/com/dsh/course/feignClient/activity/model/PointsMerchandise.java index 8b78abf..d52e25e 100644 --- a/cloud-server-management/src/main/java/com/dsh/course/feignClient/activity/model/PointsMerchandise.java +++ b/cloud-server-management/src/main/java/com/dsh/course/feignClient/activity/model/PointsMerchandise.java @@ -174,7 +174,12 @@ // 已兑换数量 @TableField(exist = false) private Integer pickUpQuantity4; - + @TableField("addUserId") + // 添加人id 判断是平台添加还是运营商添加 用于判断分账 + private Integer addUserId; + @TableField("addType") + // 添加人类型 1平台2运营商3门店 用于判断分账 + private Integer addType; @Override protected Serializable pkVal() { return this.id; diff --git a/cloud-server-management/src/main/java/com/dsh/course/mapper/CarInsuranceMapper.java b/cloud-server-management/src/main/java/com/dsh/course/mapper/CarInsuranceMapper.java index 3be0de9..4fb41a9 100644 --- a/cloud-server-management/src/main/java/com/dsh/course/mapper/CarInsuranceMapper.java +++ b/cloud-server-management/src/main/java/com/dsh/course/mapper/CarInsuranceMapper.java @@ -2,11 +2,13 @@ import com.baomidou.mybatisplus.core.mapper.BaseMapper; import com.dsh.guns.modular.system.model.CarInsurance; +import org.apache.ibatis.annotations.Mapper; import org.apache.ibatis.annotations.Param; import java.util.List; import java.util.Map; +@Mapper public interface CarInsuranceMapper extends BaseMapper<CarInsurance> { diff --git a/cloud-server-management/src/main/java/com/dsh/course/mapper/TOperatorAuthWxMapper.java b/cloud-server-management/src/main/java/com/dsh/course/mapper/TOperatorAuthWxMapper.java new file mode 100644 index 0000000..bb8dac4 --- /dev/null +++ b/cloud-server-management/src/main/java/com/dsh/course/mapper/TOperatorAuthWxMapper.java @@ -0,0 +1,20 @@ +package com.dsh.course.mapper; + + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.dsh.guns.modular.system.model.OperatorAuth; +import com.dsh.guns.modular.system.model.OperatorAuthAlipay; +import org.apache.ibatis.annotations.Mapper; + +/** + * <p> + * Mapper 接口 + * </p> + * + * @author administrator + * @since 2023-09-19 + */ +@Mapper +public interface TOperatorAuthWxMapper extends BaseMapper<OperatorAuth> { + +} diff --git a/cloud-server-management/src/main/java/com/dsh/guns/modular/system/controller/code/OperatorController.java b/cloud-server-management/src/main/java/com/dsh/guns/modular/system/controller/code/OperatorController.java index a881797..ca128ff 100644 --- a/cloud-server-management/src/main/java/com/dsh/guns/modular/system/controller/code/OperatorController.java +++ b/cloud-server-management/src/main/java/com/dsh/guns/modular/system/controller/code/OperatorController.java @@ -6,23 +6,19 @@ import com.alibaba.fastjson.JSONArray; import com.alibaba.fastjson.JSONObject; import com.alipay.api.*; -import com.alipay.api.request.AlipayMerchantIndirectAuthorderCreateRequest; -import com.alipay.api.request.AlipayMerchantIndirectAuthorderQuerystatusRequest; import com.alipay.api.request.AntMerchantExpandIndirectImageUploadRequest; import com.alipay.api.request.AntMerchantExpandIndirectZftCreateRequest; -import com.alipay.api.response.AlipayMerchantIndirectAuthorderCreateResponse; -import com.alipay.api.response.AlipayMerchantIndirectAuthorderQuerystatusResponse; import com.alipay.api.response.AntMerchantExpandIndirectImageUploadResponse; import com.alipay.api.response.AntMerchantExpandIndirectZftCreateResponse; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; -import com.dsh.course.feignClient.account.model.Coach; import com.dsh.guns.core.base.controller.BaseController; import com.dsh.guns.core.common.constant.factory.PageFactory; import com.dsh.guns.core.util.SinataUtil; import com.dsh.guns.modular.system.controller.util.MD5; +import com.dsh.guns.modular.system.controller.util.MD5AndKL; import com.dsh.guns.modular.system.model.*; import com.dsh.guns.modular.system.service.*; @@ -30,9 +26,12 @@ import com.dsh.guns.modular.system.util.PayMoneyUtil; import com.dsh.guns.modular.system.util.ResultUtil; -import com.github.binarywang.wxpay.service.BankService; -import com.mysql.cj.x.protobuf.MysqlxExpr; -import org.apache.poi.ss.formula.functions.T; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.github.binarywang.wxpay.v3.WechatPayUploadHttpPost; +import com.wechat.pay.java.service.profitsharing.ProfitsharingService; +import org.apache.commons.codec.digest.DigestUtils; +import org.apache.http.client.methods.HttpPost; +import org.springframework.beans.BeanUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Controller; import org.springframework.ui.Model; @@ -40,9 +39,20 @@ import org.springframework.web.bind.annotation.*; +import javax.crypto.BadPaddingException; +import javax.crypto.Cipher; +import javax.crypto.IllegalBlockSizeException; +import javax.crypto.NoSuchPaddingException; +import javax.security.cert.X509Certificate; +import java.io.*; +import java.net.URI; +import java.net.URISyntaxException; +import java.net.URL; +import java.security.InvalidKeyException; +import java.security.NoSuchAlgorithmException; +import java.time.LocalDateTime; +import java.time.format.DateTimeFormatter; import java.util.*; -import java.util.regex.Matcher; -import java.util.regex.Pattern; import java.util.stream.Collectors; @@ -61,6 +71,8 @@ @Autowired private IOperatorAuthService operatorAuthService; @Autowired + private IOperatorAuthWxService operatorAuthWxService; + @Autowired private IOperatorUserService operatorUserService; @Autowired private IUserService userService; @@ -74,6 +86,9 @@ private String appPrivateKey = "MIIEvwIBADANBgkqhkiG9w0BAQEFAASCBKkwggSlAgEAAoIBAQCi5i9nW/hGLJ3A06cZxTQdviFC7THpdSihoTYGLr9q006hu0V26ecBMY/o4w5bvIX0Ok/yofmZsVcCJpAPvbXL/uqVrIjnRRxXiaeBFThlxoBUTdunvbUSDYfzlEhJr5NvUKI6H6lz2niXlQGx4qy8Hau4ccWit9kM8jwUvsBVQoFgJA+xrjMvooA7YLopQtpOD+UJr5thApTSf1xrnr1W12yolTLEH15JmNV372cqXrYUuqnY0QsaPtxeqJUGAOcGdVLllQ7easEznP8DFBvDdHATcmp2SHNQDUEWN6MCVPbMgY06NQVqAXxqjTAYSVh+6TRu6bofPmpYC3TZB003AgMBAAECggEBAJAcR2+PA3NBYUYHeFrqBRMS8uX8ZR19kjZ7IgoSLTFaQsP9opRylPSPXhrPVBKAE5leRQAHn4MCSlESwHvMfxo7KFjFTFAc6dffZZpipYQUOc9bGampwJh58/3e/pyBgVMG6J23CPf/HJQtNFSkjd/V9+ayb/9l2dUEL3bC0fAZ/dbx8HsxdLw8wn3fLlWLj68hOMqa2deCZe3JdSVsPbeWqkh56FFsMLug0Nd+Ar4TgRl9/jnhXF0JWiD0LmPUYLhboY7EfUBzN4w1iYbDi1P+3zvoOYsiVKAXox9GMhQ2VzOO2UcSTuizSza2e98mGpabl/GpKmCz+RDFjtkX6eECgYEA2MyCij65eO3aGIm3FUe93DULRBYTfX8qJQSJq2WOWA3mmQlEW6L3O2B5/lG2h+8WmN6iLEs9eHpgycGYp7vAqgrANEn16ACVcuyx0scFtrZfZ+kmHMzFfiUWxJjVYk/6YngsGVBLdw6ueM42C8TTP67X9tU5TdVGoGWuqEj4W98CgYEAwFqwprXOch5Pqk/RPbb49r0Ou03K/UbciWnWWKzUhFFNS8MdlQPoDvQZbMwHLeWsa2VhaKITK3x5biLQb3U+0GLOn6lTvEyrEUH+ucREyLgVYTRAvwBPtnvlrzpyxPk2HnslQjju8WrvvLLBMKWUjlTrTOzhaHT21gz3pHMiOakCgYEAhLmfaXdBITGshb054sNLDtdCkGpbgEcrzAHdLps769iGxkYQHXHFngpQZUwtTUcoNGqIKknd1jZFrv7gsD+XkgKG7PwimehRlkwmCX5ilxtLiVgJRzRt6+5U5AMVD90a0tHzXYP0z2yjj73fBJF5KtGl0a10KZxaYrQdm1UhB00CgYBZZgzx/k9rtHC8LAqIj1CYhHejT92G53c6Gkl3vyOqN4sgKhfGmSEySfrDGPRBPZxr8ZtbIPCd5mUdberH0osWGMYFaJI1UsCy7aQwvGpniz7MhZeN7dweaOjwDs8mgtjHQ96mL4XGCDhR0BZ/wIURvZ/6iaGdhbbu9unlsWj3uQKBgQCmZYdsbbZkd3ev6f8rwyvMz+DrCQyYpY44cegBYuJgrZiQnL2fJioeN7ixX0UM48SfwsZEIrzshP/LGAwnc2MdjxKUl4jLN8SEe0NAjXOnz9Zaw740+aOmLpXcLWdP4uM2gIhWsvW1tEkQZCXmm7c9s/RsU8Pmzv+YL3+fSijOzA==";//支付宝开发者应用私钥 private String alipay_public_key = "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAmu8n/4yTHWbn7VOrNc9OsLtDL1bEQ8gC1dHkj8Wy5z0mkaOsjJRIG/28ze12M0V8jdCKuuDr5Z1OPKiqf+XO3ypguEh+mYUVMBM/cZodDFQfTY1TKLWjvQCuaqlA+QUTCK6f7T7stsgyQ1o9Jj0rXZDz6PM4QHSTzjrLIBaeqM5WIBvH+fy/X+QG5Utd+/UT0kc0JyvuKhZ65yVUd/C9VcwJJAPliRsAQNrqYterwAJ9zvw9tF11wj9W0XgJ8Ccu4x3gR1vrlLRJJo/OA97RmxPQ+5hSacWQZCUd1dwiBq+YCrKVHGTj14izRHXrLc0yBlRXo7tBOIqcy3IsvKVthQIDAQAB";//支付宝支付公钥 private String aliAppid = "2021004105665036";//支付宝appid + + + /** * 根据运营商id查询所有门店 */ @@ -110,6 +125,14 @@ List<TCity> list = cityService.list(new LambdaQueryWrapper<TCity>().eq(TCity::getParentId, 0)); model.addAttribute("provinceList",list); return PREFIX + "Operator_add.html"; + } + @RequestMapping("/bindWx/{id}") + public String bindWx(Model model,@PathVariable("id") Integer id) { + + model.addAttribute("id",id); + model.addAttribute("merchantNumber",operatorService.getById(id).getMerchantNumber()); + model.addAttribute("name",operatorService.getById(id).getMerchantName()); + return PREFIX + "Operator_wx.html"; } /** * 跳转运营商编辑页面 @@ -161,10 +184,27 @@ List<Map<String,Object>> list = operatorService.listAll(page,userName,phone,type); page.setRecords(list); return super.packForBT(page); + + } + private ProfitsharingService profitsharingService; + /** + * 手动填入微信商户号 + */ + @RequestMapping(value = "/merchantNumberWx") + @ResponseBody + public Object listAll(Integer id, String merchantNumber,String name) throws Exception { + TOperator byId = operatorService.getById(id); + byId.setMerchantNumber(merchantNumber); + operatorService.updateById(byId); + ResultUtil resultUtil = payMoneyUtil.addReceiver(merchantNumber, name); + if (resultUtil.getCode() == 500){ + return ResultUtil.error(resultUtil.getMsg()); + } + return SUCCESS_TIP; } /** - * 跳转运营商商户去认证页面 + * 支付宝跳转运营商商户去认证页面 */ @RequestMapping("/proportionAuth/{id}") public String proportionAuth(Model model,@PathVariable("id") Integer id) { @@ -215,7 +255,58 @@ return PREFIX + "OperatorUser_proportionAuth.html"; } /** - * 跳转运营商商户去认证页面 详情页面 + * 微信跳转运营商商户去认证页面 + */ + @RequestMapping("/proportionAuthWx/{id}") + public String proportionAuthWx(Model model,@PathVariable("id") Integer id) { + model.addAttribute("id",id); + TOperator data = operatorService.getById(id); + User byId = userService.getById(data.getUserId()); + model.addAttribute("user",byId); + List<TCity> list = cityService.list(new LambdaQueryWrapper<TCity>().eq(TCity::getParentId, 0)); + model.addAttribute("list",list); + model.addAttribute("data",data); + OperatorAuthAlipay info = operatorAuthService.getOne(new QueryWrapper<OperatorAuthAlipay>().eq("operatorId", id)); + model.addAttribute("item",info); + + if (info==null){ + OperatorAuthAlipay operatorAuth = new OperatorAuthAlipay(); + model.addAttribute("item",operatorAuth); + model.addAttribute("bodyType",0); + model.addAttribute("code",null); + model.addAttribute("reasons",null); + // 0不显示二维码 + model.addAttribute("type",0); + }else{ + model.addAttribute("bodyType",info.getBodyType()); + model.addAttribute("accountType",info.getAccountType()); + model.addAttribute("useType",info.getUseType()); + model.addAttribute("cardType",info.getCardType()); + model.addAttribute("reasons",info.getRefuseReason()); +// TCity one = cityService.getOne(new LambdaQueryWrapper<TCity>().eq(TCity::getCode, info.getCityCode())); +// List<TCity> district = cityService.list(new QueryWrapper<TCity>().eq("parent_id", one.getId())); +// model.addAttribute("district",district); +// if (info.getOrderStatus().equals("AUDIT_PASS")||info.getOrderStatus().equals("LEGAL_CONFIRM")||info.getOrderStatus().equals("CONTACT_CONFIRM")){ +// // 通过才展示二维码 +// model.addAttribute("type",1); +// }else{ +// model.addAttribute("type",0); +// } +// model.addAttribute("code",info.getQrCode()); +// model.addAttribute("item",info); +// model.addAttribute("bodyType",info.getBodyType()); +// if (info.getRefuseReason()!=null && (!info.getRefuseReason().equals(""))){ +// model.addAttribute("reasons",info.getRefuseReason()); +// }else{ +// model.addAttribute("reasons",null); +// } + + + } + return PREFIX + "OperatorUser_proportionAuthWX.html"; + } + /** + * 支付宝跳转运营商商户去认证页面 详情页面 */ @RequestMapping("/proportionAuth1/{id}") public String proportionAuth1(Model model,@PathVariable("id") Integer id) { @@ -291,6 +382,146 @@ return PREFIX + "OperatorUser_proportionAuth_info.html"; } /** + * 微信跳转运营商商户去认证页面 详情页面 + */ + @RequestMapping("/proportionAuth1Wx/{id}") + public String proportionAuth1Wx(Model model,@PathVariable("id") Integer id) { + model.addAttribute("id",id); + TOperator data = operatorService.getById(id); + User byId = userService.getById(data.getUserId()); + model.addAttribute("user",byId); + OperatorUser operatorId = operatorUserService.getOne(new QueryWrapper<OperatorUser>() + .eq("operatorId", data.getId())); + model.addAttribute("data",data); + OperatorAuth info = operatorAuthWxService.getOne(new QueryWrapper<OperatorAuth>() + .eq("operatorId", id)); + model.addAttribute("item",info); + List<TCity> list1 = cityService.list(new LambdaQueryWrapper<TCity>().eq(TCity::getParentId, 0)); + model.addAttribute("list1",list1); + if (StringUtils.hasLength(info.getProvince())){ + // 获取银行开户省 + List<TCity> list4 = cityService.list(new LambdaQueryWrapper<TCity>().eq(TCity::getParentId, 0)); + // 获取银行开户市 + TCity city = cityService.getOne(new QueryWrapper<TCity>().eq("code", info.getProvinceCode())); + List<TCity> list5 = cityService.list(new LambdaQueryWrapper<TCity>().eq(TCity::getParentId, city.getId())); + model.addAttribute("list4",list4); + model.addAttribute("list5",list5); + }else{ + List<TCity> list6 = cityService.list(new LambdaQueryWrapper<TCity>().eq(TCity::getParentId, 0)); + model.addAttribute("list4",list6); + List<TCity> list5 = cityService.list(new LambdaQueryWrapper<TCity>().eq(TCity::getParentId, 1)); + model.addAttribute("list5",list5); + } + model.addAttribute("bodyType",info.getBodyType()); + model.addAttribute("accountType",info.getAccountType()); + model.addAttribute("useType",info.getAccountType()); + model.addAttribute("cardType",""); + model.addAttribute("reasons",info.getRefuseReason()); + // 【申请状态】 枚举值: + //CHECKING:资料校验中 + //ACCOUNT_NEED_VERIFY:待账户验证 + //AUDITING:审核中 + //REJECTED:已驳回 + //NEED_SIGN:待签约 + //FINISH:完成 + //FROZEN:已冻结 + //CANCELED:已作废 + switch (info.getApplymentState()){ + case "CHECKING": + model.addAttribute("applymentState","资料校验中"); + break; + case "ACCOUNT_NEED_VERIFY": + model.addAttribute("applymentState","待账户验证"); + break; + case "AUDITING": + model.addAttribute("applymentState","审核中"); + break; + case "REJECTED": + model.addAttribute("applymentState","已驳回"); + break; + case "NEED_SIGN": + model.addAttribute("applymentState","待签约"); + break; + case "FINISH": + model.addAttribute("applymentState","完成"); + break; + case "FROZEN": + model.addAttribute("applymentState","已冻结"); + break; + case "CANCELED": + model.addAttribute("applymentState","已作废"); + break; + } + if (info.getSignState()!=null){ + switch (info.getApplymentState()){ + case "CHECKING": + model.addAttribute("applymentState","资料校验中"); + break; + case "ACCOUNT_NEED_VERIFY": + model.addAttribute("applymentState","待账户验证"); + break; + case "AUDITING": + model.addAttribute("applymentState","审核中"); + break; + case "REJECTED": + model.addAttribute("applymentState","已驳回"); + break; + case "NEED_SIGN": + model.addAttribute("applymentState","待签约"); + break; + case "FINISH": + model.addAttribute("applymentState","完成"); + break; + case "FROZEN": + model.addAttribute("applymentState","已冻结"); + break; + case "CANCELED": + model.addAttribute("applymentState","已作废"); + break; + } + } + + model.addAttribute("state",info.getApplymentState()); + if (info.getSignState() == null){ + model.addAttribute("signState",0); + + }else{ + model.addAttribute("signState",info.getSignState()); + + } + // todo 查询申请单状态 + model.addAttribute("accountName",info.getSignState()); + model.addAttribute("accountNo",info.getSignState()); + model.addAttribute("payAmount",info.getSignState()); + model.addAttribute("destinationAccountNumber",info.getSignState()); + model.addAttribute("destinationAccountName",info.getSignState()); + model.addAttribute("destinationAccountBank",info.getSignState()); + model.addAttribute("city",info.getSignState()); + model.addAttribute("remark",info.getSignState()); + model.addAttribute("deadline",info.getSignState()); + model.addAttribute("signState",info.getSignState()); + +// TCity one = cityService.getOne(new LambdaQueryWrapper<TCity>().eq(TCity::getCode, info.getCityCode())); +// List<TCity> district = cityService.list(new QueryWrapper<TCity>().eq("parent_id", one.getId())); +// model.addAttribute("district",district); +// if (info.getOrderStatus().equals("AUDIT_PASS")||info.getOrderStatus().equals("LEGAL_CONFIRM")||info.getOrderStatus().equals("CONTACT_CONFIRM")){ +// // 通过才展示二维码 +// model.addAttribute("type",1); +// }else{ +// model.addAttribute("type",0); +// } +// model.addAttribute("code",info.getQrCode()); +// model.addAttribute("item",info); +// model.addAttribute("bodyType",info.getBodyType()); +// if (info.getRefuseReason()!=null && (!info.getRefuseReason().equals(""))){ +// model.addAttribute("reasons",info.getRefuseReason()); +// }else{ +// model.addAttribute("reasons",null); +// } + + return PREFIX + "OperatorUser_proportionAuth_infoWX.html"; + } + /** * 根据所选市 获取区 */ @RequestMapping(value = "/getDistrict") @@ -305,7 +536,7 @@ return ERROR; } } -// public static void main(String[] args) { + // public static void main(String[] args) { // // 调用支付宝接口 通过银行卡号获取银行信息 // String url = "https://ccdcapi.alipay.com/validateAndCacheCardInfo.json?_input_charset=utf-8&" + // "cardNo=6217003800041315031&cardBinCheck=true"; @@ -319,7 +550,273 @@ // System.err.println(cardType); // // } + public static String rsaEncryptOAEP(String message, X509Certificate certificate) + throws IllegalBlockSizeException, IOException { + try { + Cipher cipher = Cipher.getInstance("RSA/ECB/OAEPWithSHA-1AndMGF1Padding"); + cipher.init(Cipher.ENCRYPT_MODE, certificate.getPublicKey()); + byte[] data = message.getBytes("utf-8"); + byte[] cipherdata = cipher.doFinal(data); + return Base64.getEncoder().encodeToString(cipherdata); + } catch (NoSuchAlgorithmException | NoSuchPaddingException e) { + throw new RuntimeException("当前Java环境不支持RSA v1.5/OAEP", e); + } catch (InvalidKeyException e) { + throw new IllegalArgumentException("无效的证书", e); + } catch (IllegalBlockSizeException | BadPaddingException e) { + throw new IllegalBlockSizeException("加密原串的长度不能超过214字节"); + } + } + /** + * 微信商户认证提交 + */ + @RequestMapping(value = "/wxAuth") + @ResponseBody + public Object wxAuth(Integer operatorId,String bodyType,String businessName,String businessNumber,String companyAddress, + String aliasName, + String license,String legalPhone, + String legalEmail, + String legalPerson,String legalAddress, + String IDCardTime,String IDCardEnd,String tradeTime,String endTime, + String leagleNumber,String legalFront,String legalBack, + String bankCard,String bankCardTwo,Integer useType,String bank,String bankName, + String accountName,String provinceCode,String province,String cityCode,String city, + String isBenefits, + String benefitsName, + String benefitsFront, + String benefitsBack, + String benefitsNumber, + String benefitsStartTime, + String benefitsEndTime, + String benefitsAddress + ) { + OperatorAuth operatorId1 = operatorAuthWxService.getOne(new QueryWrapper<OperatorAuth>() + .eq("operatorId", operatorId)); + TOperator byId = operatorService.getById(operatorId); + Integer userId1 = byId.getUserId(); + OperatorUser userId2 = operatorUserService.getOne(new QueryWrapper<OperatorUser>() + .eq("userId", userId1)); + userId2.setWechatAudit(1); + // 2是企业 4个体 + if (bodyType.equals("2")){ + userId2.setWechatType(2); + }else{ + userId2.setWechatType(4); + } + operatorUserService.updateById(userId2); + if (null == endTime || "".equals(endTime)){ + endTime = "长期"; + } + if (null == IDCardEnd || "".equals(IDCardEnd)){ + IDCardEnd = "长期"; + } + OperatorAuth operatorAuth = new OperatorAuth(); + + + operatorAuth.setOperatorId(operatorId); + operatorAuth.setBodyType(bodyType); + operatorAuth.setAliasName(aliasName); + operatorAuth.setBusinessName(businessName); + operatorAuth.setAccountType(useType); + operatorAuth.setBusinessNumber(businessNumber); + operatorAuth.setLegalRepresentative(legalPerson); + operatorAuth.setRegisterAddress(companyAddress); + operatorAuth.setBusinessTerm(tradeTime); + operatorAuth.setBusinessEnd(endTime); + operatorAuth.setLegalPerson(legalPerson); + operatorAuth.setLeagleNumber(leagleNumber); + operatorAuth.setLegalTerm(IDCardTime); + operatorAuth.setLegalEnd(IDCardEnd); + operatorAuth.setLegalEmail(legalEmail); + operatorAuth.setLegalAddress(legalAddress); + operatorAuth.setBusinessPicture(license); + operatorAuth.setLegalFront(legalFront); + operatorAuth.setLegalBack(legalBack); + if (!StringUtils.hasLength(license))operatorAuth.setBusinessPicture(null); + if (!StringUtils.hasLength(legalFront))operatorAuth.setLegalFront(null); + if (!StringUtils.hasLength(legalBack))operatorAuth.setLegalBack(null); + operatorAuth.setBank(bank); + operatorAuth.setAccountName(accountName); + operatorAuth.setProvince(province); + operatorAuth.setProvinceCode(provinceCode); + operatorAuth.setCity(city); + operatorAuth.setCityCode(cityCode); + operatorAuth.setBankName(bankName); + operatorAuth.setBankNumber(bankCard); + operatorAuth.setAuditState(0); + operatorAuth.setName(legalPerson); + operatorAuth.setLegalPhone(legalPhone); + operatorAuth.setPhone(legalPhone); + operatorAuth.setNumber(leagleNumber); + operatorAuth.setBankCardTwo(bankCardTwo); + operatorAuth.setIsBenefits(isBenefits); + + if (isBenefits.equals("true")){ + operatorAuth.setBenefitsName(legalPerson); + operatorAuth.setBenefitsFront(legalFront); + operatorAuth.setBenefitsBack(legalBack); + operatorAuth.setBenefitsNumber(leagleNumber); + operatorAuth.setBenefitsStartTime(IDCardTime); + operatorAuth.setBenefitsEndTime(IDCardEnd); + operatorAuth.setBenefitsAddress(legalAddress); + benefitsName = legalPerson; + benefitsFront = legalFront; + benefitsBack =legalBack; + benefitsNumber =leagleNumber; + benefitsStartTime =IDCardTime; + benefitsEndTime =IDCardEnd; + benefitsAddress = legalAddress; + } + LocalDateTime currentDateTime = LocalDateTime.now(); + // 格式化日期和时间信息 + DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyyMMddHHmmss"); + String formattedDateTime = currentDateTime.format(formatter); + // 生成随机数,填充剩余位数 + Random random = new Random(); + StringBuilder randomPart = new StringBuilder(); + for (int i = 0; i < 3; i++) { + // 大写字母 + randomPart.append((char) (random.nextInt(26) + 'A')); + } + // 组合业务申请编号 若申请单被驳回,可填写相同的“业务申请编号”,即可覆盖修改原申请单信息 。 + String orderNumber = formattedDateTime + randomPart; + if (operatorId1 == null){ + operatorAuth.setOutBizNo(orderNumber); + operatorAuth.setAuditState(1); + operatorAuth.setApplymentState("CHECKING"); + operatorAuthWxService.save(operatorAuth); + }else{ + operatorAuth.setId(operatorId1.getId()); + operatorAuth.setBenefitsFront(operatorId1.getLegalFront()); + operatorAuth.setBenefitsBack(operatorId1.getLegalBack()); + BeanUtils.copyProperties(operatorAuth,operatorId1); + operatorId1.setAuditState(1); + operatorId1.setApplymentState("CHECKING"); + operatorAuthWxService.updateById(operatorId1); + } + String param="{"+ + "\"out_request_no\" :"+ "\""+orderNumber+"\""+","+ + " \"organization_type\" :"+"\""+bodyType+"\""+","+ + " \"finance_institution\" : false,\n" + + " \"business_license_info\" : {\n" + + // 主体为“个体工商户/企业”时,不填。 +// "cert_type:" + "CERTIFICATE_TYPE_2388,"+ + " \"business_license_copy\" :"+ "\""+license+"\""+","+ + " \"business_license_number\" : "+"\""+businessNumber+"\""+","+ + " \"merchant_name\" : "+ "\""+businessName+"\""+","+ + " \"legal_person\" : "+ "\""+legalPerson+"\""+","+ + "\"company_address\" :"+ "\""+companyAddress+"\""+","+ + " \"business_time\" : \"[\\\\\\\""+tradeTime+"\\\\\\\",\\\\\\\""+endTime+"\\\\\\\"]\"\n" + + " },\n" + +// "finance_institution_info:" +" {"+ +// "finance_type:" + "BANK_AGENT,"+ +// "finance_license_pics:" +"["+ +// "example_finance_license_pics"+ +// "]},"+ +// "id_holder_type:" + "LEGAL,"+ + " \"id_doc_type\" : \"IDENTIFICATION_TYPE_MAINLAND_IDCARD\",\n" + +// "authorize_letter_copy:" + "47ZC6GC-vnrbEny_Ie_An5-tCpqxucuxi-vByf3Gjm7KEIUv0OF4wFNIO4kqg05InE4d2I6_H7I4,"+ + " \"id_card_info\" : {\n" + + " \"id_card_copy\" : "+ "\""+legalFront+"\""+","+ + " \"id_card_national\" : "+ "\""+legalBack+"\""+","+ + " \"id_card_name\" : "+ "\""+legalPerson+"\""+","+ + " \"id_card_number\" : "+ "\""+leagleNumber+"\""+","+ + " \"id_card_address\" : "+ "\""+legalAddress+"\""+","+ + " \"id_card_valid_time_begin\" : "+ "\""+IDCardTime+"\""+","+ + " \"id_card_valid_time\" : "+ "\""+IDCardEnd+"\""+","+ +// "id_doc_info:" + +// "{id_doc_name:" + "jTpGmxUX3FBWVQ5NJTZvlKX_gdU4cRz7z5NxpnFuAxhBTEO_PvWkfSCJ3zVIn001D8daLC-ehEuo0BJqRTvDujqhThn4ReFxikqJ5YW6zFQ,"+ +// "id_doc_number:" + "jTpGmxUX3FBWVQ5NJTZvlKX_gdU4cRz7z5NxpnFuAxhBTEO_PvWkfSCJ3zVIn001D8daLC-ehEuo0BJqRTvDujqhThn4ReFxikqJ5YW6zFQ,"+ +// "id_doc_copy:" + "47ZC6GC-vnrbEny__Ie_An5-tCpqxucuxi-vByf3Gjm7KE53JXvGy9tqZm2XAUf-4KGprrKhpVBDIUv0OF4wFNIO4kqg05InE4d2I6_H7I4,"+ +// "id_doc_copy_back:" + "47ZC6GC-vnrbEny__Ie_An5-tCpqxucuxi-vByf3Gjm7KE53JXvGy9tqZm2XAUf-4KGprrKhpVBDIUv0OF4wFNIO4kqg05InE4d2I6_H7I4,"+ +// "id_doc_address:" + "jTpGmxUX3FBWVQ5NJTZvlKX_gdU4cRz7z5NxpnFuAxhBTEO_PvWkfSCJ3zVIn001D8daLC-ehEuo0BJqRTvDujqhThn4ReFxikqJ5YW6zFQ,"+ +// "doc_period_begin:" + "2019-06-06,"+ +// "doc_period_end:" + "2020-01-02},"+ + + " \"owner\" : true,\n" + + " \"account_info\" : {\n" + + " \"bank_account_type\" : "+ "\""+useType+"\""+","+ + " \"account_bank\" : "+ "\""+bank+"\""+","+ + " \"account_name\" : "+ "\""+accountName+"\""+","+ + " \"bank_address_code\" :"+ "\""+cityCode+"\""+","+ + " \"bank_branch_id\" : "+ "\""+bankCardTwo+"\""+","+ + " \"bank_name\" : "+ "\""+bankName+"\""+","+ + " \"account_number\" : "+ "\""+bankCard+"\""+","+ + " \"contact_info\" : {\n" + + " \"contact_type\" : \"65\",\n" + + " \"contact_name\" :"+ "\""+legalPerson+"\""+","+ + " \"contact_id_doc_type\" : \"IDENTIFICATION_TYPE_MAINLAND_IDCARD\",\n" + + " \"contact_id_card_number\" : "+ "\""+leagleNumber+"\""+","+ + " \"contact_id_doc_copy\" : "+ "\""+legalFront+"\""+","+ + " \"contact_id_doc_copy_back\" :"+ "\""+legalBack+"\""+","+ +// "contact_id_doc_period_begin:"+ "2019-06-06,"+ +// "contact_id_doc_period_end:" + "2026-06-06,"+ +// "business_authorization_letter:" + "47ZC6GC-vnrbEny_Ie_An5-tCpqxucuxi-vByf3Gjm7KEIUv0OF4wFNIO4kqg05InE4d2I6_H7I4,"+ + " \"mobile_phone\" : "+ "\""+legalPhone+"\""+","+ + " \"contact_email\" : "+ "\""+legalEmail+"\""+ + " },\n" + + " \"sales_scene_info\" : {\n" + + " \"store_name\" : \"爱烧烤\",\n" + + " \"store_url\" : \"http://www.qq.com\",\n" + + " \"store_qr_code\" : \"jTpGmxUX3FBWVQ5NJTZvlKX_gdU4cRz7z5NxpnFuAxhBTEO_PvWkfSCJ3zVIn001D8daLC-ehEuo0BJqRTvDujqhThn4ReFxikqJ5YW6zFQ\",\n" + + " \"mini_program_sub_appid\" : \"wxa123344545577\"\n" + + " },\n" + + " \"settlement_info\" : {\n" ; + if (Integer.parseInt(bodyType) == 4){ + param = param+" \"settlement_id\" : 802,\n" + + " \"qualification_type\" : \"休闲娱乐/旅游服务\"\n" +" },\n" ; + }else{ + param = param+" \"settlement_id\" : 800,\n" + + " \"qualification_type\" : \"休闲娱乐/旅游服务\"\n" +" },\n" ; + } + param+= " \"merchant_shortname\" : "+ "\""+aliasName+"\""+ + +// "qualifications:" + "[\"jTpGmxUX3FBWVQ5NJTZvlKX_gdU4cRz7z5NxpnFuAxhBTEO_PvWkfSCJ3zVIn001D8daLC-ehEuo0BJqRTvDujqhThn4ReFxikqJ5YW6zFQ\",\"47ZC6GC-vnrbEny__Ie_An5-tCpqxucuxi-vByf3Gjm7KE53JXvGy9tqZm2XAUf-4KGprrKhpVBDIUv0OF4wFNIO4kqg05InE4d2I6_H7I4\"],"+ +// "business_addition_pics:" + "[\"jTpGmxUX3FBWVQ5NJTZvlKX_gdU4cRz7z5NxpnFuAxhBTEO_PvWkfSCJ3zVIn001D8daLC-ehEuo0BJqRTvDujqhThn4ReFxikqJ5YW6zFQ\",\"47ZC6GC-vnrbEny__Ie_An5-tCpqxucuxi-vByf3Gjm7KE53JXvGy9tqZm2XAUf-4KGprrKhpVBDIUv0OF4wFNIO4kqg05InE4d2I6_H7I4\"],"+ +// "business_addition_desc:" + "特殊情况,说明原因,"+ +// "ubo_info_list:"+ "[{"+ + "\"ubo_info_list\" : [\n" + + " {\n" + + " \"ubo_id_doc_type\" : \"IDENTIFICATION_TYPE_MAINLAND_IDCARD\",\n" + + " \"ubo_id_doc_copy\" : "+ "\""+benefitsFront+"\""+ + " \"ubo_id_doc_copy_back\" : "+ "\""+benefitsBack+"\""+ + " \"ubo_id_doc_name\" : "+ "\""+benefitsName+"\""+ + " \"ubo_id_doc_number\" : "+ "\""+benefitsNumber+"\""+ + " \"ubo_id_doc_address\" : "+ "\""+benefitsAddress+"\""+ + " \"ubo_id_doc_period_begin\" : "+ "\""+benefitsStartTime+"\""+ + " \"ubo_id_doc_period_end\" : "+ "\""+benefitsEndTime+"\""+ + " }\n" + + " ]"+ + " }\n"+ + " }\n"+ + " }\n"; + + + // 使用 Jackson 解析 JSON + ObjectMapper objectMapper = new ObjectMapper(); + try { + // 将 JSON 字符串解析为 Map + Map<String, Object> map = objectMapper.readValue(param, Map.class); + + // 输出 Map 中的内容 + for (Map.Entry<String, Object> entry : map.entrySet()) { + System.out.println(entry.getKey() + ": " + entry.getValue()); + } + System.err.println(map); + String s = HttpRequestUtil.postRequest1("https://api.mch.weixin.qq.com/v3/ecommerce/applyments/", map); + System.err.println("返回结果:"+s); + JSONObject jsonObject = JSON.parseObject(s); + String string = jsonObject.getString("out_request_no"); + // 获取业务申请编号 后续用该字段查询申请状态 + operatorAuth.setOrderNo(string); + System.err.println(jsonObject); + } catch (IOException e) { + e.printStackTrace(); + } + System.err.println(param); + + return SUCCESS_TIP; + } /** * 支付宝商户认证提交 @@ -513,25 +1010,25 @@ } String res= " \"service\":[" + - " \"app支付\"" + - " ]," + - " \"alipay_logon_id\":" + - " \""+zfbAccount+"\"" + - " ," + - " \"sites\":[" + - " {" + - " \"site_type\":\"02\"," + - " \"site_name\":\"玩湃生活\"," + - " \"tiny_app_id\":\"wx82f853a410b0c7c0\"" + - " }" + - " ]," + - " \"cert_name\":\""+businessName+"\","+ - " \"binding_alipay_logon_id\":\""+zfbAccount+"\","+ - " \"default_settle_rule\":{" + - " \"default_settle_type\":\""+type+"\"," + - " \"default_settle_target\":\""+account+"\"" + - " }" + - "}"; + " \"app支付\"" + + " ]," + + " \"alipay_logon_id\":" + + " \""+zfbAccount+"\"" + + " ," + + " \"sites\":[" + + " {" + + " \"site_type\":\"02\"," + + " \"site_name\":\"玩湃生活\"," + + " \"tiny_app_id\":\"wx82f853a410b0c7c0\"" + + " }" + + " ]," + + " \"cert_name\":\""+businessName+"\","+ + " \"binding_alipay_logon_id\":\""+zfbAccount+"\","+ + " \"default_settle_rule\":{" + + " \"default_settle_type\":\""+type+"\"," + + " \"default_settle_target\":\""+account+"\"" + + " }" + + "}"; if (accountType.equals("bankCard")){ request.setBizContent(param + biz_cards+res); @@ -578,6 +1075,7 @@ } return ResultUtil.success(); } + public static Object uploadImg(String img){ String appPrivateKey = "MIIEvwIBADANBgkqhkiG9w0BAQEFAASCBKkwggSlAgEAAoIBAQCi5i9nW/hGLJ3A06cZxTQdviFC7THpdSihoTYGLr9q006hu0V26ecBMY/o4w5bvIX0Ok/yofmZsVcCJpAPvbXL/uqVrIjnRRxXiaeBFThlxoBUTdunvbUSDYfzlEhJr5NvUKI6H6lz2niXlQGx4qy8Hau4ccWit9kM8jwUvsBVQoFgJA+xrjMvooA7YLopQtpOD+UJr5thApTSf1xrnr1W12yolTLEH15JmNV372cqXrYUuqnY0QsaPtxeqJUGAOcGdVLllQ7easEznP8DFBvDdHATcmp2SHNQDUEWN6MCVPbMgY06NQVqAXxqjTAYSVh+6TRu6bofPmpYC3TZB003AgMBAAECggEBAJAcR2+PA3NBYUYHeFrqBRMS8uX8ZR19kjZ7IgoSLTFaQsP9opRylPSPXhrPVBKAE5leRQAHn4MCSlESwHvMfxo7KFjFTFAc6dffZZpipYQUOc9bGampwJh58/3e/pyBgVMG6J23CPf/HJQtNFSkjd/V9+ayb/9l2dUEL3bC0fAZ/dbx8HsxdLw8wn3fLlWLj68hOMqa2deCZe3JdSVsPbeWqkh56FFsMLug0Nd+Ar4TgRl9/jnhXF0JWiD0LmPUYLhboY7EfUBzN4w1iYbDi1P+3zvoOYsiVKAXox9GMhQ2VzOO2UcSTuizSza2e98mGpabl/GpKmCz+RDFjtkX6eECgYEA2MyCij65eO3aGIm3FUe93DULRBYTfX8qJQSJq2WOWA3mmQlEW6L3O2B5/lG2h+8WmN6iLEs9eHpgycGYp7vAqgrANEn16ACVcuyx0scFtrZfZ+kmHMzFfiUWxJjVYk/6YngsGVBLdw6ueM42C8TTP67X9tU5TdVGoGWuqEj4W98CgYEAwFqwprXOch5Pqk/RPbb49r0Ou03K/UbciWnWWKzUhFFNS8MdlQPoDvQZbMwHLeWsa2VhaKITK3x5biLQb3U+0GLOn6lTvEyrEUH+ucREyLgVYTRAvwBPtnvlrzpyxPk2HnslQjju8WrvvLLBMKWUjlTrTOzhaHT21gz3pHMiOakCgYEAhLmfaXdBITGshb054sNLDtdCkGpbgEcrzAHdLps769iGxkYQHXHFngpQZUwtTUcoNGqIKknd1jZFrv7gsD+XkgKG7PwimehRlkwmCX5ilxtLiVgJRzRt6+5U5AMVD90a0tHzXYP0z2yjj73fBJF5KtGl0a10KZxaYrQdm1UhB00CgYBZZgzx/k9rtHC8LAqIj1CYhHejT92G53c6Gkl3vyOqN4sgKhfGmSEySfrDGPRBPZxr8ZtbIPCd5mUdberH0osWGMYFaJI1UsCy7aQwvGpniz7MhZeN7dweaOjwDs8mgtjHQ96mL4XGCDhR0BZ/wIURvZ/6iaGdhbbu9unlsWj3uQKBgQCmZYdsbbZkd3ev6f8rwyvMz+DrCQyYpY44cegBYuJgrZiQnL2fJioeN7ixX0UM48SfwsZEIrzshP/LGAwnc2MdjxKUl4jLN8SEe0NAjXOnz9Zaw740+aOmLpXcLWdP4uM2gIhWsvW1tEkQZCXmm7c9s/RsU8Pmzv+YL3+fSijOzA==";//支付宝开发者应用私钥 String alipay_public_key = "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAmu8n/4yTHWbn7VOrNc9OsLtDL1bEQ8gC1dHkj8Wy5z0mkaOsjJRIG/28ze12M0V8jdCKuuDr5Z1OPKiqf+XO3ypguEh+mYUVMBM/cZodDFQfTY1TKLWjvQCuaqlA+QUTCK6f7T7stsgyQ1o9Jj0rXZDz6PM4QHSTzjrLIBaeqM5WIBvH+fy/X+QG5Utd+/UT0kc0JyvuKhZ65yVUd/C9VcwJJAPliRsAQNrqYterwAJ9zvw9tF11wj9W0XgJ8Ccu4x3gR1vrlLRJJo/OA97RmxPQ+5hSacWQZCUd1dwiBq+YCrKVHGTj14izRHXrLc0yBlRXo7tBOIqcy3IsvKVthQIDAQAB";//支付宝支付公钥 @@ -624,6 +1122,74 @@ } /** + * 查询进件申请单审核状态 + */ + public JSONObject queryState(String orderNo) { + String url = "https://api.mch.weixin.qq.com/v3/ecommerce/applyments/out-request-no/"+orderNo; + String req1 = HttpRequestUtil.getReq1(url, new HashMap<>()); + System.err.println("查询申请单审核状态字符串"+req1); + JSONObject jsonObject = JSON.parseObject(req1); + System.err.println("查询申请单审核状态Json"+jsonObject); + String applymentState = jsonObject.getString("applyment_state"); + String outBizNo = jsonObject.getString("out_request_no"); + OperatorAuth operatorAuth = operatorAuthWxService.getOne( + new QueryWrapper<OperatorAuth>() + .eq("outBizNo", outBizNo)); + OperatorUser operatorUser = operatorUserService.getOne(new QueryWrapper<OperatorUser>() + .eq("operatorId", operatorAuth.getOperatorId())); + // 审核状态 + operatorAuth.setApplymentState(applymentState); + if (applymentState.equals("REJECTED") || applymentState.equals("FROZEN")){ + operatorUser.setWechatAudit(3); + operatorAuth.setAuditState(2); + // 如果被拒 赋值拒绝原因 + operatorAuth.setRefuseReason(jsonObject.getJSONObject("audit_detail").getString("reject_reason")); + } + if (applymentState.equals("NEED_SIGN")){ + operatorAuth.setSignUrl(jsonObject.getString("sign_url")); + operatorAuth.setMerchantNumber(jsonObject.getString("sub_mchid")); + } + if (applymentState.equals("FINISH")){ + operatorAuth.setMerchantNumber(jsonObject.getString("sub_mchid")); + operatorUser.setWechatAudit(2); + operatorAuth.setAuditState(1); + } + if (applymentState.equals("ACCOUNT_NEED_VERIFY")){ + operatorAuth.setLegalValidationUrl(jsonObject.getString("legal_validation_url")); + } + return jsonObject; + /** + * { + * "applyment_state" : "FINISH", + * "applyment_state_desc" : "审核中", + * "sign_url" : "https://pay.weixin.qq.com/public/apply4ec_sign/s?applymentId=2000002126198476&sign=b207b673049a32c858f3aabd7d27c7ec", + * "sub_mchid" : "1542488631", + * "account_validation" : { + * "account_name" : "aOf7Gk2qT26kakkuTZpbFAn7Mb7xcar0LlQaYoi3+LnnWwgAsfaUUTg9+GmYJq6YCz+RiluWHeHFq1lt8n3eIkF0laVvqmAU80xIWGZgWJnRmnRuZxsg0HJZfnUac2JfqyuL8OoyM2YSuYDqdsyvcOlgUQgq8MPCR6pmvhBCmIeJvnVSm8J+L+yx912itUmTDxhdBlu1CFBIUefME9nYB70vCVTNAVXgURkf65mjHMBiE9Y+wrPZVmTIIz3C3PtPVMZYDEvBT4rDdICA3ZYXshYqeOSslSjSMf+MhhC4oaujiISFzq3AE+as7mAEDJly+DgRuVs74msmKUH8pl+3oA==", + * "account_no" : "aOf7Gk2qT26kakkuTZpbFAn7Mb7xcar0LlQaYoi3+LnnWwgAsfaUUTg9+GmYJq6YCz+RiluWHeHFq1lt8n3eIkF0laVvqmAU80xIWGZgWJnRmnRuZxsg0HJZfnUac2JfqyuL8OoyM2YSuYDqdsyvcOlgUQgq8MPCR6pmvhBCmIeJvnVSm8J+L+yx912itUmTDxhdBlu1CFBIUefME9nYB70vCVTNAVXgURkf65mjHMBiE9Y+wrPZVmTIIz3C3PtPVMZYDEvBT4rDdICA3ZYXshYqeOSslSjSMf+MhhC4oaujiISFzq3AE+as7mAEDJly+DgRuVs74msmKUH8pl+3oA==", + * "pay_amount" : 124, + * "destination_account_number" : "7222223333322332", + * "destination_account_name" : "财付通支付科技有限公司", + * "destination_account_bank" : "招商银行威盛大厦支行", + * "city" : "深圳", + * "remark" : "入驻账户验证", + * "deadline" : "2018-12-10 17:09:01" + * }, + * "audit_detail" : [ + * { + * "param_name" : "id_card_copy", + * "reject_reason" : "身份证背面识别失败,请上传更清晰的身份证图片。" + * } + * ], + * "legal_validation_url" : "https://pay.weixin.qq.com/public/apply4ec_sign/s?applymentId=2000002126198476&sign=b207b673049a32c858f3aabd7d27c7ec", + * "out_request_no" : "APPLYMENT_00000000001", + * "applyment_id" : 2000002124775691, + * "sign_state" : "SIGNED" + * } + */ + } + + /** * 分账比例提交 */ @RequestMapping(value = "/proportion") @@ -635,6 +1201,86 @@ operatorUserService.updateById(id); return SUCCESS_TIP; } + + +// public static void main(String[] args) throws URISyntaxException { +// String filePath = "https://we-park-life.oss-cn-beijing.aliyuncs.com/img/a5e24fc4b13b4ea48bb2455ad8662a5d.jpg"; // 替换成你的OSS图片链接 +// String string = UUID.randomUUID().toString(); +// try { +// URL url = new URL(filePath); +// InputStream inputStream = url.openStream(); +// // 这里可以根据需求处理 inputStream,比如保存到本地文件 +// // 例如保存到本地文件 +// saveInputStreamToFile(inputStream, "D:\\tempImg\\"+string+".jpg"); +// } catch (IOException e) { +// e.printStackTrace(); +// } +// URI uri = new URI("https://api.mch.weixin.qq.com/v3/merchant/media/upload"); +// File file = new File("D:\\tempImg\\"+string+".jpg"); +// try (FileInputStream ins1 = new FileInputStream(file)) { +// String sha256 = DigestUtils.sha256Hex(ins1); +// try (InputStream ins2 = new FileInputStream(file)) { +// HttpPost request = new WechatPayUploadHttpPost.Builder(uri) +// .withImage(file.getName(), sha256, ins2) +// .build(); +//// CloseableHttpResponse response1 = httpClient.execute(request); +// } +// } catch (IOException e) { +// throw new RuntimeException(e); +// } +// } + private static void saveInputStreamToFile(InputStream inputStream, String filePath) throws IOException { + OutputStream outputStream = new FileOutputStream(filePath); + byte[] buffer = new byte[1024]; + int bytesRead; + while ((bytesRead = inputStream.read(buffer)) != -1) { + outputStream.write(buffer, 0, bytesRead); + } + outputStream.close(); + inputStream.close(); + } + /** + * 微信商户认证上传图片 + */ + @RequestMapping(value = "/wxUpload") + @ResponseBody + public Object wxUpload(String img) throws URISyntaxException, FileNotFoundException { + String filePath = "https://we-park-life.oss-cn-beijing.aliyuncs.com/img/a5e24fc4b13b4ea48bb2455ad8662a5d.jpg"; // 替换成你的OSS图片链接 + String string = UUID.randomUUID().toString(); + try { + URL url = new URL(filePath); + InputStream inputStream = url.openStream(); + // 这里可以根据需求处理 inputStream,比如保存到本地文件 + // 例如保存到本地文件 + + + saveInputStreamToFile(inputStream, "D:\\tempImg\\"+string+".jpg"); + } catch (IOException e) { + e.printStackTrace(); + } + URI uri = new URI("https://api.mch.weixin.qq.com/v3/merchant/media/upload"); + File file = new File("D:\\tempImg\\"+string+".jpg"); + try (FileInputStream ins1 = new FileInputStream(file)) { + String sha256 = DigestUtils.sha256Hex(ins1); + try (InputStream ins2 = new FileInputStream(file)) { + HttpPost request = new WechatPayUploadHttpPost.Builder(uri) + .withImage(file.getName(), sha256, ins2) + .build(); +// CloseableHttpResponse response1 = httpClient.execute(request); + } + } catch (IOException e) { + throw new RuntimeException(e); + } + return null; + } + // 辅助方法:将 InputStream 转换为 FileInputStream + private static FileInputStream convertInputStreamToFileInputStream(InputStream inputStream) throws IOException { + // 将 InputStream 转为临时文件,然后返回其 FileInputStream + File tempFile = File.createTempFile("temp", null); + org.apache.commons.io.IOUtils.copy(inputStream, new java.io.FileOutputStream(tempFile)); + return new FileInputStream(tempFile); + } + /** * 跳转运营商设置分账比例页面 */ @@ -857,6 +1503,7 @@ } + /** * 获取所有运营商 * @return diff --git a/cloud-server-management/src/main/java/com/dsh/guns/modular/system/controller/code/OperatorUserController.java b/cloud-server-management/src/main/java/com/dsh/guns/modular/system/controller/code/OperatorUserController.java index 6f35ce3..5f4478e 100644 --- a/cloud-server-management/src/main/java/com/dsh/guns/modular/system/controller/code/OperatorUserController.java +++ b/cloud-server-management/src/main/java/com/dsh/guns/modular/system/controller/code/OperatorUserController.java @@ -80,63 +80,4 @@ return list; } - @RequestMapping(value = "/mgtShopAuth", method = RequestMethod.POST) - @ApiOperation(value = "微信平台商户进件") - @ResponseBody - public Object mgtShopAuth(Integer operatorId,String aliasName, String name,String phone, - String bodyType,String businessName,String businessNumber,String legalPerson, - String legalRepresentative,String registerAddress,String businessTerm,String businessPicture, - String businessEnd,String legalNumber,String accountType, - Integer blBusinessFoeverFlag, String leagleNumber,String legalAddress, - String legalTerm,String legalEnd, Integer lpIcForeverFlag,String legalFront,String legalBack, - String legalPhone,String legalEmail, String settlementAccountType,String saBank,String saAccountName, - String saBankProvinceCode,String saBankCityCode, String saBankName,String saNumber,String baPics, - String baDesc,Integer owner, String uboName,String uboIdCard,String uboIcStartDate,String uboIcEndDate, - String uboIcFront,String uboIcBack, String uboIcAddress) { - MgtShopAuthDto mgtShopAuthDto = new MgtShopAuthDto(); - Integer userId = Objects.requireNonNull(UserExt.getUser()).getId(); - mgtShopAuthDto.setUserId(userId); - mgtShopAuthDto.setAuthId("1"); - mgtShopAuthDto.setShopId(Long.valueOf(operatorId)); - mgtShopAuthDto.setShopName(businessName); - mgtShopAuthDto.setShopownerName(name); - mgtShopAuthDto.setShopownerPhone(phone); - mgtShopAuthDto.setMainType(Integer.valueOf(bodyType)); - mgtShopAuthDto.setBlShopName(businessName); - mgtShopAuthDto.setBlNumber(businessNumber); - mgtShopAuthDto.setBlCorporateName(legalRepresentative); - mgtShopAuthDto.setBlRegisteredAddress(registerAddress); - mgtShopAuthDto.setBlBusinessStartTime(businessTerm); - mgtShopAuthDto.setBlBusinessDeanline(businessEnd); - mgtShopAuthDto.setBlBusinessFoeverFlag(blBusinessFoeverFlag); - mgtShopAuthDto.setBlImage(businessPicture); - mgtShopAuthDto.setLpCorporateName(legalPerson); - mgtShopAuthDto.setLpIdCard(legalNumber); - mgtShopAuthDto.setLpIdAddress(legalAddress); - mgtShopAuthDto.setLpIcStartDate(legalTerm); - mgtShopAuthDto.setLpIcEndDate(legalEnd); - mgtShopAuthDto.setLpIcForeverFlag(lpIcForeverFlag); - mgtShopAuthDto.setLpIcFront(legalFront); - mgtShopAuthDto.setLpIcBack(legalBack); - mgtShopAuthDto.setLpMobilePhone(legalPhone); - mgtShopAuthDto.setLpContactEmail("法人邮箱"); - mgtShopAuthDto.setSettlementAccountType(accountType); - mgtShopAuthDto.setSaBank("开户行"); - mgtShopAuthDto.setSaAccountName("开户名称"); - mgtShopAuthDto.setSaBankProvinceCode("开户所在省"); - mgtShopAuthDto.setSaBankCityCode("开户所在市"); - mgtShopAuthDto.setSaBankName("开户行全称"); - mgtShopAuthDto.setSaNumber("银行卡号"); - mgtShopAuthDto.setOwner(1); - mgtShopAuthDto.setUboName("ck"); - mgtShopAuthDto.setUboIdCard("513701199910156123"); - mgtShopAuthDto.setUboIcStartDate("2020-05-05"); - mgtShopAuthDto.setUboIcEndDate("2025-05-05"); - mgtShopAuthDto.setUboIcFront("受益人身份证正面"); - mgtShopAuthDto.setUboIcBack("受益人身份证正面"); - mgtShopAuthDto.setUboIcAddress("受益人居住地址"); - operatorUserService.mgtShopAuth(mgtShopAuthDto); - return SUCCESS_TIP; - } - } diff --git a/cloud-server-management/src/main/java/com/dsh/guns/modular/system/controller/code/TGoodsController.java b/cloud-server-management/src/main/java/com/dsh/guns/modular/system/controller/code/TGoodsController.java index f78c454..60b87ac 100644 --- a/cloud-server-management/src/main/java/com/dsh/guns/modular/system/controller/code/TGoodsController.java +++ b/cloud-server-management/src/main/java/com/dsh/guns/modular/system/controller/code/TGoodsController.java @@ -481,6 +481,8 @@ } } PointsMerchandise pointsMerchandise = new PointsMerchandise(); + pointsMerchandise.setAddUserId(UserExt.getUser().getObjectId()); + pointsMerchandise.setAddType(UserExt.getUser().getObjectType()); pointsMerchandise.setType(typeAll); pointsMerchandise.setName(name); pointsMerchandise.setCoursePackageId(coursePackageId); diff --git a/cloud-server-management/src/main/java/com/dsh/guns/modular/system/controller/util/HttpClientUtil.java b/cloud-server-management/src/main/java/com/dsh/guns/modular/system/controller/util/HttpClientUtil.java new file mode 100644 index 0000000..d299371 --- /dev/null +++ b/cloud-server-management/src/main/java/com/dsh/guns/modular/system/controller/util/HttpClientUtil.java @@ -0,0 +1,270 @@ +package com.dsh.guns.modular.system.controller.util; + +import com.alibaba.fastjson.JSON; +import com.fasterxml.jackson.databind.ObjectMapper; +import org.apache.http.NameValuePair; +import org.apache.http.client.config.RequestConfig; +import org.apache.http.client.entity.UrlEncodedFormEntity; +import org.apache.http.client.methods.CloseableHttpResponse; +import org.apache.http.client.methods.HttpGet; +import org.apache.http.client.methods.HttpPost; +import org.apache.http.conn.ssl.SSLConnectionSocketFactory; +import org.apache.http.entity.ContentType; +import org.apache.http.entity.StringEntity; +import org.apache.http.impl.client.CloseableHttpClient; +import org.apache.http.impl.client.HttpClients; +import org.apache.http.impl.conn.PoolingHttpClientConnectionManager; +import org.apache.http.message.BasicNameValuePair; +import org.apache.http.ssl.SSLContexts; +import org.apache.http.util.EntityUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import javax.net.ssl.SSLContext; +import java.io.File; +import java.io.FileInputStream; +import java.io.InputStream; +import java.nio.charset.Charset; +import java.security.KeyStore; +import java.text.SimpleDateFormat; +import java.util.*; +import java.util.concurrent.TimeUnit; + +/** + * http工具类 + */ +public class HttpClientUtil { + + private static Logger logger = LoggerFactory.getLogger(HttpClientUtil.class); + + private static PoolingHttpClientConnectionManager connectionManager; + + + { + //1.创建连接池管理器 + connectionManager = new PoolingHttpClientConnectionManager(60000, + TimeUnit.MILLISECONDS); + connectionManager.setMaxTotal(1000); + connectionManager.setDefaultMaxPerRoute(50); + } + + /** + * 创建一个httpClient对象 + */ + private static CloseableHttpClient getHttpCline() { + return HttpClients.custom() + .setConnectionManager(connectionManager) + .disableAutomaticRetries() + .build(); + } + + private static RequestConfig getRequestConfig() { + RequestConfig.Builder builder = RequestConfig.custom(); + builder.setSocketTimeout(60000)//3.1设置客户端等待服务端返回数据的超时时间 + .setConnectTimeout(30000)//3.2设置客户端发起TCP连接请求的超时时间 + .setExpectContinueEnabled(true) + .setConnectionRequestTimeout(30000);//3.3设置客户端从连接池获取链接的超时时间 + return builder.build(); + } + + + /** + * 创建一个POST请求实例 + * + * @param url 请求地址 + * @param params 请求参数 + */ + public static CloseableHttpResponse setPostHttpRequset(String url, Map<String, Object> params, Map<String, String> header, String contentType) throws Exception { + HttpPost httpPost = new HttpPost(url); + httpPost.setConfig(getRequestConfig()); + if (null != header) { + for (String key : header.keySet()) { + httpPost.setHeader(key, header.get(key)); + } + } + List<NameValuePair> list = new ArrayList<>(); + if (null != params) { + Set<String> keys = params.keySet(); + for (String key : keys) { + list.add(new BasicNameValuePair(key, null == params.get(key) ? null : params.get(key).toString())); + } + } + switch (contentType) { + case "form": + httpPost.setEntity(new UrlEncodedFormEntity(list, "UTF-8")); + break; + case "json": + ObjectMapper objectMapper = new ObjectMapper(); + String s = objectMapper.writeValueAsString(params); + httpPost.setEntity(new StringEntity(s, ContentType.create(ContentType.APPLICATION_JSON.getMimeType(), Charset.forName("UTF-8")))); + break; + } + return getHttpCline().execute(httpPost); + } + + + /** + * 获取get请求实例 + * + * @param url 请求地址 + * @param params 请求参数 + */ + private static CloseableHttpResponse setGetHttpRequset(String url, Map<String, Object> params, Map<String, String> header) throws Exception { + StringBuffer sb = new StringBuffer(); + String p = ""; + if (null != params) { + Set<String> keys = params.keySet(); + for (String key : keys) { + sb.append(key + "=" + params.get(key) + "&"); + } + p = "?" + sb.substring(0, sb.length() - 1); + } + HttpGet httpGet = new HttpGet(url + p); + httpGet.setConfig(getRequestConfig()); + if (null != header) { + for (String key : header.keySet()) { + httpGet.setHeader(key, header.get(key)); + } + } + return getHttpCline().execute(httpGet); + } + + + /** + * 发送http请求 + * + * @param mothed "GET、POST、PUT、HEAD、DELETE、HEAD、OPTIONS" + * @param url 请求地址 + * @param params 请求参数 + * @param header 请求头 + * @param contentType 参数请求方式form/json + * @return + */ + public static HttpResult pushHttpRequset(String mothed, String url, Map<String, Object> params, Map<String, String> header, String contentType) throws Exception { + String randome = UUID.randomUUID().toString(); + SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.S"); + logger.info(sdf.format(new Date()) + "----(" + randome + ")请求参数:" + JSON.toJSONString(params)); + CloseableHttpResponse httpResponse = null; + switch (mothed) { + case "GET": + httpResponse = setGetHttpRequset(url, params, header); + break; + case "POST": + httpResponse = setPostHttpRequset(url, params, header, contentType); + break; + } + int statusCode = httpResponse.getStatusLine().getStatusCode(); + String content = EntityUtils.toString(httpResponse.getEntity(), "UTF-8"); + logger.info(sdf.format(new Date()) + "----(" + randome + ")返回结果:" + content); + HttpResult httpResult = HttpResult.getHttpResult(statusCode, content); + close(httpResponse); + return httpResult; + } + + + /** + * 发送XML请求 + * + * @param url 请求地址 + * @param xml XML数据 + * @param header 自定义请求头 + * @return + */ + public static HttpResult pushHttpRequsetXml(String url, String xml, Map<String, String> header) throws Exception { + HttpPost httpPost = new HttpPost(url); + httpPost.setConfig(getRequestConfig()); + for (String key : header.keySet()) { + httpPost.setHeader(key, header.get(key)); + } + httpPost.setHeader("Content-Type", "application/xml"); + httpPost.setEntity(new StringEntity(xml, "UTF-8")); + CloseableHttpResponse httpResponse = getHttpCline().execute(httpPost); + int statusCode = httpResponse.getStatusLine().getStatusCode(); + String content = EntityUtils.toString(httpResponse.getEntity(), "UTF-8"); + HttpResult httpResult = HttpResult.getHttpResult(statusCode, content); + close(httpResponse); + return httpResult; + } + + + /** + * 请求https发送XML请求 + * + * @param url 接口路径 + * @param xml 内容 + * @param header 请求头 + * @param certPassword 证书密码 + * @param certPath 证书路径 + * @param certType 证书类型 + * @return + * @throws Exception + */ + public static String pushHttpsRequsetXml(String url, String xml, Map<String, String> header, String certPassword, String certPath, String certType) throws Exception { + HttpPost httpPost = new HttpPost(url); + for (String key : header.keySet()) { + httpPost.setHeader(key, header.get(key)); + } + httpPost.setHeader("Content-Type", "application/xml"); + httpPost.setEntity(new StringEntity(xml, "UTF-8")); + CloseableHttpClient httpCline = initCert(certPassword, certPath, certType); + CloseableHttpResponse httpResponse = httpCline.execute(httpPost); + String content = null; + if (httpResponse.getStatusLine().getStatusCode() == 200) { + content = EntityUtils.toString(httpResponse.getEntity(), "UTF-8"); + } else { + content = "返回状态码:" + httpResponse.getStatusLine() + "。" + EntityUtils.toString(httpResponse.getEntity()); + } + close(httpResponse); + httpCline.close(); + return content; + } + + + /** + * 初始化https对象(带证书) + * + * @param key 证书密码 + * @param certPath 证书路径 + * @param certType 证书类型 + * @throws Exception + */ + private static CloseableHttpClient initCert(String key, String certPath, String certType) throws Exception { + KeyStore keyStore = KeyStore.getInstance(certType); + InputStream inputStream = new FileInputStream(new File(certPath)); + try { + keyStore.load(inputStream, key.toCharArray()); + } finally { + inputStream.close(); + } + SSLContext sslcontext = SSLContexts.custom().loadKeyMaterial(keyStore, key.toCharArray()).build(); + SSLConnectionSocketFactory sslsf = + new SSLConnectionSocketFactory(sslcontext, new String[]{"TLSv1"}, null, + SSLConnectionSocketFactory.BROWSER_COMPATIBLE_HOSTNAME_VERIFIER); + return HttpClients.custom().setSSLSocketFactory(sslsf).build(); + } + + + /** + * 关闭资源 + */ + private static void close(CloseableHttpResponse httpResponse) { + try { + if (null != httpResponse) { + EntityUtils.consume(httpResponse.getEntity());//此处高能,通过源码分析,由EntityUtils是否回收HttpEntity + httpResponse.close(); + } + } catch (Exception e) { + e.printStackTrace(); + } finally { + try { + if (null != httpResponse) { + httpResponse.close(); + } + } catch (Exception e) { + e.printStackTrace(); + } + } + } + + +} diff --git a/cloud-server-management/src/main/java/com/dsh/guns/modular/system/controller/util/HttpResult.java b/cloud-server-management/src/main/java/com/dsh/guns/modular/system/controller/util/HttpResult.java new file mode 100644 index 0000000..e977064 --- /dev/null +++ b/cloud-server-management/src/main/java/com/dsh/guns/modular/system/controller/util/HttpResult.java @@ -0,0 +1,32 @@ +package com.dsh.guns.modular.system.controller.util; + +import lombok.Data; + +/** + * http请求返回封装 + */ +@Data +public class HttpResult { + /** + * 返回状态码 + */ + private Integer code; + /** + * 返回结果 + */ + private String data; + + /** + * 返回封装结果 + * + * @param code + * @param data + * @return + */ + public static HttpResult getHttpResult(Integer code, String data) { + HttpResult httpResult = new HttpResult(); + httpResult.setCode(code); + httpResult.setData(data); + return httpResult; + } +} diff --git a/cloud-server-management/src/main/java/com/dsh/guns/modular/system/controller/util/MD5AndKL.java b/cloud-server-management/src/main/java/com/dsh/guns/modular/system/controller/util/MD5AndKL.java new file mode 100644 index 0000000..20a0684 --- /dev/null +++ b/cloud-server-management/src/main/java/com/dsh/guns/modular/system/controller/util/MD5AndKL.java @@ -0,0 +1,111 @@ +package com.dsh.guns.modular.system.controller.util; + +import java.security.MessageDigest; + +public class MD5AndKL { + + /** + * MD5加码。32位 + * + * @param inStr + * @return + */ + public static String MD5(String inStr) { + MessageDigest md5 = null; + try { + md5 = MessageDigest.getInstance("MD5"); + } catch (Exception e) { + throw new RuntimeException(e.toString()); + } + byte[] md5Bytes = md5.digest(inStr.getBytes()); + StringBuffer hexValue = new StringBuffer(); + for (int i = 0; i < md5Bytes.length; i++) { + int val = ((int) md5Bytes[i]) & 0xff; + if (val < 16) { + hexValue.append("0"); + } + hexValue.append(Integer.toHexString(val)); + } + return hexValue.toString(); + } + + /** + * 可逆的加密算法 + * + * @param inStr + * @return + */ + public static String KL(String inStr) { + char[] a = inStr.toCharArray(); + for (int i = 0; i < a.length; i++) { + a[i] = (char) (a[i] ^ 't'); + } + String s = new String(a); + return s; + } + + /** + * 加密后解密 + * + * @param inStr + * @return + */ + public static String JM(String inStr) { + char[] a = inStr.toCharArray(); + for (int i = 0; i < a.length; i++) { + a[i] = (char) (a[i] ^ 't'); + } + String k = new String(a); + return k; + } + + + public static String byteArrayToHexString(byte b[]) { + StringBuffer resultSb = new StringBuffer(); + for (int i = 0; i < b.length; i++) + resultSb.append(byteToHexString(b[i])); + + return resultSb.toString(); + } + + private static String byteToHexString(byte b) { + int n = b; + if (n < 0) + n += 256; + int d1 = n / 16; + int d2 = n % 16; + return hexDigits[d1] + hexDigits[d2]; + } + + public static String MD5Encode(String origin, String charsetname) { + String resultString = null; + try { + resultString = new String(origin); + MessageDigest md = MessageDigest.getInstance("MD5"); + if (charsetname == null || "".equals(charsetname)) { + resultString = byteArrayToHexString(md.digest(resultString.getBytes())); + } else { + resultString = byteArrayToHexString(md.digest(resultString.getBytes(charsetname))); + } + } catch (Exception exception) { + exception.printStackTrace(); + } + return resultString; + } + + private static final String hexDigits[] = {"0", "1", "2", "3", "4", "5", + "6", "7", "8", "9", "a", "b", "c", "d", "e", "f"}; + +// public static void main(String args[]) { +// +// System.out.println("MD5后再加密:" + KL(MD5("123456"))); +// System.out.println(MD5("123456")); +// // System.out.println("加密:" + KL(MD5("123456"))); +// // s = KL(s); +// // System.out.println("解密:" + KL("81dc9bdb52d04dc20036dbd8313ed055")); +// // System.out.println("解密:" + JM(KL(s))); +// // System.out.println("解密为MD5后的:" + KL(KL(MD5(s)))); +// // System.out.println(JM("5d62957bb57d3e49dcf48a0df064be4c")); +// // System.out.println(MD5AndKL.KL(MD5AndKL.MD5("admin"+"87654321"))); +// } +} diff --git a/cloud-server-management/src/main/java/com/dsh/guns/modular/system/model/OperatorAuth.java b/cloud-server-management/src/main/java/com/dsh/guns/modular/system/model/OperatorAuth.java index 446f112..8649591 100644 --- a/cloud-server-management/src/main/java/com/dsh/guns/modular/system/model/OperatorAuth.java +++ b/cloud-server-management/src/main/java/com/dsh/guns/modular/system/model/OperatorAuth.java @@ -21,8 +21,6 @@ private Integer operatorId; @TableField(value = "bodyType") private String bodyType; - @TableField(value = "type") - private Integer type; @TableField(value = "businessName") private String businessName; @TableField(value = "businessNumber") @@ -49,10 +47,16 @@ private String legalAddress; @TableField(value = "legalFront") private String legalFront; + @TableField(value = "merchantNumber") + private String merchantNumber; @TableField(value = "legalBack") private String legalBack; + @TableField(value = "aliasName") + private String aliasName; @TableField(value = "accountType") private Integer accountType; + @TableField(value = "auditState") + private Integer auditState; @TableField(value = "bank") private String bank; @TableField(value = "accountName") @@ -69,27 +73,11 @@ private String bankName; @TableField(value = "bankNumber") private String bankNumber; - @TableField(value = "auditState") - private Integer auditState; - @TableField(value = "isBeneficiary") - private String isBeneficiary; - @TableField(value = "beneficiary") - private String beneficiary; - @TableField(value = "beneficiaryNumber") - private String beneficiaryNumber; - @TableField(value = "beneficiaryAddress") - private String beneficiaryAddress; - @TableField(value = "beneficiaryTerm") - private String beneficiaryTerm; - @TableField(value = "beneficiaryFront") - private String beneficiaryFront; - @TableField(value = "beneficiaryBack") - private String beneficiaryBack; + @TableField(value = "bankCardTwo") + private String bankCardTwo; @TableField(value = "refuseReason") private String refuseReason; - @TableField(value = "remark") - private String remark; @TableField(value = "outBizNo") private String outBizNo; @TableField(value = "name") @@ -102,13 +90,32 @@ private String businessEnd; @TableField(value = "legalEnd") private String legalEnd; - @TableField(value = "beneficiaryEnd") - private String beneficiaryEnd; @TableField(value = "orderNo") private String orderNo; - @TableField(value = "orderStatus") - private String orderStatus; - @TableField(value = "qrCode") - private String qrCode; + @TableField(value = "legalValidationUrl") + private String legalValidationUrl; + @TableField(value = "applymentState") + private String applymentState; + @TableField(value = "signUrl") + private String signUrl; + @TableField(value = "signState") + private String signState; + + @TableField(value = "isBenefits") + private String isBenefits; + @TableField(value = "benefitsName") + private String benefitsName; + @TableField(value = "benefitsFront") + private String benefitsFront; + @TableField(value = "benefitsBack") + private String benefitsBack; + @TableField(value = "benefitsNumber") + private String benefitsNumber; + @TableField(value = "benefitsStartTime") + private String benefitsStartTime; + @TableField(value = "benefitsEndTime") + private String benefitsEndTime; + @TableField(value = "benefitsAddress") + private String benefitsAddress; } diff --git a/cloud-server-management/src/main/java/com/dsh/guns/modular/system/model/TOperator.java b/cloud-server-management/src/main/java/com/dsh/guns/modular/system/model/TOperator.java index 9e1d4e5..e3d98a7 100644 --- a/cloud-server-management/src/main/java/com/dsh/guns/modular/system/model/TOperator.java +++ b/cloud-server-management/src/main/java/com/dsh/guns/modular/system/model/TOperator.java @@ -30,6 +30,16 @@ private Integer id; private String name; + /** + * 微信商户号 + */ + @TableField("merchantNumber") + private String merchantNumber; + /** + * 微信商户全称 + */ + @TableField("merchantName") + private String merchantName; @TableField("userId") private Integer userId; diff --git a/cloud-server-management/src/main/java/com/dsh/guns/modular/system/service/IOperatorAuthWxService.java b/cloud-server-management/src/main/java/com/dsh/guns/modular/system/service/IOperatorAuthWxService.java new file mode 100644 index 0000000..c712353 --- /dev/null +++ b/cloud-server-management/src/main/java/com/dsh/guns/modular/system/service/IOperatorAuthWxService.java @@ -0,0 +1,12 @@ +package com.dsh.guns.modular.system.service; + +import com.baomidou.mybatisplus.extension.service.IService; +import com.dsh.guns.modular.system.model.OperatorAuth; +import com.dsh.guns.modular.system.model.OperatorAuthAlipay; + +/** + * @author zhibing.pu + * @Date 2023/8/1 17:49 + */ +public interface IOperatorAuthWxService extends IService<OperatorAuth> { +} diff --git a/cloud-server-management/src/main/java/com/dsh/guns/modular/system/service/TOperatorService.java b/cloud-server-management/src/main/java/com/dsh/guns/modular/system/service/TOperatorService.java index 6a4fce6..1b8806a 100644 --- a/cloud-server-management/src/main/java/com/dsh/guns/modular/system/service/TOperatorService.java +++ b/cloud-server-management/src/main/java/com/dsh/guns/modular/system/service/TOperatorService.java @@ -6,6 +6,7 @@ import com.dsh.guns.modular.system.model.Bank; import com.dsh.guns.modular.system.model.CoachChangeStateVO; import com.dsh.guns.modular.system.model.TOperator; +import com.wechat.pay.java.service.profitsharing.model.AddReceiverResponse; import java.util.List; import java.util.Map; @@ -25,4 +26,5 @@ int changeState(CoachChangeStateVO vo); List<Bank> getBankList(); + } diff --git a/cloud-server-management/src/main/java/com/dsh/guns/modular/system/service/impl/TOperatorAuthWxServiceImpl.java b/cloud-server-management/src/main/java/com/dsh/guns/modular/system/service/impl/TOperatorAuthWxServiceImpl.java new file mode 100644 index 0000000..df5ba04 --- /dev/null +++ b/cloud-server-management/src/main/java/com/dsh/guns/modular/system/service/impl/TOperatorAuthWxServiceImpl.java @@ -0,0 +1,24 @@ +package com.dsh.guns.modular.system.service.impl; + + +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.dsh.course.mapper.TOperatorAuthMapper; +import com.dsh.course.mapper.TOperatorAuthWxMapper; +import com.dsh.guns.modular.system.model.OperatorAuth; +import com.dsh.guns.modular.system.model.OperatorAuthAlipay; +import com.dsh.guns.modular.system.service.IOperatorAuthService; +import com.dsh.guns.modular.system.service.IOperatorAuthWxService; +import org.springframework.stereotype.Service; + +/** + * <p> + * 服务实现类 + * </p> + * + * @author administrator + * @since 2023-09-19 + */ +@Service +public class TOperatorAuthWxServiceImpl extends ServiceImpl<TOperatorAuthWxMapper, OperatorAuth> implements IOperatorAuthWxService { + +} diff --git a/cloud-server-management/src/main/java/com/dsh/guns/modular/system/service/impl/TOperatorServiceImpl.java b/cloud-server-management/src/main/java/com/dsh/guns/modular/system/service/impl/TOperatorServiceImpl.java index c5e4878..9ba12d6 100644 --- a/cloud-server-management/src/main/java/com/dsh/guns/modular/system/service/impl/TOperatorServiceImpl.java +++ b/cloud-server-management/src/main/java/com/dsh/guns/modular/system/service/impl/TOperatorServiceImpl.java @@ -1,18 +1,31 @@ package com.dsh.guns.modular.system.service.impl; +import com.baomidou.mybatisplus.extension.api.R; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.dsh.course.mapper.TOperatorMapper; +import com.dsh.guns.core.exception.ServiceException; import com.dsh.guns.modular.system.model.Bank; import com.dsh.guns.modular.system.model.CoachChangeStateVO; import com.dsh.guns.modular.system.model.TOperator; import com.dsh.guns.modular.system.service.TOperatorService; +import com.wechat.pay.java.service.profitsharing.ProfitsharingService; +import com.wechat.pay.java.service.profitsharing.model.AddReceiverRequest; +import com.wechat.pay.java.service.profitsharing.model.AddReceiverResponse; +import com.wechat.pay.java.service.profitsharing.model.ReceiverRelationType; +import com.wechat.pay.java.service.profitsharing.model.ReceiverType; +import lombok.RequiredArgsConstructor; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; +import javax.annotation.Resource; +import java.security.MessageDigest; +import java.security.NoSuchAlgorithmException; import java.util.List; import java.util.Map; +import java.util.SortedMap; +import java.util.TreeMap; /** * <p> @@ -24,7 +37,6 @@ */ @Service public class TOperatorServiceImpl extends ServiceImpl<TOperatorMapper, TOperator> implements TOperatorService { - @Autowired private TOperatorMapper tOperatorMapper; @Override @@ -42,4 +54,7 @@ return tOperatorMapper.getBankList(); } + + + } diff --git a/cloud-server-management/src/main/java/com/dsh/guns/modular/system/service/impl/TOperatorUserServiceImpl.java b/cloud-server-management/src/main/java/com/dsh/guns/modular/system/service/impl/TOperatorUserServiceImpl.java index 4f67843..63bfe51 100644 --- a/cloud-server-management/src/main/java/com/dsh/guns/modular/system/service/impl/TOperatorUserServiceImpl.java +++ b/cloud-server-management/src/main/java/com/dsh/guns/modular/system/service/impl/TOperatorUserServiceImpl.java @@ -17,7 +17,6 @@ import com.dsh.guns.modular.system.service.IOperatorAuthService; import com.dsh.guns.modular.system.service.IOperatorUserService; import com.dsh.guns.modular.system.service.ITStudentService; -import com.dsh.guns.modular.system.util.WeChatUtil; import com.github.binarywang.wxpay.bean.ecommerce.ApplymentsResult; import com.github.binarywang.wxpay.service.EcommerceService; import com.github.binarywang.wxpay.service.WxPayService; @@ -46,8 +45,8 @@ private IOperatorAuthService operatorAuthService; @Autowired private TOperatorMapper operatorMapper; - @Autowired - private WeChatUtil weChatUtil; +// @Autowired +// private WeChatUtil weChatUtil; // @Override // public void mgtShopAuth(MgtShopAuthDto mgtShopAuthDto) { diff --git a/cloud-server-management/src/main/java/com/dsh/guns/modular/system/util/HttpRequestUtil.java b/cloud-server-management/src/main/java/com/dsh/guns/modular/system/util/HttpRequestUtil.java index f63c573..5adbfaa 100644 --- a/cloud-server-management/src/main/java/com/dsh/guns/modular/system/util/HttpRequestUtil.java +++ b/cloud-server-management/src/main/java/com/dsh/guns/modular/system/util/HttpRequestUtil.java @@ -53,7 +53,39 @@ e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); - } + } + return result; + }/*** + * get请求(带参数) + * @param url + * @return String + */ + public static String getReq1(String url, Map<String, String> params) { + String result = null; + try { + URIBuilder uriBuilder = new URIBuilder(url); + Iterator maplist = params.entrySet().iterator(); + while (maplist.hasNext()) { + Map.Entry<String, String> map = (Map.Entry<String, String>) maplist.next(); + uriBuilder.addParameter(map.getKey(), map.getValue()); + } + CloseableHttpClient client = HttpClientBuilder.create().build(); + HttpPost get = new HttpPost(uriBuilder.build()); + // todo 验签 + get.setHeader("Authorization", "close"); + get.setHeader("Content-Type", "application/json"); + get.setHeader("Accept", "application/json"); + get.addHeader("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.81 Safari/537.36"); + HttpResponse response = client.execute(get); + result = EntityUtils.toString(response.getEntity(), "UTF-8"); + + } catch (URISyntaxException e) { + e.printStackTrace(); + } catch (ClientProtocolException e) { + e.printStackTrace(); + } catch (IOException e) { + e.printStackTrace(); + } return result; } public static String postRequest(String url, Map<String, String> params) { @@ -96,7 +128,49 @@ } return result; } - + public static String postRequest1(String url, Map<String, Object> params) { + // 构造HttpClient的实例 + HttpClient httpClient = new HttpClient(); + // 创建POST方法的实例 + PostMethod postMethod = new PostMethod(url); + // 设置请求头信息 + postMethod.setRequestHeader("Authorization", "close"); + postMethod.setRequestHeader("Accept", "application/json"); + postMethod.addRequestHeader("Content-Type", "application/json"); + postMethod.addRequestHeader("Wechatpay-Serial", "application/json"); + postMethod.setRequestHeader("Connection", "close"); + // 添加参数 + for (Map.Entry<String, Object> entry : params.entrySet()) { + postMethod.addParameter(entry.getKey(), entry.getValue().toString()); + } + // 使用系统提供的默认的恢复策略,设置请求重试处理,用的是默认的重试处理:请求三次 + httpClient.getParams().setBooleanParameter("http.protocol.expect-continue", false); + // 接收处理结果 + String result = null; + try { + // 执行Http Post请求 + httpClient.executeMethod(postMethod); + // 返回处理结果 + result = postMethod.getResponseBodyAsString(); + } catch (HttpException e) { + // 发生致命的异常,可能是协议不对或者返回的内容有问题 + System.out.println("请检查输入的URL!"); + e.printStackTrace(); + } catch (IOException e) { + // 发生网络异常 + System.out.println("发生网络异常!"); + e.printStackTrace(); + } finally { + // 释放链接 + postMethod.releaseConnection(); + // 关闭HttpClient实例 + if (httpClient != null) { + ((SimpleHttpConnectionManager) httpClient.getHttpConnectionManager()).shutdown(); + httpClient = null; + } + } + return result; + } public static String getRequest(String url, Map<String, String> params) { // 构造HttpClient实例 HttpClient client = new HttpClient(); diff --git a/cloud-server-management/src/main/java/com/dsh/guns/modular/system/util/PayMoneyUtil.java b/cloud-server-management/src/main/java/com/dsh/guns/modular/system/util/PayMoneyUtil.java index db0815e..dc0f498 100644 --- a/cloud-server-management/src/main/java/com/dsh/guns/modular/system/util/PayMoneyUtil.java +++ b/cloud-server-management/src/main/java/com/dsh/guns/modular/system/util/PayMoneyUtil.java @@ -12,6 +12,9 @@ import com.alipay.api.request.*; import com.alipay.api.response.*; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.dsh.course.util.UUIDUtil; +import com.dsh.guns.modular.system.controller.util.HttpClientUtil; +import com.dsh.guns.modular.system.controller.util.MD5AndKL; import com.dsh.guns.modular.system.model.OperatorAuthAlipay; import com.dsh.guns.modular.system.model.OperatorUser; import com.dsh.guns.modular.system.service.IOperatorAuthService; @@ -22,11 +25,18 @@ import org.dom4j.Element; import org.dom4j.io.SAXReader; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.HttpHeaders; +import org.springframework.http.MediaType; import org.springframework.stereotype.Component; +import javax.crypto.Mac; +import javax.crypto.spec.SecretKeySpec; import javax.servlet.http.HttpServletRequest; import java.io.*; import java.util.*; + +import static com.dsh.guns.modular.system.controller.util.MD5AndKL.byteArrayToHexString; + /** * 第三方支付工具类 */ @@ -40,13 +50,15 @@ private String alipay_public_key = "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAmu8n/4yTHWbn7VOrNc9OsLtDL1bEQ8gC1dHkj8Wy5z0mkaOsjJRIG/28ze12M0V8jdCKuuDr5Z1OPKiqf+XO3ypguEh+mYUVMBM/cZodDFQfTY1TKLWjvQCuaqlA+QUTCK6f7T7stsgyQ1o9Jj0rXZDz6PM4QHSTzjrLIBaeqM5WIBvH+fy/X+QG5Utd+/UT0kc0JyvuKhZ65yVUd/C9VcwJJAPliRsAQNrqYterwAJ9zvw9tF11wj9W0XgJ8Ccu4x3gR1vrlLRJJo/OA97RmxPQ+5hSacWQZCUd1dwiBq+YCrKVHGTj14izRHXrLc0yBlRXo7tBOIqcy3IsvKVthQIDAQAB";//支付宝支付公钥 - private String appid = "";//微信appid + private String smid = "2088330203191220";//平台支付宝商户号... - private String appletsAppid = "";//微信小程序appid + private String appid = "wx41d32f362ba0f911";//微信appid - private String mchId = "";//微信商户号 + private String appSecret = "cf0ebf950f5926a69041a0e2bbe20f3e"; - private String key = "";//微信商户号 + private String mchId = "1501481761";//微信商户号 + + private String key = "6f5e0c2dcabfa9c27b5da5836a362fef";//微信商户号 private String callbackPath = "https://online.daowepark.com:443/account";//支付回调网关地址 @@ -66,6 +78,269 @@ private IOperatorUserService operatorUserService; /** + * 添加分账接收方 + * @param number 商户号或者openId + * @param name 商户全称或者个人姓名 + * @return + */ + public ResultUtil addReceiver(String number,String name) throws Exception { + Map<String, Object> map = new HashMap<>(); + map.put("mch_id", mchId); + map.put("appid", appid); + String nonce_str = UUIDUtil.getRandomCode(16); + map.put("nonce_str", nonce_str); + // 将这个字符串使用json格式拼接起来 + Map<String, Object> body = new HashMap<>(); + body.put("type", "MERCHANT_ID"); + body.put("account", number); + body.put("name", name); + body.put("relation_type", "PARTNER"); + JSONObject jsonObject = new JSONObject(body); + String jsonString = jsonObject.toString(); + map.put("receiver",jsonString ); + String s = this.weixinSignature(map); + map.put("sign", s); + String url = "https://api.mch.weixin.qq.com/pay/profitsharingaddreceiver"; + //设置请求头 + HttpHeaders headers = new HttpHeaders(); + headers.setContentType(MediaType.APPLICATION_XML); + StringBuffer xmlString = new StringBuffer(); + Set<String> strings = map.keySet(); + String[] keys = {}; + keys = strings.toArray(keys); + Arrays.sort(keys); + xmlString.append("<xml>"); + for (int l = 0; l < keys.length; l++) { + xmlString.append("<" + keys[l] + ">" + map.get(keys[l]) + "</" + keys[l] + ">"); + } + xmlString.append("</xml>"); + + Map<String, String> map1 = null; + String body1 = null; + try { + body1 = HttpClientUtil.pushHttpRequsetXml(url, xmlString.toString(), new HashMap<>()).getData(); + } catch (Exception e) { + e.printStackTrace(); + } + //将结果xml解析成map + body1 = body1.replaceAll("<!\\[CDATA\\[", ""); + body1 = body1.replaceAll("]]>", ""); + try { + map1 = this.xmlToMap(body1, "UTF-8"); + } catch (UnsupportedEncodingException e) { + e.printStackTrace(); + } catch (DocumentException e) { + e.printStackTrace(); + } + String return_code = map1.get("return_code"); + if ("SUCCESS".equals(return_code)) { + String result_code = map1.get("result_code"); + if ("SUCCESS".equals(result_code)) { + return ResultUtil.success(); + } else { +// System.err.println(map1.get("err_code_des")); + return ResultUtil.error(map1.get("err_code_des")); + } + } else { +// System.err.println(map1.get("return_msg") + appid + "----" + mchId); + return ResultUtil.error(map1.get("return_msg"), new JSONObject()); + } + } + /** + * 发起分账 + * @param order 微信订单号 + * @return + */ + public ResultUtil fenzhang(String order) throws Exception { + Map<String, Object> map = new HashMap<>(); + map.put("mch_id", mchId); + map.put("appid", appid); + String nonce_str = UUIDUtil.getRandomCode(16); + map.put("nonce_str", nonce_str); + map.put("transaction_id", order); + // 将这个字符串使用json格式拼接起来 + Map<String, Object> body = new HashMap<>(); + body.put("type", "MERCHANT_ID"); + // todo 分账接收方 计算分账金额 + body.put("account", "1233"); + body.put("amount", "0"); + body.put("description", "订单分账"); + JSONObject jsonObject = new JSONObject(body); + String jsonString = jsonObject.toString(); + map.put("receiver",jsonString); + String s = this.weixinSignature(map); + map.put("sign", s); + String url = "https://api.mch.weixin.qq.com/secapi/pay/profitsharing"; + //设置请求头 + HttpHeaders headers = new HttpHeaders(); + headers.setContentType(MediaType.APPLICATION_XML); + StringBuffer xmlString = new StringBuffer(); + Set<String> strings = map.keySet(); + String[] keys = {}; + keys = strings.toArray(keys); + Arrays.sort(keys); + xmlString.append("<xml>"); + for (int l = 0; l < keys.length; l++) { + xmlString.append("<" + keys[l] + ">" + map.get(keys[l]) + "</" + keys[l] + ">"); + } + xmlString.append("</xml>"); + + Map<String, String> map1 = null; + String body1 = null; + try { + body1 = HttpClientUtil.pushHttpRequsetXml(url, xmlString.toString(), new HashMap<>()).getData(); + } catch (Exception e) { + e.printStackTrace(); + } + //将结果xml解析成map + body1 = body1.replaceAll("<!\\[CDATA\\[", ""); + body1 = body1.replaceAll("]]>", ""); + try { + map1 = this.xmlToMap(body1, "UTF-8"); + } catch (UnsupportedEncodingException e) { + e.printStackTrace(); + } catch (DocumentException e) { + e.printStackTrace(); + } + String return_code = map1.get("return_code"); + if ("SUCCESS".equals(return_code)) { + String result_code = map1.get("result_code"); + if ("SUCCESS".equals(result_code)) { + return ResultUtil.success(); + } else { +// System.err.println(map1.get("err_code_des")); + return ResultUtil.error(map1.get("err_code_des")); + } + } else { +// System.err.println(map1.get("return_msg") + appid + "----" + mchId); + return ResultUtil.error(map1.get("return_msg"), new JSONObject()); + } + } + /** + * 删除分账接收方 + * @param number 商户号或者openId + * @param name 商户全称或者个人姓名 + * @return + */ + public ResultUtil deleteReceiver(String number,String name) throws Exception { + Map<String, Object> map = new HashMap<>(); + map.put("mch_id", mchId); + map.put("appid", appid); + String nonce_str = UUIDUtil.getRandomCode(16); + map.put("nonce_str", nonce_str); + // 将这个字符串使用json格式拼接起来 + Map<String, Object> body = new HashMap<>(); + body.put("type", "MERCHANT_ID"); + body.put("account", number); + body.put("name", name); + body.put("relation_type", "PARTNER"); + JSONObject jsonObject = new JSONObject(body); + String jsonString = jsonObject.toString(); + map.put("receiver",jsonString ); + String s = this.weixinSignature(map); + map.put("sign", s); + String url = "https://api.mch.weixin.qq.com/pay/profitsharingaddreceiver"; + //设置请求头 + HttpHeaders headers = new HttpHeaders(); + headers.setContentType(MediaType.APPLICATION_XML); + StringBuffer xmlString = new StringBuffer(); + Set<String> strings = map.keySet(); + String[] keys = {}; + keys = strings.toArray(keys); + Arrays.sort(keys); + xmlString.append("<xml>"); + for (int l = 0; l < keys.length; l++) { + xmlString.append("<" + keys[l] + ">" + map.get(keys[l]) + "</" + keys[l] + ">"); + } + xmlString.append("</xml>"); + + Map<String, String> map1 = null; + String body1 = null; + try { + body1 = HttpClientUtil.pushHttpRequsetXml(url, xmlString.toString(), new HashMap<>()).getData(); + } catch (Exception e) { + e.printStackTrace(); + } + //将结果xml解析成map + body1 = body1.replaceAll("<!\\[CDATA\\[", ""); + body1 = body1.replaceAll("]]>", ""); + try { + map1 = this.xmlToMap(body1, "UTF-8"); + } catch (UnsupportedEncodingException e) { + e.printStackTrace(); + } catch (DocumentException e) { + e.printStackTrace(); + } + String return_code = map1.get("return_code"); + if ("SUCCESS".equals(return_code)) { + String result_code = map1.get("result_code"); + if ("SUCCESS".equals(result_code)) { + return ResultUtil.success(); + } else { +// System.err.println(map1.get("err_code_des")); + return ResultUtil.error(map1.get("err_code_des")); + } + } else { +// System.err.println(map1.get("return_msg") + appid + "----" + mchId); + return ResultUtil.error(map1.get("return_msg"), new JSONObject()); + } + } + /** + * 微信下单的签名算法 + * + * @param map + * @return + */ + private String weixinSignature(Map<String, Object> map) { + try { + Set<Map.Entry<String, Object>> entries = map.entrySet(); + List<Map.Entry<String, Object>> infoIds = new ArrayList<Map.Entry<String, Object>>(entries); + // 对所有传入参数按照字段名的 ASCII 码从小到大排序(字典序) + Collections.sort(infoIds, new Comparator<Map.Entry<String, Object>>() { + public int compare(Map.Entry<String, Object> o1, Map.Entry<String, Object> o2) { + return (o1.getKey()).toString().compareTo(o2.getKey()); + } + }); + // 构造签名键值对的格式 + StringBuilder sb = new StringBuilder(); + for (Map.Entry<String, Object> item : infoIds) { + if (item.getKey() != null || item.getKey() != "") { + String key = item.getKey(); + Object val = item.getValue(); + if (!(val == "" || val == null)) { + sb.append(key + "=" + val + "&"); + } + } + } + sb.append("key=" + key); + String sign = sha256_HMAC(sb.toString(), key).toUpperCase(); + return sign; + } catch (Exception e) { + e.printStackTrace(); + } + return null; + } + /** + * sha256_HMAC加密 + * @param message 消息 + * @param secret 秘钥 + * @return 加密后字符串 + */ + public String sha256_HMAC(String message, String secret) { + String hash = ""; + try { + Mac sha256_HMAC = Mac.getInstance("HmacSHA256"); + SecretKeySpec secret_key = new SecretKeySpec(secret.getBytes(), "HmacSHA256"); + sha256_HMAC.init(secret_key); + byte[] bytes = sha256_HMAC.doFinal(message.getBytes()); + hash = byteArrayToHexString(bytes); + } catch (Exception e) { + System.out.println("Error HmacSHA256 ===========" + e.getMessage()); + } + return hash; + } + + /** * 处理直付通审核通过和拒绝消息 */ public void getMessage() { diff --git a/cloud-server-management/src/main/java/com/dsh/guns/modular/system/util/TaskUtil.java b/cloud-server-management/src/main/java/com/dsh/guns/modular/system/util/TaskUtil.java index 146c8b4..60b077b 100644 --- a/cloud-server-management/src/main/java/com/dsh/guns/modular/system/util/TaskUtil.java +++ b/cloud-server-management/src/main/java/com/dsh/guns/modular/system/util/TaskUtil.java @@ -1,8 +1,20 @@ package com.dsh.guns.modular.system.util; +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONObject; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.dsh.guns.modular.system.model.OperatorAuth; +import com.dsh.guns.modular.system.model.OperatorAuthAlipay; +import com.dsh.guns.modular.system.model.OperatorUser; +import com.dsh.guns.modular.system.model.TOperator; +import com.dsh.guns.modular.system.service.*; +import org.springframework.beans.factory.annotation.Autowired; import org.springframework.scheduling.annotation.Scheduled; import org.springframework.stereotype.Component; + +import java.util.HashMap; +import java.util.List; /** @@ -10,12 +22,131 @@ */ @Component public class TaskUtil { + @Autowired + private TOperatorService operatorService; + @Autowired + private TOperatorCityService operatorCityService; + @Autowired + private IOperatorAuthService operatorAuthService; + @Autowired + private IOperatorAuthWxService operatorAuthWxService; + @Autowired + private IOperatorUserService operatorUserService; + // 每隔5分钟执行一次 查询商户支付宝和微信绑定状态 + @Scheduled(fixedRate = 5 * 60 * 1000) + public void queryWxAndZfbState() { + // 支付宝 + List<OperatorAuthAlipay> list = operatorAuthService.list(); + for (OperatorAuthAlipay operatorAuthAlipay : list) { + OperatorUser operatorId = operatorUserService.getOne(new QueryWrapper<OperatorUser>() + .eq("operatorId", operatorAuthAlipay.getOperatorId())); + if (operatorId == null)return; + operatorId.setAlipayAudit(operatorAuthAlipay.getAuditState()); + operatorUserService.updateById(operatorId); + } + // 微信 + List<OperatorAuth> list1 = operatorAuthWxService.list(); + for (OperatorAuth operatorAuth : list1) { + OperatorUser operatorId = operatorUserService.getOne(new QueryWrapper<OperatorUser>() + .eq("operatorId", operatorAuth.getOperatorId())); + if (operatorId == null)return; + operatorId.setWechatAudit(operatorAuth.getAuditState()); + operatorUserService.updateById(operatorId); + } + } + // 每隔5分钟执行一次 查询商户支付宝和微信绑定状态 如果两者都进件成功 那么修改t_operator表为商户绑定成功状态 + @Scheduled(fixedRate = 5 * 60 * 1000) + public void queryOperatorState() { + List<TOperator> list2 = operatorService.list(); + for (TOperator tOperator : list2) { + OperatorUser operatorId = operatorUserService.getOne(new QueryWrapper<OperatorUser>() + .eq("operatorId", tOperator.getId())); + if (operatorId == null)return; + if (operatorId.getAlipayAudit() == 2 && operatorId.getWechatAudit() == 2){ + tOperator.setState(2); + operatorService.updateById(tOperator); + } + } + } + @Scheduled(fixedRate = 1 * 60 * 1000) + public void queryOperatorState1() { + List<OperatorAuth> list = operatorAuthWxService.list(); + for (OperatorAuth operatorAuth : list) { + queryState(operatorAuth.getOrderNo()); + } + } + /** + * 查询进件申请单审核状态 + */ + public JSONObject queryState(String orderNo) { + String url = "https://api.mch.weixin.qq.com/v3/ecommerce/applyments/out-request-no/"+orderNo; + String req1 = HttpRequestUtil.getReq1(url, new HashMap<>()); + System.err.println("查询申请单审核状态字符串"+req1); + JSONObject jsonObject = JSON.parseObject(req1); + System.err.println("查询申请单审核状态Json"+jsonObject); + String applymentState = jsonObject.getString("applyment_state"); + String outBizNo = jsonObject.getString("out_request_no"); + OperatorAuth operatorAuth = operatorAuthWxService.getOne( + new QueryWrapper<OperatorAuth>() + .eq("outBizNo", outBizNo)); + if (operatorAuth == null)return null; - - + OperatorUser operatorUser = operatorUserService.getOne(new QueryWrapper<OperatorUser>() + .eq("operatorId", operatorAuth.getOperatorId())); + // 审核状态 + operatorAuth.setApplymentState(applymentState); + if (applymentState.equals("REJECTED") || applymentState.equals("FROZEN")){ + operatorUser.setWechatAudit(3); + operatorAuth.setAuditState(2); + // 如果被拒 赋值拒绝原因 + operatorAuth.setRefuseReason(jsonObject.getJSONObject("audit_detail").getString("reject_reason")); + } + if (applymentState.equals("NEED_SIGN")){ + operatorAuth.setSignUrl(jsonObject.getString("sign_url")); + operatorAuth.setMerchantNumber(jsonObject.getString("sub_mchid")); + } + if (applymentState.equals("FINISH")){ + operatorAuth.setMerchantNumber(jsonObject.getString("sub_mchid")); + operatorUser.setWechatAudit(2); + operatorAuth.setAuditState(1); + } + if (applymentState.equals("ACCOUNT_NEED_VERIFY")){ + operatorAuth.setLegalValidationUrl(jsonObject.getString("legal_validation_url")); + } + return jsonObject; + /** + * { + * "applyment_state" : "FINISH", + * "applyment_state_desc" : "审核中", + * "sign_url" : "https://pay.weixin.qq.com/public/apply4ec_sign/s?applymentId=2000002126198476&sign=b207b673049a32c858f3aabd7d27c7ec", + * "sub_mchid" : "1542488631", + * "account_validation" : { + * "account_name" : "aOf7Gk2qT26kakkuTZpbFAn7Mb7xcar0LlQaYoi3+LnnWwgAsfaUUTg9+GmYJq6YCz+RiluWHeHFq1lt8n3eIkF0laVvqmAU80xIWGZgWJnRmnRuZxsg0HJZfnUac2JfqyuL8OoyM2YSuYDqdsyvcOlgUQgq8MPCR6pmvhBCmIeJvnVSm8J+L+yx912itUmTDxhdBlu1CFBIUefME9nYB70vCVTNAVXgURkf65mjHMBiE9Y+wrPZVmTIIz3C3PtPVMZYDEvBT4rDdICA3ZYXshYqeOSslSjSMf+MhhC4oaujiISFzq3AE+as7mAEDJly+DgRuVs74msmKUH8pl+3oA==", + * "account_no" : "aOf7Gk2qT26kakkuTZpbFAn7Mb7xcar0LlQaYoi3+LnnWwgAsfaUUTg9+GmYJq6YCz+RiluWHeHFq1lt8n3eIkF0laVvqmAU80xIWGZgWJnRmnRuZxsg0HJZfnUac2JfqyuL8OoyM2YSuYDqdsyvcOlgUQgq8MPCR6pmvhBCmIeJvnVSm8J+L+yx912itUmTDxhdBlu1CFBIUefME9nYB70vCVTNAVXgURkf65mjHMBiE9Y+wrPZVmTIIz3C3PtPVMZYDEvBT4rDdICA3ZYXshYqeOSslSjSMf+MhhC4oaujiISFzq3AE+as7mAEDJly+DgRuVs74msmKUH8pl+3oA==", + * "pay_amount" : 124, + * "destination_account_number" : "7222223333322332", + * "destination_account_name" : "财付通支付科技有限公司", + * "destination_account_bank" : "招商银行威盛大厦支行", + * "city" : "深圳", + * "remark" : "入驻账户验证", + * "deadline" : "2018-12-10 17:09:01" + * }, + * "audit_detail" : [ + * { + * "param_name" : "id_card_copy", + * "reject_reason" : "身份证背面识别失败,请上传更清晰的身份证图片。" + * } + * ], + * "legal_validation_url" : "https://pay.weixin.qq.com/public/apply4ec_sign/s?applymentId=2000002126198476&sign=b207b673049a32c858f3aabd7d27c7ec", + * "out_request_no" : "APPLYMENT_00000000001", + * "applyment_id" : 2000002124775691, + * "sign_state" : "SIGNED" + * } + */ + } /** * 每月第一天的1点执行的任务 diff --git a/cloud-server-management/src/main/java/com/dsh/guns/modular/system/util/WeChatUtil.java b/cloud-server-management/src/main/java/com/dsh/guns/modular/system/util/WeChatUtil.java index b85e134..0db8e40 100644 --- a/cloud-server-management/src/main/java/com/dsh/guns/modular/system/util/WeChatUtil.java +++ b/cloud-server-management/src/main/java/com/dsh/guns/modular/system/util/WeChatUtil.java @@ -1,168 +1,168 @@ -package com.dsh.guns.modular.system.util; - -import com.alibaba.fastjson.JSON; -import com.alibaba.fastjson.JSONObject; -import com.alipay.api.domain.Shop; -import com.dsh.course.util.UUIDUtil; -import com.dsh.guns.core.util.ToolUtil; -import com.dsh.guns.modular.system.controller.util.UploadUtil; -import com.dsh.guns.modular.system.model.OperatorAuth; -import com.dsh.guns.modular.system.model.TOperator; -import com.dsh.guns.modular.system.model.User; -import com.dsh.guns.modular.system.service.IUserService; -import com.github.binarywang.wxpay.bean.ecommerce.ApplymentsRequest; -import com.github.binarywang.wxpay.bean.ecommerce.ApplymentsResult; -import com.github.binarywang.wxpay.bean.media.ImageUploadResult; -import com.github.binarywang.wxpay.service.EcommerceService; -import com.github.binarywang.wxpay.service.MerchantMediaService; -import com.github.binarywang.wxpay.service.WxPayService; -import lombok.AllArgsConstructor; -import lombok.NoArgsConstructor; -import org.apache.commons.codec.digest.DigestUtils; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.beans.factory.annotation.Value; -import org.springframework.context.annotation.Bean; -import org.springframework.http.*; -import org.springframework.stereotype.Component; -import org.springframework.web.client.RestTemplate; - -import java.io.ByteArrayInputStream; -import java.io.InputStream; -import java.io.UnsupportedEncodingException; -import java.net.URLDecoder; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -/** - * 微信工具类 - */ -@Component -public class WeChatUtil { - - private WxPayService wxService; - - - - /** - * @description 电商二级商户进件(提交申请单) - * @author jqs - * @date 2023/8/11 10:04 - * @param shopAuthentication - * @param applyNumber - * @param operator - * @return ApplymentsResult - */ - - - public ApplymentsResult ecommerceApply(OperatorAuth shopAuthentication, String applyNumber, TOperator operator) throws Exception { - - EcommerceService ecommerceService = wxService.getEcommerceService(); - MerchantMediaService merchantMediaService = wxService.getMerchantMediaService(); - ApplymentsRequest request = new ApplymentsRequest(); - //生成提交类 - request.setOutRequestNo(applyNumber); - if("ENTERPRISE".equals(shopAuthentication.getBodyType())){ - request.setOrganizationType("2"); - }else{ - request.setOrganizationType("4"); - } - //营业执照 - ApplymentsRequest.BusinessLicenseInfo business_license_info = new ApplymentsRequest.BusinessLicenseInfo(); - InputStream blImageIO = OBSUploadUtil.getOBSStream(shopAuthentication.getBusinessPicture().replace("https://obs.ap-southeast-4.myhuaweicloud.com/","")); - ImageUploadResult blImageIR = merchantMediaService.imageUploadV3(blImageIO,applyNumber+"blimage.jpg"); - business_license_info.setBusinessLicenseCopy(blImageIR.getMediaId()); - blImageIO.close(); - business_license_info.setBusinessLicenseNumber(shopAuthentication.getBusinessNumber()); - business_license_info.setMerchantName(shopAuthentication.getBusinessName()); - business_license_info.setLegalPerson(shopAuthentication.getLegalPerson()); - business_license_info.setCompanyAddress(shopAuthentication.getRegisterAddress()); - List<String> businessTimeList = new ArrayList<>(); - businessTimeList.add(0,shopAuthentication.getBusinessTerm()); - businessTimeList.add(1,shopAuthentication.getBusinessEnd()); - if(businessTimeList!=null&&businessTimeList.size()>1){ - String businessTime = JSONObject.toJSONString(businessTimeList); - business_license_info.setBusinessTime(businessTime); - } - request.setBusinessLicenseInfo(business_license_info); - //法人证件 - request.setIdDocType("IDENTIFICATION_TYPE_MAINLAND_IDCARD"); - ApplymentsRequest.IdCardInfo id_card_info = new ApplymentsRequest.IdCardInfo(); - InputStream lpIcFrontIO = OBSUploadUtil.getOBSStream(shopAuthentication.getLegalFront().replace("https://obs.ap-southeast-4.myhuaweicloud.com/","")); - ImageUploadResult lpIcFrontIR = merchantMediaService.imageUploadV3(lpIcFrontIO,applyNumber+"lpIcFront.jpg"); - id_card_info.setIdCardCopy(lpIcFrontIR.getMediaId()); - lpIcFrontIO.close(); - InputStream lpIcBackIO = OBSUploadUtil.getOBSStream(shopAuthentication.getLegalBack().replace("https://obs.ap-southeast-4.myhuaweicloud.com/","")); - ImageUploadResult lpIcBackIR = merchantMediaService.imageUploadV3(lpIcBackIO,applyNumber+"lpIcBack.jpg"); - id_card_info.setIdCardNational(lpIcBackIR.getMediaId()); - lpIcBackIO.close(); - id_card_info.setIdCardName(shopAuthentication.getLegalPerson()); - id_card_info.setIdCardNumber(shopAuthentication.getLeagleNumber()); - if("ENTERPRISE".equals(shopAuthentication.getBodyType())){ - id_card_info.setIdCardAddress(shopAuthentication.getLegalAddress()); - } - id_card_info.setIdCardValidTimeBegin(shopAuthentication.getLegalTerm()); - id_card_info.setIdCardValidTime(shopAuthentication.getLegalEnd()); - request.setIdCardInfo(id_card_info); - //企业填写 - if("ENTERPRISE".equals(shopAuthentication.getBodyType())){ - //受益人 - if("true".equals(shopAuthentication.getIsBeneficiary())){ - request.setOwner(true); - }else{ - request.setOwner(false); - List<ApplymentsRequest.UboInfo> ubo_info_list = new ArrayList<>(); - ApplymentsRequest.UboInfo uboInfo = new ApplymentsRequest.UboInfo(); - uboInfo.setUboIdDocType("IDENTIFICATION_TYPE_MAINLAND_IDCARD"); - InputStream uboIcFrontIO = OBSUploadUtil.getOBSStream(shopAuthentication.getBeneficiaryFront().replace("https://obs.ap-southeast-4.myhuaweicloud.com/","")); - ImageUploadResult uboIcFrontIR = merchantMediaService.imageUploadV3(uboIcFrontIO,applyNumber+"uboIcFront.jpg"); - uboInfo.setUboIdDocCopy(uboIcFrontIR.getMediaId()); - uboIcFrontIO.close(); - InputStream uboIcBackIO = OBSUploadUtil.getOBSStream(shopAuthentication.getBeneficiaryBack().replace("https://obs.ap-southeast-4.myhuaweicloud.com/","")); - ImageUploadResult uboIcBackIR = merchantMediaService.imageUploadV3(uboIcBackIO,applyNumber+"uboIcBack.jpg"); - uboInfo.setUboIdDocCopyBack(uboIcBackIR.getMediaId()); - uboIcBackIO.close(); - uboInfo.setUboIdDocName(shopAuthentication.getBeneficiary()); - uboInfo.setUboIdDocNumber(shopAuthentication.getBeneficiaryNumber()); - uboInfo.setUboIdDocAddress(shopAuthentication.getBeneficiaryAddress()); - uboInfo.setUboIdDocPeriodBegin(shopAuthentication.getBeneficiaryTerm()); - ubo_info_list.add(uboInfo); - request.setUboInfoList(ubo_info_list); - } - } - //结算账户信息 - ApplymentsRequest.AccountInfo accountInfo = new ApplymentsRequest.AccountInfo(); - if(shopAuthentication.getAccountType().equals(1)){ - accountInfo.setBankAccountType("74"); - }else{ - accountInfo.setBankAccountType("75"); - } - accountInfo.setAccountBank(shopAuthentication.getBank()); - accountInfo.setAccountName(shopAuthentication.getAccountName()); - accountInfo.setBankAddressCode(shopAuthentication.getCityCode()); - accountInfo.setBankName(shopAuthentication.getBankName()); - accountInfo.setAccountNumber(shopAuthentication.getBankNumber()); - request.setAccountInfo(accountInfo); - ApplymentsRequest.ContactInfo contactInfo = new ApplymentsRequest.ContactInfo(); - contactInfo.setContactType("65"); - contactInfo.setContactName(shopAuthentication.getLegalPerson()); - contactInfo.setContactIdCardNumber(shopAuthentication.getLeagleNumber()); - contactInfo.setMobilePhone(shopAuthentication.getLegalPhone()); - contactInfo.setContactEmail(shopAuthentication.getLegalEmail()); - request.setContactInfo(contactInfo); - //店铺信息 - ApplymentsRequest.SalesSceneInfo salesSceneInfo = new ApplymentsRequest.SalesSceneInfo(); - salesSceneInfo.setStoreName(operator.getName()); -// InputStream storeQrCodeIO = OBSUploadUtils.getOSSInputStream(operator.getShopCode().replace("https://hongruitang.oss-cn-beijing.aliyuncs.com/","")); -// ImageUploadResult storeQrCodeIR = merchantMediaService.imageUploadV3(storeQrCodeIO,applyNumber+"storeQrCode.jpg"); -// salesSceneInfo.setStoreQrCode(storeQrCodeIR.getMediaId()); -// storeQrCodeIO.close(); - request.setSalesSceneInfo(salesSceneInfo); - request.setMerchantShortname(operator.getName()); -// request.setBusinessAdditionPics(shopAuthentication.getBaPics()); -// request.setBusinessAdditionDesc(shopAuthentication.getBaDesc()); - return ecommerceService.createApply(request); - } - -} +//package com.dsh.guns.modular.system.util; +// +//import com.alibaba.fastjson.JSON; +//import com.alibaba.fastjson.JSONObject; +//import com.alipay.api.domain.Shop; +//import com.dsh.course.util.UUIDUtil; +//import com.dsh.guns.core.util.ToolUtil; +//import com.dsh.guns.modular.system.controller.util.UploadUtil; +//import com.dsh.guns.modular.system.model.OperatorAuth; +//import com.dsh.guns.modular.system.model.TOperator; +//import com.dsh.guns.modular.system.model.User; +//import com.dsh.guns.modular.system.service.IUserService; +//import com.github.binarywang.wxpay.bean.ecommerce.ApplymentsRequest; +//import com.github.binarywang.wxpay.bean.ecommerce.ApplymentsResult; +//import com.github.binarywang.wxpay.bean.media.ImageUploadResult; +//import com.github.binarywang.wxpay.service.EcommerceService; +//import com.github.binarywang.wxpay.service.MerchantMediaService; +//import com.github.binarywang.wxpay.service.WxPayService; +//import lombok.AllArgsConstructor; +//import lombok.NoArgsConstructor; +//import org.apache.commons.codec.digest.DigestUtils; +//import org.springframework.beans.factory.annotation.Autowired; +//import org.springframework.beans.factory.annotation.Value; +//import org.springframework.context.annotation.Bean; +//import org.springframework.http.*; +//import org.springframework.stereotype.Component; +//import org.springframework.web.client.RestTemplate; +// +//import java.io.ByteArrayInputStream; +//import java.io.InputStream; +//import java.io.UnsupportedEncodingException; +//import java.net.URLDecoder; +//import java.util.ArrayList; +//import java.util.HashMap; +//import java.util.List; +//import java.util.Map; +// +///** +// * 微信工具类 +// */ +//@Component +//public class WeChatUtil { +// +// private WxPayService wxService; +// +// +// +// /** +// * @description 电商二级商户进件(提交申请单) +// * @author jqs +// * @date 2023/8/11 10:04 +// * @param shopAuthentication +// * @param applyNumber +// * @param operator +// * @return ApplymentsResult +// */ +// +// +// public ApplymentsResult ecommerceApply(OperatorAuth shopAuthentication, String applyNumber, TOperator operator) throws Exception { +// +// EcommerceService ecommerceService = wxService.getEcommerceService(); +// MerchantMediaService merchantMediaService = wxService.getMerchantMediaService(); +// ApplymentsRequest request = new ApplymentsRequest(); +// //生成提交类 +// request.setOutRequestNo(applyNumber); +// if("ENTERPRISE".equals(shopAuthentication.getBodyType())){ +// request.setOrganizationType("2"); +// }else{ +// request.setOrganizationType("4"); +// } +// //营业执照 +// ApplymentsRequest.BusinessLicenseInfo business_license_info = new ApplymentsRequest.BusinessLicenseInfo(); +// InputStream blImageIO = OBSUploadUtil.getOBSStream(shopAuthentication.getBusinessPicture().replace("https://obs.ap-southeast-4.myhuaweicloud.com/","")); +// ImageUploadResult blImageIR = merchantMediaService.imageUploadV3(blImageIO,applyNumber+"blimage.jpg"); +// business_license_info.setBusinessLicenseCopy(blImageIR.getMediaId()); +// blImageIO.close(); +// business_license_info.setBusinessLicenseNumber(shopAuthentication.getBusinessNumber()); +// business_license_info.setMerchantName(shopAuthentication.getBusinessName()); +// business_license_info.setLegalPerson(shopAuthentication.getLegalPerson()); +// business_license_info.setCompanyAddress(shopAuthentication.getRegisterAddress()); +// List<String> businessTimeList = new ArrayList<>(); +// businessTimeList.add(0,shopAuthentication.getBusinessTerm()); +// businessTimeList.add(1,shopAuthentication.getBusinessEnd()); +// if(businessTimeList!=null&&businessTimeList.size()>1){ +// String businessTime = JSONObject.toJSONString(businessTimeList); +// business_license_info.setBusinessTime(businessTime); +// } +// request.setBusinessLicenseInfo(business_license_info); +// //法人证件 +// request.setIdDocType("IDENTIFICATION_TYPE_MAINLAND_IDCARD"); +// ApplymentsRequest.IdCardInfo id_card_info = new ApplymentsRequest.IdCardInfo(); +// InputStream lpIcFrontIO = OBSUploadUtil.getOBSStream(shopAuthentication.getLegalFront().replace("https://obs.ap-southeast-4.myhuaweicloud.com/","")); +// ImageUploadResult lpIcFrontIR = merchantMediaService.imageUploadV3(lpIcFrontIO,applyNumber+"lpIcFront.jpg"); +// id_card_info.setIdCardCopy(lpIcFrontIR.getMediaId()); +// lpIcFrontIO.close(); +// InputStream lpIcBackIO = OBSUploadUtil.getOBSStream(shopAuthentication.getLegalBack().replace("https://obs.ap-southeast-4.myhuaweicloud.com/","")); +// ImageUploadResult lpIcBackIR = merchantMediaService.imageUploadV3(lpIcBackIO,applyNumber+"lpIcBack.jpg"); +// id_card_info.setIdCardNational(lpIcBackIR.getMediaId()); +// lpIcBackIO.close(); +// id_card_info.setIdCardName(shopAuthentication.getLegalPerson()); +// id_card_info.setIdCardNumber(shopAuthentication.getLeagleNumber()); +// if("ENTERPRISE".equals(shopAuthentication.getBodyType())){ +// id_card_info.setIdCardAddress(shopAuthentication.getLegalAddress()); +// } +// id_card_info.setIdCardValidTimeBegin(shopAuthentication.getLegalTerm()); +// id_card_info.setIdCardValidTime(shopAuthentication.getLegalEnd()); +// request.setIdCardInfo(id_card_info); +// //企业填写 +// if("ENTERPRISE".equals(shopAuthentication.getBodyType())){ +// //受益人 +// if("true".equals(shopAuthentication.getIsBeneficiary())){ +// request.setOwner(true); +// }else{ +// request.setOwner(false); +// List<ApplymentsRequest.UboInfo> ubo_info_list = new ArrayList<>(); +// ApplymentsRequest.UboInfo uboInfo = new ApplymentsRequest.UboInfo(); +// uboInfo.setUboIdDocType("IDENTIFICATION_TYPE_MAINLAND_IDCARD"); +// InputStream uboIcFrontIO = OBSUploadUtil.getOBSStream(shopAuthentication.getBeneficiaryFront().replace("https://obs.ap-southeast-4.myhuaweicloud.com/","")); +// ImageUploadResult uboIcFrontIR = merchantMediaService.imageUploadV3(uboIcFrontIO,applyNumber+"uboIcFront.jpg"); +// uboInfo.setUboIdDocCopy(uboIcFrontIR.getMediaId()); +// uboIcFrontIO.close(); +// InputStream uboIcBackIO = OBSUploadUtil.getOBSStream(shopAuthentication.getBeneficiaryBack().replace("https://obs.ap-southeast-4.myhuaweicloud.com/","")); +// ImageUploadResult uboIcBackIR = merchantMediaService.imageUploadV3(uboIcBackIO,applyNumber+"uboIcBack.jpg"); +// uboInfo.setUboIdDocCopyBack(uboIcBackIR.getMediaId()); +// uboIcBackIO.close(); +// uboInfo.setUboIdDocName(shopAuthentication.getBeneficiary()); +// uboInfo.setUboIdDocNumber(shopAuthentication.getBeneficiaryNumber()); +// uboInfo.setUboIdDocAddress(shopAuthentication.getBeneficiaryAddress()); +// uboInfo.setUboIdDocPeriodBegin(shopAuthentication.getBeneficiaryTerm()); +// ubo_info_list.add(uboInfo); +// request.setUboInfoList(ubo_info_list); +// } +// } +// //结算账户信息 +// ApplymentsRequest.AccountInfo accountInfo = new ApplymentsRequest.AccountInfo(); +// if(shopAuthentication.getAccountType().equals(1)){ +// accountInfo.setBankAccountType("74"); +// }else{ +// accountInfo.setBankAccountType("75"); +// } +// accountInfo.setAccountBank(shopAuthentication.getBank()); +// accountInfo.setAccountName(shopAuthentication.getAccountName()); +// accountInfo.setBankAddressCode(shopAuthentication.getCityCode()); +// accountInfo.setBankName(shopAuthentication.getBankName()); +// accountInfo.setAccountNumber(shopAuthentication.getBankNumber()); +// request.setAccountInfo(accountInfo); +// ApplymentsRequest.ContactInfo contactInfo = new ApplymentsRequest.ContactInfo(); +// contactInfo.setContactType("65"); +// contactInfo.setContactName(shopAuthentication.getLegalPerson()); +// contactInfo.setContactIdCardNumber(shopAuthentication.getLeagleNumber()); +// contactInfo.setMobilePhone(shopAuthentication.getLegalPhone()); +// contactInfo.setContactEmail(shopAuthentication.getLegalEmail()); +// request.setContactInfo(contactInfo); +// //店铺信息 +// ApplymentsRequest.SalesSceneInfo salesSceneInfo = new ApplymentsRequest.SalesSceneInfo(); +// salesSceneInfo.setStoreName(operator.getName()); +//// InputStream storeQrCodeIO = OBSUploadUtils.getOSSInputStream(operator.getShopCode().replace("https://hongruitang.oss-cn-beijing.aliyuncs.com/","")); +//// ImageUploadResult storeQrCodeIR = merchantMediaService.imageUploadV3(storeQrCodeIO,applyNumber+"storeQrCode.jpg"); +//// salesSceneInfo.setStoreQrCode(storeQrCodeIR.getMediaId()); +//// storeQrCodeIO.close(); +// request.setSalesSceneInfo(salesSceneInfo); +// request.setMerchantShortname(operator.getName()); +//// request.setBusinessAdditionPics(shopAuthentication.getBaPics()); +//// request.setBusinessAdditionDesc(shopAuthentication.getBaDesc()); +// return ecommerceService.createApply(request); +// } +// +//} diff --git a/cloud-server-management/src/main/java/com/dsh/guns/modular/system/util/WxUploadImgUtil.java b/cloud-server-management/src/main/java/com/dsh/guns/modular/system/util/WxUploadImgUtil.java new file mode 100644 index 0000000..143894f --- /dev/null +++ b/cloud-server-management/src/main/java/com/dsh/guns/modular/system/util/WxUploadImgUtil.java @@ -0,0 +1,95 @@ +package com.dsh.guns.modular.system.util; + + +import com.github.binarywang.wxpay.v3.WechatPayUploadHttpPost; +import com.wechat.pay.contrib.apache.httpclient.WechatPayHttpClientBuilder; +import com.wechat.pay.contrib.apache.httpclient.auth.AutoUpdateCertificatesVerifier; +import com.wechat.pay.contrib.apache.httpclient.auth.PrivateKeySigner; +import com.wechat.pay.contrib.apache.httpclient.auth.WechatPay2Credentials; +import com.wechat.pay.contrib.apache.httpclient.auth.WechatPay2Validator; +import com.wechat.pay.contrib.apache.httpclient.util.PemUtil; +import org.apache.commons.codec.digest.DigestUtils; +import org.apache.commons.lang3.time.DateUtils; +import org.apache.http.HttpEntity; +import org.apache.http.client.methods.CloseableHttpResponse; +import org.apache.http.impl.client.CloseableHttpClient; +import org.apache.http.util.EntityUtils; +import org.springframework.scheduling.annotation.Scheduled; +import org.springframework.stereotype.Component; + +import java.io.File; +import java.io.FileInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.net.URI; +import java.net.URISyntaxException; +import java.nio.charset.StandardCharsets; +import java.security.PrivateKey; +import java.text.ParseException; +import java.util.Date; + +import static org.apache.http.HttpStatus.SC_OK; +import static org.junit.Assert.assertEquals; + + +/** + * 定时任务工具类 + */ +@Component +public class WxUploadImgUtil { + // 你的商户私钥 + private static final String privateKey = "-----BEGIN PRIVATE KEY-----\n" + + "-----END PRIVATE KEY-----\n"; + //测试AutoUpdateCertificatesVerifier的verify方法参数 + private static final String serialNumber = ""; + private static final String message = ""; + private static final String signature = ""; + private static final String merchantId = ""; // 商户号 + private static final String merchantSerialNumber = ""; // 商户证书序列号 + private static final String apiV3Key = ""; // API V3密钥 + private CloseableHttpClient httpClient; + private AutoUpdateCertificatesVerifier verifier; + + public String uploadImg(String date, String pattern) throws IOException, URISyntaxException { + PrivateKey merchantPrivateKey = PemUtil.loadPrivateKey(privateKey); + + //使用自动更新的签名验证器,不需要传入证书 + verifier = new AutoUpdateCertificatesVerifier( + new WechatPay2Credentials(merchantId, new PrivateKeySigner(merchantSerialNumber, merchantPrivateKey)), + apiV3Key.getBytes(StandardCharsets.UTF_8)); + + httpClient = WechatPayHttpClientBuilder.create() + .withMerchant(merchantId, merchantSerialNumber, merchantPrivateKey) + .withValidator(new WechatPay2Validator(verifier)) + .build(); + String filePath = "/your/home/hellokitty.png"; + URI uri = new URI("https://api.mch.weixin.qq.com/v3/merchant/media/upload"); + File file = new File(filePath); + try (FileInputStream fileIs = new FileInputStream(file)) { + String sha256 = DigestUtils.sha256Hex(fileIs); + try (InputStream is = new FileInputStream(file)) { + WechatPayUploadHttpPost request = new WechatPayUploadHttpPost.Builder(uri) + .withImage(file.getName(), sha256, is) + .build(); + + try (CloseableHttpResponse response = httpClient.execute(request)) { + assertEquals(SC_OK, response.getStatusLine().getStatusCode()); + HttpEntity entity = response.getEntity(); + // do something useful with the response body + // and ensure it is fully consumed + String s = EntityUtils.toString(entity); + System.out.println(s); + } + } + } + httpClient.close(); + return null; + } + + + + + + + +} diff --git a/cloud-server-management/src/main/resources/bootstrap.properties b/cloud-server-management/src/main/resources/bootstrap.properties index f173039..70c8af5 100644 --- a/cloud-server-management/src/main/resources/bootstrap.properties +++ b/cloud-server-management/src/main/resources/bootstrap.properties @@ -31,4 +31,5 @@ feign.compression.request.enabled=true feign.compression.response.enabled=true -mybatis-plus.configuration.map-underscore-to-camel-case=false \ No newline at end of file +mybatis-plus.configuration.map-underscore-to-camel-case=false + diff --git a/cloud-server-management/src/main/resources/mapper/TOperatorAuthWxMapper.xml b/cloud-server-management/src/main/resources/mapper/TOperatorAuthWxMapper.xml new file mode 100644 index 0000000..c32f426 --- /dev/null +++ b/cloud-server-management/src/main/resources/mapper/TOperatorAuthWxMapper.xml @@ -0,0 +1,6 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> +<mapper namespace="com.dsh.course.mapper.TOperatorAuthWxMapper"> + + +</mapper> diff --git a/cloud-server-management/src/main/webapp/WEB-INF/view/system/operator/Operator.html b/cloud-server-management/src/main/webapp/WEB-INF/view/system/operator/Operator.html index b132165..5a01801 100644 --- a/cloud-server-management/src/main/webapp/WEB-INF/view/system/operator/Operator.html +++ b/cloud-server-management/src/main/webapp/WEB-INF/view/system/operator/Operator.html @@ -40,6 +40,7 @@ <#button name="冻结" icon="fa-remove" clickFun="TSite.offShelf()" space="true"/> <#button name="解冻" icon="fa-check" clickFun="TSite.onShelf()" space="true"/> <#button name="重置密码" icon="fa-search" clickFun="TSite.reload()" space="true"/> + <#button name="绑定微信商户号" icon="fa-search" clickFun="TSite.bindWx()" space="true"/> </div> <#table id="TSiteTable"/> </div> diff --git a/cloud-server-management/src/main/webapp/WEB-INF/view/system/operator/OperatorUser_proportionAuthWX.html b/cloud-server-management/src/main/webapp/WEB-INF/view/system/operator/OperatorUser_proportionAuthWX.html new file mode 100644 index 0000000..dec2b08 --- /dev/null +++ b/cloud-server-management/src/main/webapp/WEB-INF/view/system/operator/OperatorUser_proportionAuthWX.html @@ -0,0 +1,305 @@ +@layout("/common/_container.html"){ +<style> + .avatar-uploader .el-upload { + border: 1px dashed #d9d9d9; + border-radius: 6px; + cursor: pointer; + position: relative; + height: 100px; + width: 100px; + overflow: hidden; + } + + .avatar-uploader .el-upload:hover { + border-color: #409EFF; + } + .avatar-uploader-icon { + font-size: 28px; + color: #8c939d; + width: 100px; + height: 100px; + line-height: 100px; + margin-top: 32px; + text-align: center; + } + .avatar { + width: 100px; + height: 100px; + display: block; + } + + .col-sm-12 { + margin-top: 20px; + } + + .col-sm-12 select { + height: 33px; + } + #app1{ + margin-left: 255px; + } + + +</style> +<script type="text/javascript" src="http://webapi.amap.com/maps?v=1.4.15&key=77b37f0753049c4e712ea79a24e0719c"></script> +<div class="ibox float-e-margins"> + <div class="ibox-content"> + <div class="form-horizontal" id="carInfoForm"> + <h2>商户信息</h2> + <div style="display: flex"> + <span>运营商名称:</span><span>${data.name}</span> + <span>管理员姓名:</span><span>${user.name}</span> + <span>管理员电话:</span><span>${user.phone}</span> + </div> + <h2>商户号信息</h2> + </br> + </br> + <input hidden id="id" value="${id}"> + <div class="row"> + <div class="col-lg-6" style=""> + <div class="form-group"> + <label class="col-sm-4 control-label" > + 商户类型:<input checked type="radio" name="bodyType" value="2" onclick="updateHalf(2)">企业 + <input type="radio" name="bodyType" value="4" onclick="updateHalf(1)">个人 + </label> + </div> + + <div class="form-group" > + <label class="col-sm-3 control-label">*法人姓名:</label> + <div class="col-sm-9" > + <input style="width: 300px" class="form-control" id="legalPerson" value="" placeholder="请输入" type="text"> + </div> + </div> + <div class="form-group"> + <label class="col-sm-3 control-label">*法人身份证号:</label> + <div class="col-sm-9"> + <input style="width: 300px" class="form-control" value="" id="leagleNumber" placeholder="请输入" type="text"> + </div> + </div> + <div class="form-group"> + <#avatar id="IDCardImg" name="*法人身份证正面照" avatarImg="" /> + </div> + <div class="form-group"> + <#avatar id="IDCardImg1" name="*法人身份证背面照" avatarImg="" /> + </div> + <div class="form-group"> + <label class="col-sm-3 control-label">*身份证开始时间:</label> + <div class="col-sm-9" style="display: flex"> + <input style="width: 300px" class="form-control" id="IDCardTime" value="" name="IDCardTime" type="date"> + </div> + </div> + <div class="form-group"> + <label class="col-sm-3 control-label">*身份证结束时间:</label> + <div class="col-sm-9" style="display: flex"> + <input style="width: 300px" class="form-control" value="" id="IDCardEnd" name="IDCardTime" type="date"> + <input type="checkbox" style="margin-left: 10px" id="IDCardE" value="0" onchange="TSite.tradeYse(this)">长期</input> + </div> + </div> + <div class="form-group"> + <label class="col-sm-3 control-label">*证件居住地址:</label> + <div class="col-sm-9"> + <input style="width: 300px" class="form-control" value="" id="legalAddress" placeholder="请输入" type="text"> + </div> + </div> + <div class="form-group"> + <label class="col-sm-3 control-label">*法人邮箱:</label> + <div class="col-sm-9"> + <input style="width: 300px" class="form-control" value="" id="legalEmail" placeholder="请输入" type="text"> + </div> + </div> + <div class="form-group"> + <label class="col-sm-3 control-label">*法人电话:</label> + <div class="col-sm-9"> + <input style="width: 300px" class="form-control" value="" id="legalPhone" placeholder="请输入" type="text"> + </div> + </div> + <div class="form-group"> + <#avatar id="license" name="*营业执照" avatarImg="" /> + </div> + <div class="form-group" > + <label class="col-sm-3 control-label">*营业执照注册号:</label> + <div class="col-sm-9" > + <input style="width: 300px" class="form-control" id="businessNumber" value="" placeholder="请输入营业执照注册号" type="text"> + </div> + </div> + <div class="form-group" > + <label class="col-sm-3 control-label">*商户名称(一般与证件名称相同):</label> + <div class="col-sm-9"> + <input style="width: 300px" class="form-control" value="" id="businessName" placeholder="请输入商户名称" type="text"> + </div> + </div> + <div class="form-group" > + <label class="col-sm-3 control-label">*商户别名(微信账单显示的商户名称):</label> + <div class="col-sm-9"> + <input style="width: 300px" class="form-control" value="" id="aliasName" placeholder="请输入商户别名" type="text"> + </div> + </div> + <div class="form-group"> + <label class="col-sm-3 control-label">*营业期限(开始):</label> + <div class="col-sm-9" style="display: flex"> + <input style="width: 300px" class="form-control" id="tradeTime" value="" name="tradeTime" type="date"> + </div> + </div> + <div class="form-group"> + <label class="col-sm-3 control-label">*营业期限(结束):</label> + <div class="col-sm-9" style="display: flex"> + <input style="width: 300px" class="form-control" value="" id="endTime" name="endTime" type="date"> + <input type="checkbox" style="margin-left: 10px" id="tradeE" value="0" onchange="TSite.tradeYse(this)">长期</input> + </div> + </div> + <div class="form-group"> + <label class="col-sm-3 control-label">*营业执照注册地址:</label> + <div class="col-sm-9"> + <input style="width: 300px" class="form-control" value="" id="companyAddress" placeholder="请输入" type="text"> + </div> + </div> + </div> + <div class="col-lg-6" style=""> + <div id="banks"> + <div class="form-group"> + <label class="col-sm-4 control-label" > + 账号使用类型:<input checked type="radio" name="useType" value="74" >对公 + <input type="radio" name="useType" value="75" >对私 + </label> + </div> + <div class="form-group"> + <label class="col-sm-3 control-label">*开户银行:</label> + <div class="col-sm-9"> + <input style="width: 300px" class="form-control" id="bank" value="" placeholder="请输入(例:中国农业银行)" type="text"> + </div> + </div> + <div class="form-group" > + <label class="col-sm-3 control-label">*开户银行联行号:</label> + <div class="col-sm-9" > + <input style="width: 300px" class="form-control" id="bankCardTwo" value="" placeholder="请输入" type="text"> + </div> + </div> + <div class="form-group" > + <label class="col-sm-3 control-label">*开户名称:</label> + <div class="col-sm-9" > + <input style="width: 300px" class="form-control" id="bankUserName" value="" placeholder="请输入" type="text"> + </div> + </div> + <div class="form-group" > + <label class="col-sm-3 control-label">*开户银行全称(含支行):</label> + <div class="col-sm-9" > + <input style="width: 300px" class="form-control" id="bankName1" value="" placeholder="请输入" type="text"> + </div> + </div> + <div class="form-group" > + <label class="col-sm-3 control-label">*银行账号:</label> + <div class="col-sm-9" > + <input style="width: 300px" class="form-control" id="bankCard" value="" placeholder="请输入" type="text"> + </div> + </div> + + <div class="form-group" id="provinceCode"> + <label class="col-sm-3 control-label">*开户行所在省:</label> + <div class="col-sm-9"> + <select style="width: 300px" class="form-control" id="pCode" name="pCode" onchange="TSite.oneChange2(this)"> + <option style="width: 300px" value="">全部</option> + @for(obj in list){ + <option style="width: 300px" value="${obj.code}">${obj.name}</option> + @} + </select> + </div> + </div> + <div class="form-group" id="cityCode"> + <label class="col-sm-3 control-label">*开户行所在市:</label> + <div class="col-sm-9"> + <select style="width: 300px" class="form-control" id="cCode" name="cCode" > + </select> + </div> + </div> + </div> + </div> + <div class="row" id="benefit"> + <div class="col-lg-6" style=""> + <div class="form-group"> + <label class="col-sm-4 control-label" > + 法人是否为受益人:<input type="radio" checked name="type" value="true" onclick="updateHalf1(1)">是 + <input type="radio" name="type" value="false" onclick="updateHalf1(0)">否 + </label> + </div> + <div hidden id="benefitInfo"> + <div class="form-group"> + <label class="col-sm-3 control-label">*受益人姓名:</label> + <div class="col-sm-9"> + <input style="width: 300px" class="form-control" id="bName" name="bName" type="text"> + </div> + </div> + <div class="form-group"> + <label class="col-sm-3 control-label">*受益人身份证地址:</label> + <div class="col-sm-9"> + <input style="width: 300px" class="form-control" id="bAddress" placeholder="请输入" type="text"> + </div> + </div> + <div class="form-group"> + <label class="col-sm-3 control-label">*受益人身份证有效期:</label> + <div class="col-sm-9"> + <input style="width: 300px" class="form-control" id="bTime" name="bTime" type="date"> + </div> + </div> + <div class="form-group"> + <label class="col-sm-3 control-label">*受益人身份证结束时间:</label> + <div class="col-sm-9" style="display: flex"> + <input style="width: 300px" class="form-control" id="bEnd" name="IDCardTime" type="date"> + <input type="checkbox" style="margin-left: 10px" id="bIDCardT" value="0" onchange="TSite.tradeYse(this)">长期</input> + </div> + </div> + <div class="form-group"> + <#avatar id="bImg1" name="受益人身份证正面照" /> + </div> + + <div class="col-lg-6" style=""> + <div class="form-group"> + <label class="col-sm-3 control-label">*受益人身份证号:</label> + <div class="col-sm-9" > + <input style="width: 300px" class="form-control" id="bIDNumber" placeholder="请输入" type="text"> + </div> + </div> + <div class="form-group"> + <#avatar id="bImg2" name="受益人身份证背面照" /> + </div> + </div> + </div> + </div> + </div> + </div> + <div class="form-group"> + <div class="row btn-group-m-t"> + <div class="col-sm-10 col-sm-offset-5" > + <#button btnCss="info" name="提交" id="ensure" icon="fa-check" clickFun="TSite.addSubmit1()"/> + <#button btnCss="danger" name="取消" id="cancel" icon="fa-eraser" clickFun="TSite.close()"/> + </div> + </div> + </div> + </div> + </div> +</div> + +<script src="${ctxPath}/modular/system/operatorUser/operatorUser.js"></script> +<script src="${ctxPath}/js/vue/vue.js"></script> +<script src="${ctxPath}/js/elementui/index.js"></script> +<link rel="stylesheet" href="${ctxPath}/js/elementui/index.css"> +<script> + function updateHalf(e) { + if(e==1){ + $("#benefit").hide() + }else { + $("#benefit").show() + } + } + function updateHalf1(e) { + if(e==0){ + // 法人不是受益人 + $("#benefitInfo").show() + }else { + // 法人是受益人 + $("#benefitInfo").hide() + } + } + + +</script> +@} diff --git a/cloud-server-management/src/main/webapp/WEB-INF/view/system/operator/OperatorUser_proportionAuth_info.html b/cloud-server-management/src/main/webapp/WEB-INF/view/system/operator/OperatorUser_proportionAuth_info.html index 2a8879b..ed31748 100644 --- a/cloud-server-management/src/main/webapp/WEB-INF/view/system/operator/OperatorUser_proportionAuth_info.html +++ b/cloud-server-management/src/main/webapp/WEB-INF/view/system/operator/OperatorUser_proportionAuth_info.html @@ -149,7 +149,7 @@ <input type="radio" name="useType" value="02" >对私 </label> </div> - <div class="form-group"> + <div cl ass="form-group"> <label class="col-sm-4 control-label" > 银行卡类型:<input checked type="radio" name="cardType" value="DC" onclick="updateHalf(2)">借记卡 <input type="radio" name="cardType" value="CC" onclick="updateHalf(1)">信用卡 @@ -256,7 +256,7 @@ var cardType = "${cardType}"; var OBJradio=document.getElementsByName("bodyType") var type=document.getElementsByName("type") - if("${bodyType}"=="01"){ + if("${bodyType}"=="2"){ OBJradio[0].checked=true }else { OBJradio[1].checked=true diff --git a/cloud-server-management/src/main/webapp/WEB-INF/view/system/operator/OperatorUser_proportionAuth_infoWX.html b/cloud-server-management/src/main/webapp/WEB-INF/view/system/operator/OperatorUser_proportionAuth_infoWX.html new file mode 100644 index 0000000..337137d --- /dev/null +++ b/cloud-server-management/src/main/webapp/WEB-INF/view/system/operator/OperatorUser_proportionAuth_infoWX.html @@ -0,0 +1,480 @@ +@layout("/common/_container.html"){ +<style> + .avatar-uploader .el-upload { + border: 1px dashed #d9d9d9; + border-radius: 6px; + cursor: pointer; + position: relative; + height: 100px; + width: 100px; + overflow: hidden; + } + + .avatar-uploader .el-upload:hover { + border-color: #409EFF; + } + .avatar-uploader-icon { + font-size: 28px; + color: #8c939d; + width: 100px; + height: 100px; + line-height: 100px; + margin-top: 32px; + text-align: center; + } + .avatar { + width: 100px; + height: 100px; + display: block; + } + + .col-sm-12 { + margin-top: 20px; + } + + .col-sm-12 select { + height: 33px; + } + #app1{ + margin-left: 255px; + } + + +</style> +<script type="text/javascript" src="http://webapi.amap.com/maps?v=1.4.15&key=77b37f0753049c4e712ea79a24e0719c"></script> +<div class="ibox float-e-margins"> + <div class="ibox-content"> + <div class="form-horizontal" id="carInfoForm"> + <h2>商户信息</h2> + <div style="display: flex"> + <span>运营商名称:</span><span>${data.name}</span> + <span>管理员姓名:</span><span>${user.name}</span> + <span>管理员电话:</span><span>${user.phone}</span> + </div> + <h2>商户号信息</h2> + </br> + </br> + <input hidden id="id" value="${id}"> + <div class="row"> + <div class="col-lg-6" style=""> + <div class="form-group"> + <label class="col-sm-4 control-label" > + 商户类型:<input checked type="radio" name="bodyType" value="2" onclick="updateHalf(2)">企业 + <input type="radio" name="bodyType" value="4" onclick="updateHalf(1)">个人 + </label> + </div> + + <div class="form-group" > + <label class="col-sm-3 control-label">*法人姓名:</label> + <div class="col-sm-9" > + <input style="width: 300px" class="form-control" id="legalPerson" value="${item.legalPerson}" placeholder="请输入" type="text"> + </div> + </div> + <div class="form-group"> + <label class="col-sm-3 control-label">*法人身份证号:</label> + <div class="col-sm-9"> + <input style="width: 300px" class="form-control" value="${item.leagleNumber}" id="leagleNumber" placeholder="请输入" type="text"> + </div> + </div> + <div class="form-group"> + <#avatar id="IDCardImg" name="*法人身份证正面照" avatarImg="${item.legalFront}" /> + </div> + <div class="form-group"> + <#avatar id="IDCardImg1" name="*法人身份证背面照" avatarImg="${item.legalBack}" /> + </div> + <div class="form-group"> + <label class="col-sm-3 control-label">*身份证开始时间:</label> + <div class="col-sm-9" style="display: flex"> + <input style="width: 300px" class="form-control" id="IDCardTime" value="${item.legalTerm}" name="IDCardTime" type="date"> + </div> + </div> + <div class="form-group"> + <label class="col-sm-3 control-label">*身份证结束时间:</label> + <div class="col-sm-9" style="display: flex"> + <input style="width: 300px" class="form-control" value="${item.legalEnd}" id="IDCardEnd" name="IDCardTime" type="date"> + <input type="checkbox" style="margin-left: 10px" id="IDCardE" value="0" onchange="TSite.tradeYse(this)">长期</input> + </div> + </div> + <div class="form-group"> + <label class="col-sm-3 control-label">*证件居住地址:</label> + <div class="col-sm-9"> + <input style="width: 300px" class="form-control" value="${item.legalAddress}" id="legalAddress" placeholder="请输入" type="text"> + </div> + </div> + <div class="form-group"> + <label class="col-sm-3 control-label">*法人邮箱:</label> + <div class="col-sm-9"> + <input style="width: 300px" class="form-control" value="${item.legalEmail}" id="email" placeholder="请输入" type="text"> + </div> + </div> + <div class="form-group"> + <label class="col-sm-3 control-label">*法人电话:</label> + <div class="col-sm-9"> + <input style="width: 300px" class="form-control" value="${item.legalPhone}" id="legalPhone" placeholder="请输入" type="text"> + </div> + </div> + <div class="form-group"> + <#avatar id="license" name="*营业执照" avatarImg="${item.businessPicture}" /> + </div> + <div class="form-group" > + <label class="col-sm-3 control-label">*营业执照注册号:</label> + <div class="col-sm-9" > + <input style="width: 300px" class="form-control" id="businessNumber" value="${item.businessNumber}" placeholder="请输入营业执照注册号" type="text"> + </div> + </div> + <div class="form-group" > + <label class="col-sm-3 control-label">*商户名称(一般与证件名称相同):</label> + <div class="col-sm-9"> + <input style="width: 300px" class="form-control" value="${item.businessName}" id="businessName" placeholder="请输入商户名称" type="text"> + </div> + </div> + <div class="form-group" > + <label class="col-sm-3 control-label">*商户别名(微信账单显示的商户名称):</label> + <div class="col-sm-9"> + <input style="width: 300px" class="form-control" value="${item.aliasName}" id="aliasName" placeholder="请输入商户别名" type="text"> + </div> + </div> + <div class="form-group"> + <label class="col-sm-3 control-label">*营业期限(开始):</label> + <div class="col-sm-9" style="display: flex"> + <input style="width: 300px" class="form-control" id="tradeTime" value="${item.businessTerm}" name="tradeTime" type="date"> + </div> + </div> + <div class="form-group"> + <label class="col-sm-3 control-label">*营业期限(结束):</label> + <div class="col-sm-9" style="display: flex"> + <input style="width: 300px" class="form-control" value="${item.businessEnd}" id="endTime" name="endTime" type="date"> + <input type="checkbox" style="margin-left: 10px" id="tradeE" value="0" onchange="TSite.tradeYse(this)">长期</input> + </div> + </div> + <div class="form-group"> + <label class="col-sm-3 control-label">*营业执照注册地址:</label> + <div class="col-sm-9"> + <input style="width: 300px" class="form-control" value="${item.registerAddress}" id="companyAddress" placeholder="请输入" type="text"> + </div> + </div> + </div> + <div class="col-lg-6" style=""> + <div id="banks"> + <div class="form-group"> + <label class="col-sm-4 control-label" > + 账号使用类型:<input checked type="radio" name="useType" value="74" >对公 + <input type="radio" name="useType" value="75" >对私 + </label> + </div> + <div class="form-group"> + <label class="col-sm-3 control-label">*开户银行:</label> + <div class="col-sm-9"> + <input style="width: 300px" class="form-control" id="bankName" value="${item.bank}" placeholder="请输入(例:中国农业银行)" type="text"> + </div> + </div> + <div class="form-group" > + <label class="col-sm-3 control-label">*开户银行联行号:</label> + <div class="col-sm-9" > + <input style="width: 300px" class="form-control" id="bankCardTwo" value="${item.bankCardTwo}" placeholder="请输入" type="text"> + </div> + </div> + <div class="form-group" > + <label class="col-sm-3 control-label">*开户名称:</label> + <div class="col-sm-9" > + <input style="width: 300px" class="form-control" id="bankUserName" value="${item.accountName}" placeholder="请输入" type="text"> + </div> + </div> + <div class="form-group" > + <label class="col-sm-3 control-label">*开户银行全称(含支行):</label> + <div class="col-sm-9" > + <input style="width: 300px" class="form-control" id="bankName1" value="${item.bankName}" placeholder="请输入" type="text"> + </div> + </div> + <div class="form-group" > + <label class="col-sm-3 control-label">*银行账号:</label> + <div class="col-sm-9" > + <input style="width: 300px" class="form-control" id="bankCard" value="${item.bankNumber}" placeholder="请输入" type="text"> + </div> + </div> + + <div class="form-group" id="provinceCode"> + <label class="col-sm-3 control-label">*开户行所在省:</label> + <div class="col-sm-9"> + <select style="width: 300px" class="form-control" id="pCode" name="pCode" onchange="TSite.oneChange2(this)"> + @for(obj in list4){ + <option style="width: 300px" value="${obj.code}" ${obj.code == item.provinceCode ? 'selected=selected' : ''}>${obj.name}</option> + @} + </select> + </div> + </div> + <div class="form-group" id="cityCode"> + <label class="col-sm-3 control-label">*开户行所在市:</label> + <div class="col-sm-9"> + <select style="width: 300px" class="form-control" id="cCode" name="cCode" > + @for(obj in list5){ + <option style="width: 300px" value="${obj.code}" ${obj.code == item.cityCode ? 'selected=selected' : ''}>${obj.name}</option> + @} + </select> + </div> + </div> + <div class="row" id="benefit"> + + <div class="form-group"> + <label class="col-sm-4 control-label" > + 法人是否为受益人:<input type="radio" checked name="type" value="true" onclick="updateHalf1(1)">是 + <input type="radio" name="type" value="false" onclick="updateHalf1(0)">否 + </label> + </div> + <div hidden id="benefitInfo"> + <div class="form-group"> + <label class="col-sm-3 control-label">*受益人姓名:</label> + <div class="col-sm-9"> + <input style="width: 300px" value="${item.benefitsName}"class="form-control" id="bName" name="bName" type="text"> + </div> + </div> + <div class="form-group"> + <label class="col-sm-3 control-label">*受益人身份证地址:</label> + <div class="col-sm-9"> + <input style="width: 300px" class="form-control"value="${item.benefitsAddress}" id="bAddress" placeholder="请输入" type="text"> + </div> + </div> + <div class="form-group"> + <label class="col-sm-3 control-label">*受益人身份证有效期:</label> + <div class="col-sm-9"> + <input style="width: 300px" class="form-control" value="${item.benefitsStartTime}" id="bTime" name="bTime" type="date"> + </div> + </div> + <div class="form-group"> + <label class="col-sm-3 control-label">*受益人身份证结束时间:</label> + <div class="col-sm-9" style="display: flex"> + <input style="width: 300px" class="form-control" value="${item.benefitsEndTime}" id="bEnd" name="IDCardTime" type="date"> + <input type="checkbox" style="margin-left: 10px" id="bIDCardT" value="0" onchange="TSite.tradeYse(this)">长期</input> + </div> + </div> + <div class="form-group"> + <#avatar id="bImg1" name="受益人身份证正面照" avatarImg="${item.benefitsFront}" /> + </div> + + <div class="form-group"> + <label class="col-sm-3 control-label">*受益人身份证号:</label> + <div class="col-sm-9" > + <input style="width: 300px" class="form-control" value="${item.benefitsNumber}" id="bIDNumber" placeholder="请输入" type="text"> + </div> + </div> + <div class="form-group"> + <label class="col-sm-3 control-label">*受益人证件居住地址:</label> + <div class="col-sm-9" > + <input style="width: 300px" class="form-control" value="${item.benefitsAddress}" id="bIDAddress" placeholder="请输入" type="text"> + </div> + </div> + <div class="form-group"> + <#avatar id="bImg2" name="受益人身份证背面照" avatarImg="${item.benefitsBack}"/> + + </div> + </div> + </div> + <div class="row" id="applyment_state"> + <div class="col-lg-6" > + <div class="form-group"> + <label class="col-sm-3 control-label">*申请状态:</label> + <div class="col-sm-9"> + <h3 style="color: red">${applymentState}</h3> + </div> + </div> + </div> + </div> + <div class="row" hidden id="account"> + <div class="col-lg-6" > + <div class="form-group"> + <label class="col-sm-3 control-label">*付款户名:</label> + <div class="col-sm-9"> + <h3>${accountName}</h3> + </div> + </div> + </div> + <div class="col-lg-6" > + <div class="form-group"> + <label class="col-sm-3 control-label">*付款卡号:</label> + <div class="col-sm-9"> + <h3>${accountNo}</h3> + </div> + </div> + </div> + <div class="col-lg-6" > + <div class="form-group"> + <label class="col-sm-3 control-label">*需要汇款的金额(单位:分):</label> + <div class="col-sm-9"> + <h3>${payAmount}</h3> + </div> + </div> + </div> + <div class="col-lg-6" > + <div class="form-group"> + <label class="col-sm-3 control-label">*收款账户的卡号:</label> + <div class="col-sm-9"> + <h3>${destinationAccountNumber}</h3> + </div> + </div> + </div> + <div class="col-lg-6" > + <div class="form-group"> + <label class="col-sm-3 control-label">*收款账户名:</label> + <div class="col-sm-9"> + <h3>${destinationAccountName}</h3> + </div> + </div> + </div> + <div class="col-lg-6" > + <div class="form-group"> + <label class="col-sm-3 control-label">*收款账户的开户银行名称:</label> + <div class="col-sm-9"> + <h3>${destinationAccountBank}</h3> + </div> + </div> + </div> + <div class="col-lg-6" > + <div class="form-group"> + <label class="col-sm-3 control-label">*收款账户的省市:</label> + <div class="col-sm-9"> + <h3>${city}</h3> + </div> + </div> + </div> + <div class="col-lg-6" > + <div class="form-group"> + <label class="col-sm-3 control-label">*商户汇款时,需要填写的备注信息:</label> + <div class="col-sm-9"> + <h3>${remark}</h3> + </div> + </div> + </div> + <div class="col-lg-6" > + <div class="form-group"> + <label class="col-sm-3 control-label">*请在此时间前完成汇款:</label> + <div class="col-sm-9"> + <h3>${deadline}</h3> + </div> + </div> + </div> + </div> + <div class="form-group" hidden id="sign_url"> + <label class="col-sm-3 control-label">*签约链接(需让申请单-管理者用微信扫码打开,完成签约):</label> + <div class="col-sm-9" > + <img src="https://we-park-life.oss-cn-beijing.aliyuncs.com/img/10e7c7ec88c14cb9970910ad642b4ad5.png" width="200px" height="200px" alt="二维码"> + </div> + </div> + <div class="form-group" hidden id="legal_validation_url"> + <label class="col-sm-3 control-label">*法人验证链接(商户法人用微信扫码打开,完成账户验证):</label> + <div class="col-sm-9" > + <img src="https://we-park-life.oss-cn-beijing.aliyuncs.com/img/10e7c7ec88c14cb9970910ad642b4ad5.png" width="200px" height="200px" alt="二维码"> + </div> + </div> + + <div class="row" hidden id="sign_state"> + <div class="col-lg-6" > + <div class="form-group"> + <label class="col-sm-3 control-label">*签约状态:</label> + <div class="col-sm-9"> + <h3 style="color: red">${signState}</h3> + </div> + </div> + </div> + </div> + </div> + </div> + </div> + <div class="form-group"> + <div class="row btn-group-m-t"> + <div class="col-sm-10 col-sm-offset-5" > + <#button btnCss="info" name="提交" id="ensure" icon="fa-check" clickFun="TSite.addSubmit1()"/> + <#button btnCss="danger" name="取消" id="cancel" icon="fa-eraser" clickFun="TSite.close()"/> + </div> + </div> + </div> + </div> + </div> +</div> + +<script src="${ctxPath}/modular/system/operatorUser/operatorUser.js"></script> +<script src="${ctxPath}/js/vue/vue.js"></script> +<script src="${ctxPath}/js/elementui/index.js"></script> +<link rel="stylesheet" href="${ctxPath}/js/elementui/index.css"> +<script> + function updateHalf1(e) { + if(e==0){ + // 法人不是受益人 + $("#benefitInfo").show() + }else { + // 法人是受益人 + $("#benefitInfo").hide() + } + } + // function updateHalf(e) { + // if(e==3){ + // console.log("展示") + // $("#banks").show() + // $("#aliNumber").hide() + // }else if (e==4){ + // // 结算到支付宝账号 + // console.log("隐藏") + // $("#banks").hide() + // $("#aliNumber").show() + // } + // } + + window.onload = function(){ + var state="${state}" + if(state=="FINISH"){ + $("#sign_url").show() + } + var signState="${signState}" + if(signState!= 0){ + $("#sign_url").show() + } + var applymentState="${applymentState}" + var legalValidationUrl="${item.legalValidationUrl}" + if(applymentState== "待账户验证"){ + $("#account").show() + if (legalValidationUrl !=null && legalValidationUrl != ""){ + $("#legal_validation_url").show() + } + } + // 如果state为finish 才展示二维码链接 + var idCardEnd="${item.legalEnd}" + var businessEnd="${item.businessEnd}" + var benefitsEndTime="${item.benefitsEndTime}" + var tradeT = document.getElementById('tradeE'); + var IDCardTime = document.getElementById('IDCardTime'); + var endTime = document.getElementById('endTime'); + var IDCardT = document.getElementById('IDCardE'); + var IDCardTime = document.getElementById('IDCardEnd'); + var IDCardE = document.getElementById('IDCardE'); + var IDCardTime = document.getElementById('IDCardEnd'); + var IDCardE = document.getElementById('IDCardE'); + var bEnd = document.getElementById('bEnd'); + console.log("进入") + + console.log("身份证结束时间") + console.log(idCardEnd) + if (idCardEnd == "长期"){ + IDCardE.checked = true; + IDCardTime.disabled = true; + } + console.log("营业结束时间") + console.log(businessEnd) + if (businessEnd == "长期"){ + tradeT.checked = true; + endTime.disabled = true; + } + if (benefitsEndTime == "长期"){ + bIDCardT.checked = true; + bEnd.disabled = true; + } + console.log("${item.accountType}") + var accountType = "${item.accountType}"; + var OBJradio=document.getElementsByName("useType") + if(accountType=="74"){ + OBJradio[0].checked=true + }else { + OBJradio[1].checked=true + } + + } +</script> +@} diff --git a/cloud-server-management/src/main/webapp/WEB-INF/view/system/operator/Operator_wx.html b/cloud-server-management/src/main/webapp/WEB-INF/view/system/operator/Operator_wx.html new file mode 100644 index 0000000..fd8e561 --- /dev/null +++ b/cloud-server-management/src/main/webapp/WEB-INF/view/system/operator/Operator_wx.html @@ -0,0 +1,81 @@ +@layout("/common/_container.html"){ +<style> + .avatar-uploader .el-upload { + border: 1px dashed #d9d9d9; + border-radius: 6px; + cursor: pointer; + position: relative; + height: 100px; + width: 100px; + overflow: hidden; + } + + .avatar-uploader .el-upload:hover { + border-color: #409EFF; + } + .avatar-uploader-icon { + font-size: 28px; + color: #8c939d; + width: 100px; + height: 100px; + line-height: 100px; + margin-top: 32px; + text-align: center; + } + .avatar { + width: 100px; + height: 100px; + display: block; + } + + .col-sm-12 { + margin-top: 20px; + } + + .col-sm-12 select { + height: 33px; + } + #app1{ + margin-left: 255px; + } + + +</style> +<script type="text/javascript" src="http://webapi.amap.com/maps?v=1.4.15&key=77b37f0753049c4e712ea79a24e0719c"></script> +<div class="ibox float-e-margins"> + <div class="ibox-content"> + <div class="form-horizontal" id="carInfoForm"> + <div class="row"> + <input hidden id="id" value="${id}"> + <div class="col-lg-6" style=""> + <div class="form-group" > + + <label class="col-sm-3 control-label">*微信商户号:</label> + <div class="col-sm-9"> + <input style="width: 300px" class="form-control" id="merchantNumber" value="${merchantNumber}" placeholder="请输入" type="number"> + </div> + <label class="col-sm-3 control-label">*微信商户全称:</label> + <div class="col-sm-9"> + <input style="width: 300px" class="form-control" id="name" value="${name}" placeholder="请输入" type="text"> + </div> + </div> + </div> + </div> + <div class="form-group"> + <div class="row btn-group-m-t"> + <div class="col-sm-10 col-sm-offset-5" > + <#button btnCss="info" name="提交" id="ensure" icon="fa-check" clickFun="TSite.merchantNumber()"/> + <#button btnCss="danger" name="取消" id="cancel" icon="fa-eraser" clickFun="TSite.close()"/> + </div> + </div> + </div> + </div> + </div> +</div> + +<script src="${ctxPath}/modular/system/operator/operator_add.js"></script> +<script src="${ctxPath}/js/vue/vue.js"></script> +<script src="${ctxPath}/js/elementui/index.js"></script> +<link rel="stylesheet" href="${ctxPath}/js/elementui/index.css"> + +@} diff --git a/cloud-server-management/src/main/webapp/WEB-INF/view/system/tShop/TShop.html b/cloud-server-management/src/main/webapp/WEB-INF/view/system/tShop/TShop.html index 56a376c..e32a26d 100644 --- a/cloud-server-management/src/main/webapp/WEB-INF/view/system/tShop/TShop.html +++ b/cloud-server-management/src/main/webapp/WEB-INF/view/system/tShop/TShop.html @@ -69,7 +69,7 @@ @} <#button name="免费福利" icon="fa-remove" clickFun="TCompetition.gift()" space="true"/> <#button name="首页设置" icon="fa-remove" clickFun="TCompetition.indexSet()" space="true"/> - + @if(role == '1'){ @if(shiro.hasPermission("/tHomeModule/tHomeModule_platformSet")){ <#button name="图文模块设置" icon="fa-edit" clickFun="TCompetition.platformSet()" space="true"/> diff --git a/cloud-server-management/src/main/webapp/static/modular/system/operator/operator.js b/cloud-server-management/src/main/webapp/static/modular/system/operator/operator.js index e376ae5..529af05 100644 --- a/cloud-server-management/src/main/webapp/static/modular/system/operator/operator.js +++ b/cloud-server-management/src/main/webapp/static/modular/system/operator/operator.js @@ -19,7 +19,7 @@ */ TSite.initColumn = function () { return [ - {field: 'selectItem', checkbox: true}, + {field: 'selectItem', radio: true}, {title: '序号', field: 'id', visible: true, align: 'center', valign: 'middle'}, {title: '运营商名称', field: 'name', visible: true, align: 'center', valign: 'middle',width:'20%',}, {title: '管理员姓名', field: 'userName', visible: true, align: 'center', valign: 'middle', @@ -95,6 +95,19 @@ this.layerIndex = index; } }; +TSite.bindWx = function () { + if (this.check()) { + var index = layer.open({ + type: 2, + title: "商户认证", + area: ['100%', '100%'], //宽高 + fix: false, //不固定 + maxmin: true, + content: Feng.ctxPath + '/operator/bindWx/' + TSite.seItem.id + }); + this.layerIndex = index; + } +}; /** * 商户号认证页面回显 */ diff --git a/cloud-server-management/src/main/webapp/static/modular/system/operator/operator_add.js b/cloud-server-management/src/main/webapp/static/modular/system/operator/operator_add.js index f4d67b0..5090314 100644 --- a/cloud-server-management/src/main/webapp/static/modular/system/operator/operator_add.js +++ b/cloud-server-management/src/main/webapp/static/modular/system/operator/operator_add.js @@ -100,7 +100,59 @@ } }; +TSite.oneChange = function (e) { + console.log("进入!") + var oneId=$(e).val(); + console.log(oneId) + var ajax = new $ax(Feng.ctxPath + "/tCompetition/onChange", function(data){ + var content='<option value="">选择市</option>'; + $.each(data, function(k,v) { + content += "<option value='"+v.code+"'>"+v.name+"</option>"; + }); + $("#cCode").empty().append(content); + }); + if (oneId==""){ + var temp = '<option value="">请先选择省</option>'; + $("#cCode").empty().append(temp); + } + ajax.set("oneId",oneId); + ajax.start(); +} +/** + * 关闭此对话框 + */ +TSite.close = function() { + parent.layer.close(window.parent.TSite.layerIndex); +} + +TSite.merchantNumber = function(){ + if($("#merchantNumber").val() == "" || $("#merchantNumber").val() == null){ + Feng.error("请填写微信商户号") + return; + } + if($("#name").val() == "" || $("#name").val() == null){ + Feng.error("请填写微信商户全称") + return; + } + //提交信息 + var ajax = new $ax(Feng.ctxPath + "/operator/merchantNumberWx", function(data){ + console.log(data) + if (data.code == 500){ + Feng.error(data.msg) + return + } + Feng.success("操作成功!"); + window.parent.TSite.table.refresh(); + TSite.close(); + },function(data){ + Feng.error("操作失败!" + data.responseJSON.message + "!"); + }); + ajax.set("id",$("#id").val()); + ajax.set("merchantNumber",$("#merchantNumber").val()); + ajax.set("name",$("#name").val()); + ajax.start(); +}; TSite.oneChange = function (e) { console.log("进入!") var oneId=$(e).val(); diff --git a/cloud-server-management/src/main/webapp/static/modular/system/operatorUser/operatorUser.js b/cloud-server-management/src/main/webapp/static/modular/system/operatorUser/operatorUser.js index bc6a466..27d2cfa 100644 --- a/cloud-server-management/src/main/webapp/static/modular/system/operatorUser/operatorUser.js +++ b/cloud-server-management/src/main/webapp/static/modular/system/operatorUser/operatorUser.js @@ -58,17 +58,36 @@ }, ]; }; +/** + * 商户号认证页面 + */ TSite.auth = function () { + console.log("看看行内平台") if (this.check()) { - var index = layer.open({ - type: 2, - title: "商户认证", - area: ['100%', '100%'], //宽高 - fix: false, //不固定 - maxmin: true, - content: Feng.ctxPath + '/operator/proportionAuth/' + TSite.seItem.operatorId - }); - this.layerIndex = index; + console.log("看看行内平台") + console.log(TSite.seItem.platform) + if (TSite.seItem.platform == "微信"){ + var index = layer.open({ + type: 2, + title: "微信商户认证", + area: ['100%', '100%'], //宽高 + fix: false, //不固定 + maxmin: true, + content: Feng.ctxPath + '/operator/proportionAuthWx/' + TSite.seItem.operatorId + }); + this.layerIndex = index; + }else{ + var index = layer.open({ + type: 2, + title: "支付宝商户认证", + area: ['100%', '100%'], //宽高 + fix: false, //不固定 + maxmin: true, + content: Feng.ctxPath + '/operator/proportionAuth/' + TSite.seItem.operatorId + }); + this.layerIndex = index; + } + } }; /** @@ -76,15 +95,28 @@ */ TSite.auth1 = function () { if (this.check()) { - var index = layer.open({ - type: 2, - title: "商户认证详情", - area: ['100%', '100%'], //宽高 - fix: false, //不固定 - maxmin: true, - content: Feng.ctxPath + '/operator/proportionAuth1/' + TSite.seItem.operatorId - }); - this.layerIndex = index; + console.log(TSite.seItem.platform) + if (TSite.seItem.platform == "微信"){ + var index = layer.open({ + type: 2, + title: "微信商户认证", + area: ['100%', '100%'], //宽高 + fix: false, //不固定 + maxmin: true, + content: Feng.ctxPath + '/operator/proportionAuth1Wx/' + TSite.seItem.operatorId + }); + this.layerIndex = index; + }else { + var index = layer.open({ + type: 2, + title: "商户认证详情", + area: ['100%', '100%'], //宽高 + fix: false, //不固定 + maxmin: true, + content: Feng.ctxPath + '/operator/proportionAuth1/' + TSite.seItem.operatorId + }); + this.layerIndex = index; + } } }; TSite.proportion = function () { @@ -136,6 +168,10 @@ var oneId=$(e).val(); console.log(oneId) console.log("!!!!!!!!!!!!!") + if ($("#pCode").val()==""){ + var content='<option value="">请先选择省</option>'; + $("#cCode").empty().append(content); + } var ajax = new $ax(Feng.ctxPath + "/tCompetition/onChange3", function(data){ if(data!=null){ var content='<option value="">选择市</option>'; @@ -201,10 +237,7 @@ Feng.error("请输入营业执照编号"); return; } - if ("" == $("#businessNumber").val() ){ - Feng.error("请上传营业执照"); - return; - } + if ("" == $("#name").val() ){ Feng.error("请输入联系人姓名"); return; @@ -328,6 +361,214 @@ ajax.set("zfbAccount", $("#zfbAccount").val() ); ajax.start(); }; +// 微信商户认证提交按钮 +TSite.addSubmit1 = function(){ + var bodyType = $("input[name='bodyType']:checked").val(); + if (bodyType=="" || null == bodyType){ + Feng.error("请选择主体类型"); + return; + } + var radios = document.getElementsByName('type'); + if (bodyType == 2){ + for (var i = 0; i < radios.length; i++) { + if (radios[i].checked) { + if (radios[i].value != "true"){ + // 法人不是受益人 + if ("" == $("#bName").val() ){ + Feng.error("请输入受益人姓名"); + return; + } + if ("" == $("#bAddress").val() ){ + Feng.error("请输入受益人身份证居住地址"); + return; + } + if ("" == $("#bTime").val() ){ + Feng.error("请选择受益人身份证开始时间"); + return; + } + var bIDCardT = document.getElementById("bIDCardT"); + if (!bIDCardT.checked){ + if ("" == $("#bEnd").val() || null == $("#bEnd").val()){ + Feng.error("请选择受益人身份证过期时间"); + return; + } + } + + if ("" == $("#bIDNumber").val() ){ + Feng.error("请输入受益人身份证号"); + return; + } + + } + + + } + } + } + + if ("" == $("#businessName").val() ){ + Feng.error("请输入商户名称"); + return; + } + if ("" == $("#aliasName").val() ){ + Feng.error("请输入商户别名"); + return; + } + if ("" == $("#businessNumber").val() ){ + Feng.error("请输入营业执照编号"); + return; + } + + var tradeT = document.getElementById("tradeE"); + if (!tradeT.checked){ + if ("" == $("#endTime").val() || null == $("#endTime").val()){ + Feng.error("请输入营业证照过期时间"); + return; + } + } + if ("" == $("#tradeTime").val() || null == $("#tradeTime").val()){ + Feng.error("请输入营业执照生效期间"); + return; + } + if ("" == $("#licenseRegistration").val() ){ + Feng.error("请输入营业执照注册号"); + return; + } + if ("" == $("#companyAddress").val() ){ + Feng.error("营业执照注册地址"); + return; + } + if ("" == $("#legalPerson").val()){ + Feng.error("请输入法人姓名"); + return; + } + if ("" == $("#leagleNumber").val()){ + Feng.error("请输入法人身份证号"); + return; + } + var IDCardE = document.getElementById("IDCardE"); + if (!IDCardE.checked){ + if ("" == $("#IDCardEnd").val() || null == $("#IDCardEnd").val()){ + Feng.error("请选择身份证过期时间"); + return; + } + } + if ("" == $("#IDCardTime").val() || null == $("#IDCardTime").val()){ + Feng.error("请选择身份证开始时间"); + return; + } + // 结算账户类型 + var useType = $("input[name='useType']:checked").val(); + // 结算到银行卡 + if ("" == $("#bankCard").val()){ + Feng.error("请输入银行卡号"); + return; + } + if ("" == $("#bankName").val()){ + Feng.error("请输入开户银行"); + return; + } + if ("" == $("#bankCardTwo").val()){ + Feng.error("请输入开户银行联行号"); + return; + } + if ("" == $("#bankUserName").val()){ + Feng.error("请输入开户名称"); + return; + } + if ("" == $("#bankCard").val()){ + Feng.error("请输入银行账号"); + return; + } + if ("" == $("#bankName1").val()){ + Feng.error("请输入开户支行名称"); + return; + } + + if ("" == $("#pCode").val()){ + Feng.error("请选择开户银行所在省"); + return; + } + if ("" == $("#cCode").val()){ + Feng.error("请选择开户银行所在市"); + return; + } + //提交信息 + var ajax = new $ax(Feng.ctxPath + "/operator/wxAuth", function(data){ + if (data==5001){ + Feng.error("未上传营业执照!"); + return; + }else if(data==5002){ + Feng.error("未上传法人身份证正面照!"); + return; + }else if(data==5003){ + Feng.error("未上传法人身份证背面照!"); + return; + }else if (data.code==500){ + console.log(data); + Feng.error("认证失败:"+data.msg); + return; + }else{ + Feng.success("认证成功!请等待微信平台审核"); + window.parent.TSite.table.refresh(); + TSite.close(); + } + },function(data){ + Feng.error("操作失败!"); + }); + ajax.set("operatorId", $("#id").val()); + ajax.set("bodyType", bodyType ); + ajax.set("businessName", $("#businessName").val()); + ajax.set("aliasName", $("#aliasName").val()); + ajax.set("businessNumber", $("#businessNumber").val() ); + ajax.set("tradeTime", $("#tradeTime").val() ); + ajax.set("endTime", $("#endTime").val() ); + ajax.set("businessNumber", $("#businessNumber").val() ); + ajax.set("license", $("#license").val() ); + ajax.set("companyAddress", $("#companyAddress").val() ); + ajax.set("legalPerson", $("#legalPerson").val() ); + ajax.set("leagleNumber", $("#leagleNumber").val() ); + ajax.set("IDCardTime", $("#IDCardTime").val() ); + ajax.set("IDCardEnd", $("#IDCardEnd").val() ); + ajax.set("leagleNumber", $("#leagleNumber").val() ); + ajax.set("legalFront", $("#IDCardImg").val() ); + ajax.set("legalBack", $("#IDCardImg1").val() ); + ajax.set("legalPhone", $("#legalPhone").val() ); + ajax.set("legalEmail", $("#legalEmail").val() ); + ajax.set("legalAddress", $("#legalAddress").val() ); + ajax.set("useType", useType ); + ajax.set("bankCard", $("#bankCard").val() ); + ajax.set("bank", $("#bank").val() ); + ajax.set("bankCardTwo", $("#bankCardTwo").val() ); + ajax.set("accountName", $("#bankUserName").val() ); + ajax.set("bankName", $("#bankName1").val() ); + ajax.set("provinceCode", $("#pCode").val() ); + ajax.set("province", $('#pCode option:selected').text()); + ajax.set("cityCode", $("#cCode").val() ); + ajax.set("city", $('#cCode option:selected').text()); + if (radios[0].value == "true"){ + ajax.set("isBenefits", "true"); + ajax.set("benefitsName", $("#legalPerson").val() ); + ajax.set("benefitsFront", $("#IDCardImg").val() ); + ajax.set("benefitsBack", $("#IDCardImg1").val() ); + ajax.set("benefitsNumber", $("#leagleNumber").val() ); + ajax.set("benefitsStartTime", $("#IDCardTime").val() ); + ajax.set("benefitsEndTime", $("#IDCardEnd").val() ); + ajax.set("benefitsAddress", $("#legalAddress").val() ); + }else{ + ajax.set("isBenefits", "false"); + ajax.set("benefitsName", $("#bName").val() ); + ajax.set("benefitsFront", $("#bImg1").val() ); + ajax.set("benefitsBack", $("#bImg2").val() ); + ajax.set("benefitsNumber", $("#bIDNumber").val() ); + ajax.set("benefitsStartTime", $("#bTime").val() ); + ajax.set("benefitsEndTime", $("#bEnd").val() ); + ajax.set("benefitsAddress", $("#bAddress").val() ); + } + + + ajax.start(); +}; /** * 检查是否选中 */ @@ -416,20 +657,23 @@ // 判断是否被选中 if (tradeT.checked) { endTime.disabled = true; - endTime.value=""; + endTime.value="长期"; } else { endTime.disabled = false; + endTime.value=""; } if (IDCardT.checked) { - IDCardTime.value=""; + IDCardTime.value="长期"; IDCardTime.disabled = true; } else { IDCardTime.disabled = false; + IDCardTime.value=""; } if (bIDCardT.checked) { - bTime.value=""; + bTime.value="长期"; bTime.disabled = true; } else { + bTime.value=""; bTime.disabled = false; } }; diff --git a/cloud-server-other/src/main/java/com/dsh/other/controller/GameController.java b/cloud-server-other/src/main/java/com/dsh/other/controller/GameController.java index bda7919..bf1a715 100644 --- a/cloud-server-other/src/main/java/com/dsh/other/controller/GameController.java +++ b/cloud-server-other/src/main/java/com/dsh/other/controller/GameController.java @@ -177,7 +177,8 @@ - + @Autowired + private IOperatorUserService operatorUserService; @ResponseBody @PostMapping("/api/game/payGame") @ApiOperation(value = "支付游戏", tags = {"用户—游戏"}) @@ -195,6 +196,14 @@ Integer uid = tokenUtil.getUserIdFormRedis(); if (null == uid) { return ResultUtil.tokenErr(); + } + Site byId = siteService.getById(spaceId); + // 是否分账 0否1是 + int isFenZhang= 1; + String merchantNumber = ""; + if (byId.getOperatorId()==null || byId.getOperatorId()==0){ + // 平台 + isFenZhang = 0; } //判断当前用户是否是员工 AppUser appUser1 = appUserClient.queryAppUser(uid); @@ -218,7 +227,7 @@ tGameRecord.setMoney(config.getCash()); gameRecordService.updateById(tGameRecord); String params = uid + "_" + gameId + "_" + spaceId + "_" + sutuId+"_"+code+"_"+configId + "_" + gameType; - ResultUtil weixinpay = payMoneyUtil.weixinpay("游戏支付", params, code, config.getCash().toString(), + ResultUtil weixinpay = payMoneyUtil.weixinpay("游戏支付-"+isFenZhang, params, code, config.getCash().toString(), "/base/game/wechatPaymentGameCallback", "APP", ""); if (weixinpay.getCode() == 200) { new Thread(new Runnable() { @@ -262,7 +271,43 @@ } gameRecordService.updateBatchById(list); Integer integer = startGame(uid, gameType, gameId, spaceId, sutuId); + if (byId.getOperatorId()!=null && byId.getOperatorId()!=0){ + // 休眠两分钟后再调用分账接口 避免提示订单正在处理中 + Thread.sleep(120000); + // 根据运营商id获取对应运营商分账比例 返回格式: 微信分账比例,支付宝分账比例 + OperatorUser operatorId = operatorUserService.getOne( + new QueryWrapper<OperatorUser>().eq("operatorId",byId.getOperatorId()) + ); + if (operatorId.getWechatProportion() == null){ + operatorId.setWechatProportion("0"); + } + if (operatorId.getAlipayProportion() == null){ + operatorId.setAlipayProportion("0"); + } + String proportion= operatorId.getWechatProportion()+","+operatorId.getAlipayProportion(); + String[] split = proportion.split(","); + String s1 = split[0]; + if (!s1.equals("未设置")){ + BigDecimal bigDecimal = new BigDecimal(s1); + // 分账比例 + BigDecimal bigDecimal1 = bigDecimal.divide(new BigDecimal(100)).setScale(2); + // 微信商户号 + String s2 =siteService.getmerchantNumberByOperatorId(byId.getOperatorId()); + String nonce_str = UUIDUtil.getRandomCode(16); + + ResultUtil fenzhang = payMoneyUtil.fenzhang(transaction_id, config.getCash().multiply(bigDecimal1), s2,nonce_str); + if (!fenzhang.getCode().equals(500)){ + System.err.println("分账失败 原因是:"+fenzhang.getMsg()); + }else{ + tGameRecord.setFenzhangNo(fenzhang.getMsg()); + tGameRecord.setFenzhangOrderNo(nonce_str); + tGameRecord.setFenzhangAmount(config.getCash().multiply(bigDecimal1)); + gameRecordService.updateById(tGameRecord); + } + } + } break; + } if ("USERPAYING".equals(s) || "NOTPAY".equals(s)) { num++; diff --git a/cloud-server-other/src/main/java/com/dsh/other/controller/SiteController.java b/cloud-server-other/src/main/java/com/dsh/other/controller/SiteController.java index b611816..3092149 100644 --- a/cloud-server-other/src/main/java/com/dsh/other/controller/SiteController.java +++ b/cloud-server-other/src/main/java/com/dsh/other/controller/SiteController.java @@ -15,6 +15,7 @@ import com.dsh.other.feignclient.model.BillingDataRequestVo; import com.dsh.other.feignclient.model.SiteChangeStateVO; import com.dsh.other.feignclient.model.SiteVo; +import com.dsh.other.mapper.TOperatorUserMapper; import com.dsh.other.model.*; import com.dsh.other.model.dto.siteDto.TSiteDTO; import com.dsh.other.model.vo.siteVo.ExpireSiteSearchVO; @@ -66,6 +67,8 @@ @Resource private CityManagerClient cityManagerClient; + @Autowired + private IOperatorUserService operatorUserService; @Autowired private TGameConfigService gameConfigService; @@ -75,6 +78,7 @@ @Resource private CourseRecordClient courseRecordClient; + @Autowired private RedisUtil redisUtil; @@ -95,8 +99,32 @@ @RequestMapping("/base/getSMIDByOperatorId") @ResponseBody public String getSMIDByOperatorId(Integer id) { - // 获取运营商的管理员 return siteService.getSMIDByOperatorId(id); + } + /** + * 通过运营商id查询运营商对应的微信商户号 + */ + @RequestMapping("/base/getmerchantNumberByOperatorId") + @ResponseBody + public String getmerchantNumberByOperatorId(Integer id) { + return siteService.getmerchantNumberByOperatorId(id); + } + /** + * 根据运营商id获取对应运营商分账比例 返回格式: 微信分账比例,支付宝分账比例 + */ + @RequestMapping("/base/getProportionByOperatorId") + @ResponseBody + public String getProportionByOperatorId(Integer id) { + OperatorUser operatorId = operatorUserService.getOne( + new QueryWrapper<OperatorUser>().eq("operatorId",id) + ); + if (operatorId.getWechatProportion() == null){ + operatorId.setWechatProportion("0"); + } + if (operatorId.getAlipayProportion() == null){ + operatorId.setAlipayProportion("0"); + } + return operatorId.getWechatProportion()+","+operatorId.getAlipayProportion(); } /** * 获取所有场地 @@ -686,10 +714,6 @@ @Autowired private StoreService service; - - @Autowired - private IOperatorUserService operatorUserService; - @ResponseBody @PostMapping("/base/site/game") diff --git a/cloud-server-other/src/main/java/com/dsh/other/entity/SiteBooking.java b/cloud-server-other/src/main/java/com/dsh/other/entity/SiteBooking.java index cbfc476..2653f40 100644 --- a/cloud-server-other/src/main/java/com/dsh/other/entity/SiteBooking.java +++ b/cloud-server-other/src/main/java/com/dsh/other/entity/SiteBooking.java @@ -8,6 +8,7 @@ import io.swagger.annotations.ApiModelProperty; import lombok.Data; +import java.math.BigDecimal; import java.util.Date; import java.util.List; @@ -191,4 +192,20 @@ private List<Integer> rid; @TableField("addType") private Integer addType; + /** + * 分账流水号 + */ + @TableField("fenzhangNo") + private String fenzhangNo; + /** + * 分账业务号 存值表明已分账 未存表明未分账 + */ + @TableField("fenzhangOrderNo") + private String fenzhangOrderNo; + // 分账金额 + @TableField("fenzhangAmount") + private BigDecimal fenzhangAmount; + // 分账回退流水号 + @TableField("fenzhangRefundNo") + private String fenzhangRefundNo; } diff --git a/cloud-server-other/src/main/java/com/dsh/other/entity/TGameRecord.java b/cloud-server-other/src/main/java/com/dsh/other/entity/TGameRecord.java index e814c0d..a639a50 100644 --- a/cloud-server-other/src/main/java/com/dsh/other/entity/TGameRecord.java +++ b/cloud-server-other/src/main/java/com/dsh/other/entity/TGameRecord.java @@ -62,7 +62,18 @@ private Date time; - + /** + * 分账流水号 + */ + private String fenzhangNo; + /** + * 分账业务号 存值表明已分账 未存表明未分账 + */ + private String fenzhangOrderNo; + // 分账金额 + private BigDecimal fenzhangAmount; + // 分账回退流水号 + private String fenzhangRefundNo; @Override protected Serializable pkVal() { return this.id; diff --git a/cloud-server-other/src/main/java/com/dsh/other/feignclient/StoreClient.java b/cloud-server-other/src/main/java/com/dsh/other/feignclient/StoreClient.java index 461a683..b51e0d7 100644 --- a/cloud-server-other/src/main/java/com/dsh/other/feignclient/StoreClient.java +++ b/cloud-server-other/src/main/java/com/dsh/other/feignclient/StoreClient.java @@ -11,7 +11,12 @@ @FeignClient(value = "mb-cloud-other") public interface StoreClient { - + /** + * 根据运营商id获取对应运营商商户号 + * @return + */ + @PostMapping("/base/getSMIDByOperatorId") + String getSMIDByOperatorId(Integer id); @PostMapping("/base/protocol/storeDetail/courseOfSto") StoreDetailOfCourse getCourseOfStore(@RequestParam("storeId") Integer storeId); diff --git a/cloud-server-other/src/main/java/com/dsh/other/mapper/SiteMapper.java b/cloud-server-other/src/main/java/com/dsh/other/mapper/SiteMapper.java index c677a2c..e82bac1 100644 --- a/cloud-server-other/src/main/java/com/dsh/other/mapper/SiteMapper.java +++ b/cloud-server-other/src/main/java/com/dsh/other/mapper/SiteMapper.java @@ -49,5 +49,6 @@ List<TSiteDTO> listExipre(@Param("query") ExpireSiteSearchVO vo); String getSMIDByOperatorId(@Param("id")Integer id); + String getmerchantNumberByOperatorId(@Param("id")Integer id); } diff --git a/cloud-server-other/src/main/java/com/dsh/other/service/ISiteService.java b/cloud-server-other/src/main/java/com/dsh/other/service/ISiteService.java index 15295f6..76de886 100644 --- a/cloud-server-other/src/main/java/com/dsh/other/service/ISiteService.java +++ b/cloud-server-other/src/main/java/com/dsh/other/service/ISiteService.java @@ -102,5 +102,6 @@ Object changeState(SiteChangeStateVO vo); String getSMIDByOperatorId(Integer id); + String getmerchantNumberByOperatorId(Integer id); } diff --git a/cloud-server-other/src/main/java/com/dsh/other/service/impl/SiteServiceImpl.java b/cloud-server-other/src/main/java/com/dsh/other/service/impl/SiteServiceImpl.java index 767ab40..0397da7 100644 --- a/cloud-server-other/src/main/java/com/dsh/other/service/impl/SiteServiceImpl.java +++ b/cloud-server-other/src/main/java/com/dsh/other/service/impl/SiteServiceImpl.java @@ -4,11 +4,16 @@ import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSONArray; import com.alibaba.fastjson.JSONObject; +import com.alipay.api.AlipayClient; +import com.alipay.api.DefaultAlipayClient; +import com.alipay.api.request.AlipayTradeOrderSettleRequest; +import com.alipay.api.response.AlipayTradeOrderSettleResponse; import com.alipay.api.response.AlipayTradeQueryResponse; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.dsh.other.entity.*; +import com.dsh.other.feignclient.StoreClient; import com.dsh.other.feignclient.account.AppUserClient; import com.dsh.other.feignclient.account.model.AppUser; import com.dsh.other.feignclient.activity.CouponClient; @@ -25,6 +30,7 @@ import org.aspectj.weaver.ast.Var; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; +import org.springframework.util.StringUtils; import javax.annotation.Resource; import java.math.BigDecimal; @@ -462,7 +468,15 @@ public ResultUtil weChatPaymentSite(Double paymentPrice, SiteBooking siteBooking) throws Exception { String code = siteBooking.getOrderNo(); Integer id = siteBooking.getId(); - ResultUtil weixinpay = payMoneyUtil.weixinpay("预约场地", id.toString(), code, paymentPrice.toString(), + Site byId = siteService.getById(siteBooking.getSiteId()); + // 是否分账 0否1是 + int isFenZhang= 1; + String merchantNumber = ""; + if (byId.getOperatorId()==null || byId.getOperatorId()==0){ + // 平台 + isFenZhang = 0; + } + ResultUtil weixinpay = payMoneyUtil.weixinpay("预约场地-"+isFenZhang, id.toString(), code, paymentPrice.toString(), "/base/site/weChatPaymentSiteCallback", "APP", ""); if (weixinpay.getCode() == 200) { new Thread(new Runnable() { @@ -501,6 +515,43 @@ siteBooking.setStatus(1); siteBooking.setPayOrderNo(transaction_id); siteBookingService.updateById(siteBooking); + + if (byId.getOperatorId()!=null && byId.getOperatorId()!=0){ + // 休眠两分钟后再调用分账接口 避免提示订单正在处理中 + Thread.sleep(120000); + // 根据运营商id获取对应运营商分账比例 返回格式: 微信分账比例,支付宝分账比例 + OperatorUser operatorId = operatorUserService.getOne( + new QueryWrapper<OperatorUser>().eq("operatorId",byId.getOperatorId()) + ); + if (operatorId.getWechatProportion() == null){ + operatorId.setWechatProportion("0"); + } + if (operatorId.getAlipayProportion() == null){ + operatorId.setAlipayProportion("0"); + } + String proportion= operatorId.getWechatProportion()+","+operatorId.getAlipayProportion(); + String[] split = proportion.split(","); + String s1 = split[0]; + if (!s1.equals("未设置")){ + BigDecimal bigDecimal = new BigDecimal(s1); + // 分账比例 + BigDecimal bigDecimal1 = bigDecimal.divide(new BigDecimal(100)).setScale(2); + // 微信商户号 + String s2 =siteService.getmerchantNumberByOperatorId(byId.getOperatorId()); + String nonce_str = UUIDUtil.getRandomCode(16); + BigDecimal bigDecimal2 = new BigDecimal(paymentPrice); + ResultUtil fenzhang = payMoneyUtil.fenzhang(transaction_id, bigDecimal2.multiply(bigDecimal1), s2,nonce_str); + if (!fenzhang.getCode().equals(500)){ + System.err.println("分账失败 原因是:"+fenzhang.getMsg()); + }else{ + siteBooking.setFenzhangNo(fenzhang.getMsg()); + siteBooking.setFenzhangOrderNo(nonce_str); + siteBooking.setFenzhangAmount(bigDecimal2.multiply(bigDecimal1)); + siteBookingService.updateById(siteBooking); + } + } + } + break; } if ("USERPAYING".equals(s) || "NOTPAY".equals(s)) { @@ -518,6 +569,10 @@ } private String smid = "2088330203191220";//平台支付宝商户号 + @Autowired + private IOperatorUserService operatorUserService; + @Autowired + private StoreClient storeClient; /** * 课程支付宝支付 * @@ -586,15 +641,16 @@ Store byId = storeService.getById(storeId); Integer operatorId = byId.getOperatorId(); String smid1 = ""; - if (operatorId == null ){ - // 平台的门店 - }else if (operatorId == 0){ - smid1 = smid; + if (operatorId == null || operatorId == 0){ + // 平台的门店 不冻结资金不做分账处理 + payMoneyUtil.confirm1(smid1,code,tradeNo,paymentPrice.toString()); }else{ smid1 = siteService.getSMIDByOperatorId(operatorId); - + payMoneyUtil.confirm(smid1,code,tradeNo,paymentPrice.toString()); + // 分账 + extracted(operatorId, new BigDecimal(paymentPrice.toString()), tradeNo); } - payMoneyUtil.confirm(smid1,code,tradeNo,paymentPrice.toString()); + break; } if ("WAIT_BUYER_PAY".equals(s)) { @@ -611,7 +667,53 @@ return alipay; } + private void extracted(Integer operatorId, BigDecimal coursePackageOrder1, String tradeNo) throws Exception { + // 分账 + AlipayClient alipayClient = new DefaultAlipayClient("https://openapi.alipay.com/gateway.do", + "2021004105665036", + "MIIEvwIBADANBgkqhkiG9w0BAQEFAASCBKkwggSlAgEAAoIBAQCi5i9nW/hGLJ3A06cZxTQdviFC7THpdSihoTYGLr9q006hu0V26ecBMY/o4w5bvIX0Ok/yofmZsVcCJpAPvbXL/uqVrIjnRRxXiaeBFThlxoBUTdunvbUSDYfzlEhJr5NvUKI6H6lz2niXlQGx4qy8Hau4ccWit9kM8jwUvsBVQoFgJA+xrjMvooA7YLopQtpOD+UJr5thApTSf1xrnr1W12yolTLEH15JmNV372cqXrYUuqnY0QsaPtxeqJUGAOcGdVLllQ7easEznP8DFBvDdHATcmp2SHNQDUEWN6MCVPbMgY06NQVqAXxqjTAYSVh+6TRu6bofPmpYC3TZB003AgMBAAECggEBAJAcR2+PA3NBYUYHeFrqBRMS8uX8ZR19kjZ7IgoSLTFaQsP9opRylPSPXhrPVBKAE5leRQAHn4MCSlESwHvMfxo7KFjFTFAc6dffZZpipYQUOc9bGampwJh58/3e/pyBgVMG6J23CPf/HJQtNFSkjd/V9+ayb/9l2dUEL3bC0fAZ/dbx8HsxdLw8wn3fLlWLj68hOMqa2deCZe3JdSVsPbeWqkh56FFsMLug0Nd+Ar4TgRl9/jnhXF0JWiD0LmPUYLhboY7EfUBzN4w1iYbDi1P+3zvoOYsiVKAXox9GMhQ2VzOO2UcSTuizSza2e98mGpabl/GpKmCz+RDFjtkX6eECgYEA2MyCij65eO3aGIm3FUe93DULRBYTfX8qJQSJq2WOWA3mmQlEW6L3O2B5/lG2h+8WmN6iLEs9eHpgycGYp7vAqgrANEn16ACVcuyx0scFtrZfZ+kmHMzFfiUWxJjVYk/6YngsGVBLdw6ueM42C8TTP67X9tU5TdVGoGWuqEj4W98CgYEAwFqwprXOch5Pqk/RPbb49r0Ou03K/UbciWnWWKzUhFFNS8MdlQPoDvQZbMwHLeWsa2VhaKITK3x5biLQb3U+0GLOn6lTvEyrEUH+ucREyLgVYTRAvwBPtnvlrzpyxPk2HnslQjju8WrvvLLBMKWUjlTrTOzhaHT21gz3pHMiOakCgYEAhLmfaXdBITGshb054sNLDtdCkGpbgEcrzAHdLps769iGxkYQHXHFngpQZUwtTUcoNGqIKknd1jZFrv7gsD+XkgKG7PwimehRlkwmCX5ilxtLiVgJRzRt6+5U5AMVD90a0tHzXYP0z2yjj73fBJF5KtGl0a10KZxaYrQdm1UhB00CgYBZZgzx/k9rtHC8LAqIj1CYhHejT92G53c6Gkl3vyOqN4sgKhfGmSEySfrDGPRBPZxr8ZtbIPCd5mUdberH0osWGMYFaJI1UsCy7aQwvGpniz7MhZeN7dweaOjwDs8mgtjHQ96mL4XGCDhR0BZ/wIURvZ/6iaGdhbbu9unlsWj3uQKBgQCmZYdsbbZkd3ev6f8rwyvMz+DrCQyYpY44cegBYuJgrZiQnL2fJioeN7ixX0UM48SfwsZEIrzshP/LGAwnc2MdjxKUl4jLN8SEe0NAjXOnz9Zaw740+aOmLpXcLWdP4uM2gIhWsvW1tEkQZCXmm7c9s/RsU8Pmzv+YL3+fSijOzA==", + "json", "GBK", + "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAmu8n/4yTHWbn7VOrNc9OsLtDL1bEQ8gC1dHkj8Wy5z0mkaOsjJRIG/28ze12M0V8jdCKuuDr5Z1OPKiqf+XO3ypguEh+mYUVMBM/cZodDFQfTY1TKLWjvQCuaqlA+QUTCK6f7T7stsgyQ1o9Jj0rXZDz6PM4QHSTzjrLIBaeqM5WIBvH+fy/X+QG5Utd+/UT0kc0JyvuKhZ65yVUd/C9VcwJJAPliRsAQNrqYterwAJ9zvw9tF11wj9W0XgJ8Ccu4x3gR1vrlLRJJo/OA97RmxPQ+5hSacWQZCUd1dwiBq+YCrKVHGTj14izRHXrLc0yBlRXo7tBOIqcy3IsvKVthQIDAQAB", + "RSA2"); + AlipayTradeOrderSettleRequest request = new AlipayTradeOrderSettleRequest(); + String randomCode = UUIDUtil.getRandomCode(16); + String proportionByOperatorId = operatorUserService.getOne(new QueryWrapper<OperatorUser>() + .eq("operatorId",operatorId)).getAlipayProportion(); + // 支付宝分账比例 + String s1 = proportionByOperatorId.split(",")[1]; + double i = Double.parseDouble(s1); + double v = i * 0.01; + BigDecimal bigDecimal1 = new BigDecimal(String.valueOf(v)); + // 分账金额 + BigDecimal bigDecimal2 = coursePackageOrder1.multiply(bigDecimal1).setScale(2, RoundingMode.DOWN); + request.setBizContent("{" + + " \"out_request_no\":\"" + randomCode + "\"," + + " \"trade_no\":\"" + tradeNo + "\"," + + " \"royalty_parameters\":[" + + " {" + + " \"royalty_type\":\"transfer\"," + + " \"trans_out\":\"" + storeClient.getSMIDByOperatorId(operatorId)+ "\"," + + " \"trans_out_type\":\"userId\"," + + " \"trans_in_type\":\"userId\"," + + " \"trans_in\":\"" + smid + "\"," + + " \"amount\":" + bigDecimal2 + "," + + " \"desc\":\"平台服务费\"," + + " \"royalty_scene\":\"平台服务费\"," + + " }" + + " ]," + + " \"extend_params\":{" + + " \"royalty_finish\":\"true\"" + + " }," + + " \"royalty_mode\":\"async\"" + + "}"); + AlipayTradeOrderSettleResponse response = alipayClient.execute(request); + if (response.isSuccess()) { + System.out.println("调用成功"); + } else { + System.out.println("调用失败"); + } + } /** * 玩湃币支付 * @@ -675,7 +777,7 @@ @Override public ResultUtil cancelMySite(Integer uid, Integer id) throws Exception { SiteBooking siteBooking = siteBookingService.getById(id); - + Site byId = siteService.getById(siteBooking.getSiteId()); SimpleDateFormat format = new SimpleDateFormat("yyyyMMdd"); Date startTime = siteBooking.getStartTime(); if (format.format(new Date()).equals(format.format(startTime)) && siteBooking.getStatus() != 0) { @@ -699,6 +801,26 @@ return ResultUtil.error("不能进行取消操作"); } if (siteBooking.getPayType() == 1) {//微信支付 + if (StringUtils.hasLength(siteBooking.getFenzhangNo())){ + // 是分账订单 如果分账金额不为0 那么回退分账金额 + if (siteBooking.getFenzhangAmount()!=null && siteBooking.getFenzhangAmount().compareTo(BigDecimal.ZERO)>0){ + String randomCode = UUIDUtil.getRandomCode(16); + String randomCode1 = UUIDUtil.getRandomCode(16); + if (byId.getOperatorId()!=null && byId.getOperatorId()!=0){ + // 休眠两分钟后再调用分账接口 避免提示订单正在处理中 + // 微信商户号 + String s2 =siteService.getmerchantNumberByOperatorId(byId.getOperatorId()); + ResultUtil resultUtil = payMoneyUtil.fenzhangRefund(siteBooking.getFenzhangNo(), siteBooking.getFenzhangAmount(), s2, randomCode, randomCode1); + if (!resultUtil.getCode().equals(500)){ + System.err.println("分账回退失败 原因是:"+resultUtil.getMsg()); + }else{ + siteBooking.setFenzhangRefundNo(resultUtil.getMsg()); + siteBookingService.updateById(siteBooking); + } + + } + } + } Map<String, String> map = payMoneyUtil.wxRefund(siteBooking.getPayOrderNo(), siteBooking.getOrderNo(), siteBooking.getPayMoney().toString(), siteBooking.getPayMoney().toString(), "/base/site/cancelMySiteCallback"); if (null == map) { @@ -920,4 +1042,8 @@ public String getSMIDByOperatorId(Integer id) { return siteMapper.getSMIDByOperatorId(id); } + @Override + public String getmerchantNumberByOperatorId(Integer id) { + return siteMapper.getmerchantNumberByOperatorId(id); + } } diff --git a/cloud-server-other/src/main/java/com/dsh/other/util/PayMoneyUtil.java b/cloud-server-other/src/main/java/com/dsh/other/util/PayMoneyUtil.java index 84fcdae..a7b08c9 100644 --- a/cloud-server-other/src/main/java/com/dsh/other/util/PayMoneyUtil.java +++ b/cloud-server-other/src/main/java/com/dsh/other/util/PayMoneyUtil.java @@ -21,6 +21,7 @@ import org.springframework.http.HttpHeaders; import org.springframework.http.MediaType; import org.springframework.stereotype.Component; +import org.springframework.util.StringUtils; import javax.annotation.Resource; import javax.crypto.BadPaddingException; @@ -98,6 +99,47 @@ " }," + " \"extend_params\":{" + " \"royalty_freeze\":\"true\"" + + " }" + + "}"); + AlipayTradeSettleConfirmResponse response = null; + try { + response = alipayClient.execute(request); + } catch (AlipayApiException e) { + e.printStackTrace(); + } + if(response.isSuccess()){ + System.out.println("调用成功"); + return ResultUtil.success(); + } else { + System.out.println("调用失败"); + return ResultUtil.error("出现问题啦"); + } + } + // 属于平台的运营商 因为无需分账不冻结资金 + public ResultUtil confirm1(String smid,String code, String outTradeNo, String amount) { + AlipayClient alipayClient = new DefaultAlipayClient("https://openapi.alipay.com/gateway.do", + aliAppid, + appPrivateKey, + "json", + "GBK", + alipay_public_key, + "RSA2"); + AlipayTradeSettleConfirmRequest request = new AlipayTradeSettleConfirmRequest(); + request.setBizContent("{" + + " \"out_request_no\":\""+code+"\"," + + " \"trade_no\":\""+outTradeNo+"\"," + + " \"settle_info\":{" + + " \"settle_detail_infos\":[" + + " {" + + " \"trans_in_type\":\"defaultSettle\"," + + " \"settle_entity_id\":\""+smid+"\"," + + " \"settle_entity_type\":\"SecondMerchant\"," + + " \"amount\":"+amount+"," + + " }" + + " ]" + + " }," + + " \"extend_params\":{" + + " \"royalty_freeze\":\"false\"" + " }" + "}"); AlipayTradeSettleConfirmResponse response = null; @@ -285,7 +327,6 @@ e.printStackTrace(); } JSONObject alipay_trade_precreate_response = JSON.parseObject(response.getBody()).getJSONObject("alipay_trade_precreate_response"); - System.err.print(alipay_trade_precreate_response.getString("qr_code")); return ResultUtil.success(alipay_trade_precreate_response.getString("qr_code")); } @@ -403,7 +444,17 @@ map.put("appid", appid); map.put("mch_id", mchId); map.put("nonce_str", nonce_str); - map.put("body", body); + String temp = ""; + if (body.split("-").length>1){ + temp = body.split("-")[1]; + map.put("body", body.split("-")[0]); + }else{ + map.put("body", body); + } + if (StringUtils.hasLength(temp) && temp.equals("1")){ + // 添加分账标识 + map.put("profit_sharing", "Y"); + } map.put("attach", attach);//存储订单id map.put("out_trade_no", out_trade_no);//存储的订单code map.put("total_fee", i); @@ -494,7 +545,142 @@ return ResultUtil.error(map1.get("return_msg"), new JSONObject()); } } + /** + * 发起分账 + * @param order 微信订单号 + * @return + */ + public ResultUtil fenzhang(String order,BigDecimal amount,String merchantNumber,String nonce_str) throws Exception { + Map<String, Object> map = new HashMap<>(); + map.put("mch_id", mchId); + map.put("appid", appid); + map.put("nonce_str", nonce_str); + map.put("transaction_id", order); + // 将这个字符串使用json格式拼接起来 + Map<String, Object> body = new HashMap<>(); + body.put("type", "MERCHANT_ID"); + body.put("account", merchantNumber); + body.put("amount", amount); + body.put("description", "订单分账"); + JSONObject jsonObject = new JSONObject(body); + String jsonString = jsonObject.toString(); + map.put("receiver",jsonString); + String s = this.weixinSignature(map); + map.put("sign", s); + String url = "https://api.mch.weixin.qq.com/secapi/pay/profitsharing"; + //设置请求头 + HttpHeaders headers = new HttpHeaders(); + headers.setContentType(MediaType.APPLICATION_XML); + StringBuffer xmlString = new StringBuffer(); + Set<String> strings = map.keySet(); + String[] keys = {}; + keys = strings.toArray(keys); + Arrays.sort(keys); + xmlString.append("<xml>"); + for (int l = 0; l < keys.length; l++) { + xmlString.append("<" + keys[l] + ">" + map.get(keys[l]) + "</" + keys[l] + ">"); + } + xmlString.append("</xml>"); + Map<String, String> map1 = null; + String body1 = null; + try { + body1 = HttpClientUtil.pushHttpsRequsetXml(url, xmlString.toString(), new HashMap<>(), mchId, certPath, "PKCS12"); + } catch (Exception e) { + e.printStackTrace(); + } + System.err.println("分账请求"+body1); + //将结果xml解析成map + body1 = body1.replaceAll("<!\\[CDATA\\[", ""); + body1 = body1.replaceAll("]]>", ""); + try { + map1 = this.xmlToMap(body1, "UTF-8"); + } catch (UnsupportedEncodingException e) { + e.printStackTrace(); + } catch (DocumentException e) { + e.printStackTrace(); + } + String return_code = map1.get("return_code"); + if ("SUCCESS".equals(return_code)) { + String result_code = map1.get("result_code"); + if ("SUCCESS".equals(result_code)) { + return ResultUtil.success(); + } else { +// System.err.println(map1.get("err_code_des")); + return ResultUtil.error(map1.get("err_code_des")); + } + } else { +// System.err.println(map1.get("return_msg") + appid + "----" + mchId); + return ResultUtil.error(map1.get("return_msg"), new JSONObject()); + } + } + /** + * 发起分账回退 + * @param order 微信订单号 + * @return + */ + public ResultUtil fenzhangRefund(String order,BigDecimal amount,String merchantNumber, + String nonce_str, + String fenzhangRefundNo) throws Exception { + Map<String, Object> map = new HashMap<>(); + map.put("mch_id", mchId); + map.put("appid", appid); + map.put("nonce_str", nonce_str); + map.put("order_id", order); + map.put("out_return_no", fenzhangRefundNo); + map.put("return_account_type", "MERCHANT_ID"); + map.put("return_account", merchantNumber); + map.put("return_amount", amount); + map.put("description", "用户退款"); + String s = this.weixinSignature(map); + map.put("sign", s); + String url = "https://api.mch.weixin.qq.com/secapi/pay/profitsharingreturn"; + //设置请求头 + HttpHeaders headers = new HttpHeaders(); + headers.setContentType(MediaType.APPLICATION_XML); + StringBuffer xmlString = new StringBuffer(); + Set<String> strings = map.keySet(); + String[] keys = {}; + keys = strings.toArray(keys); + Arrays.sort(keys); + xmlString.append("<xml>"); + for (int l = 0; l < keys.length; l++) { + xmlString.append("<" + keys[l] + ">" + map.get(keys[l]) + "</" + keys[l] + ">"); + } + xmlString.append("</xml>"); + + Map<String, String> map1 = null; + String body1 = null; + try { + body1 = HttpClientUtil.pushHttpsRequsetXml(url, xmlString.toString(), new HashMap<>(), mchId, certPath, "PKCS12"); + } catch (Exception e) { + e.printStackTrace(); + } + System.err.println("分账金额回退"+body1); + //将结果xml解析成map + body1 = body1.replaceAll("<!\\[CDATA\\[", ""); + body1 = body1.replaceAll("]]>", ""); + try { + map1 = this.xmlToMap(body1, "UTF-8"); + } catch (UnsupportedEncodingException e) { + e.printStackTrace(); + } catch (DocumentException e) { + e.printStackTrace(); + } + String return_code = map1.get("return_code"); + if ("SUCCESS".equals(return_code)) { + String result_code = map1.get("result_code"); + if ("SUCCESS".equals(result_code)) { + return ResultUtil.success(map1.get("return_no")); + } else { +// System.err.println(map1.get("err_code_des")); + return ResultUtil.error(map1.get("err_code_des")); + } + } else { +// System.err.println(map1.get("return_msg") + appid + "----" + mchId); + return ResultUtil.error(map1.get("return_msg"), new JSONObject()); + } + } /** * 微信支付成功后的回调处理 diff --git a/cloud-server-other/src/main/resources/mapper/SiteMapper.xml b/cloud-server-other/src/main/resources/mapper/SiteMapper.xml index 6b4d3e7..0a8266d 100644 --- a/cloud-server-other/src/main/resources/mapper/SiteMapper.xml +++ b/cloud-server-other/src/main/resources/mapper/SiteMapper.xml @@ -144,4 +144,7 @@ <select id="getSMIDByOperatorId" resultType="java.lang.String"> select alipayNum from t_operator_user where operatorId = #{id} </select> + <select id="getmerchantNumberByOperatorId" resultType="java.lang.String"> + select merchantNumber from t_operator where id = #{id} + </select> </mapper> -- Gitblit v1.7.1