From 7fd053651ac11db87fe4f6c57e65eed3b9a59452 Mon Sep 17 00:00:00 2001 From: 无关风月 <443237572@qq.com> Date: 星期三, 23 七月 2025 10:47:24 +0800 Subject: [PATCH] yml活动管理代码 --- ruoyi-service/ruoyi-other/src/main/java/com/ruoyi/other/util/pay/Md5_Sign.java | 27 + ruoyi-service/ruoyi-other/src/main/java/com/ruoyi/other/util/pay/Base64.java | 118 ++++++ ruoyi-service/ruoyi-order/src/main/java/com/ruoyi/order/controller/ChargeOrderController.java | 4 ruoyi-service/ruoyi-other/src/main/java/com/ruoyi/other/util/pay/HttpClientPayUtil.java | 39 ++ ruoyi-service/ruoyi-other/src/main/java/com/ruoyi/other/vo/PayDto.java | 14 ruoyi-service/ruoyi-other/src/main/java/com/ruoyi/other/util/pay/HttpRequester.java | 204 +++++++++++ ruoyi-service/ruoyi-order/src/main/java/com/ruoyi/order/service/ChargeOrderService.java | 4 ruoyi-service/ruoyi-other/src/main/java/com/ruoyi/other/controller/TServiceController.java | 1 ruoyi-service/ruoyi-other/pom.xml | 5 ruoyi-service/ruoyi-other/src/main/java/com/ruoyi/other/controller/TIntegralController.java | 73 +++ ruoyi-service/ruoyi-other/src/main/java/com/ruoyi/other/controller/WXCallBackController.java | 91 ++-- ruoyi-service/ruoyi-other/src/main/java/com/ruoyi/other/util/pay/CreateLinkStringByGet1.java | 37 ++ ruoyi-service/ruoyi-other/src/main/java/com/ruoyi/other/util/pay/RSAUtils.java | 229 ++++++++++++ ruoyi-service/ruoyi-other/src/main/java/com/ruoyi/other/util/pay/HttpRespons.java | 184 ++++++++++ ruoyi-service/ruoyi-order/src/main/java/com/ruoyi/order/service/impl/ChargeOrderServiceImpl.java | 18 15 files changed, 986 insertions(+), 62 deletions(-) diff --git a/ruoyi-service/ruoyi-order/src/main/java/com/ruoyi/order/controller/ChargeOrderController.java b/ruoyi-service/ruoyi-order/src/main/java/com/ruoyi/order/controller/ChargeOrderController.java index 418894b..1bfd56d 100644 --- a/ruoyi-service/ruoyi-order/src/main/java/com/ruoyi/order/controller/ChargeOrderController.java +++ b/ruoyi-service/ruoyi-order/src/main/java/com/ruoyi/order/controller/ChargeOrderController.java @@ -30,8 +30,8 @@ if (file.isEmpty()) { return R.fail("请选择要上传的文件"); } - chargeOrderService.importExpress(file); - return R.ok(); + + return chargeOrderService.importExpress(file); } /** diff --git a/ruoyi-service/ruoyi-order/src/main/java/com/ruoyi/order/service/ChargeOrderService.java b/ruoyi-service/ruoyi-order/src/main/java/com/ruoyi/order/service/ChargeOrderService.java index 6f6c6cc..cec3f87 100644 --- a/ruoyi-service/ruoyi-order/src/main/java/com/ruoyi/order/service/ChargeOrderService.java +++ b/ruoyi-service/ruoyi-order/src/main/java/com/ruoyi/order/service/ChargeOrderService.java @@ -1,6 +1,8 @@ package com.ruoyi.order.service; +import cn.hutool.json.JSONObject; import com.baomidou.mybatisplus.extension.service.IService; +import com.ruoyi.common.core.domain.R; import com.ruoyi.common.core.web.page.PageInfo; import com.ruoyi.order.dto.GetImportOrderDTO; import com.ruoyi.order.model.ChargeOrder; @@ -8,7 +10,7 @@ import org.springframework.web.multipart.MultipartFile; public interface ChargeOrderService extends IService<ChargeOrder> { - void importExpress(MultipartFile file); + R<JSONObject> importExpress(MultipartFile file); PageInfo<ChargeOrder> getUserPointPageList(GetImportOrderDTO getImportOrderDTO); } diff --git a/ruoyi-service/ruoyi-order/src/main/java/com/ruoyi/order/service/impl/ChargeOrderServiceImpl.java b/ruoyi-service/ruoyi-order/src/main/java/com/ruoyi/order/service/impl/ChargeOrderServiceImpl.java index dc3b6ed..5027c93 100644 --- a/ruoyi-service/ruoyi-order/src/main/java/com/ruoyi/order/service/impl/ChargeOrderServiceImpl.java +++ b/ruoyi-service/ruoyi-order/src/main/java/com/ruoyi/order/service/impl/ChargeOrderServiceImpl.java @@ -1,7 +1,7 @@ package com.ruoyi.order.service.impl; import cn.hutool.core.util.IdUtil; -import com.alibaba.fastjson2.JSONObject; +import cn.hutool.json.JSONObject; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.ruoyi.account.api.feignClient.AppUserClient; @@ -68,7 +68,7 @@ @Override - public void importExpress(MultipartFile file) { + public R<JSONObject> importExpress(MultipartFile file) { /* System.out.println("导入订单url:"+url); URL url1 = null; try { @@ -80,7 +80,7 @@ throw new RuntimeException(e); }*/ List<String> orderNumberList=new ArrayList<>(); - + JSONObject result = new JSONObject(); try (InputStream inputStream = file.getInputStream(); Workbook workbook = new XSSFWorkbook(inputStream)) { // Workbook workbook = new XSSFWorkbook(fileInputStream); @@ -238,14 +238,18 @@ //检查订单号是否重复 if (orderNumberList.contains(orderNum)) { - throw new ServiceException("订单号重复:" + orderNum, 500); +// throw new ServiceException("订单号重复:" + orderNum, 500); + result.append("订单号:[", orderNum+"]重复"); + continue; } //数据库中是否存在 ChargeOrder order = chargeOrderService.getOne(new LambdaQueryWrapper<ChargeOrder>() .eq(ChargeOrder::getOrderNumber, orderNum) ); if (order != null) { - throw new ServiceException("数据库中订单已存在:" + orderNum, 500); +// throw new ServiceException("数据库中订单已存在:" + orderNum, 500); + result.append("订单号:[", orderNum+"]数据库中订单已存在"); + continue; } orderNumberList.add(orderNum);//添加到订单集合中 @@ -279,6 +283,10 @@ e.printStackTrace(); throw new ServiceException(e.getMessage()); } + if(!result.isEmpty()){ + return R.ok(result); + } + return R.ok(); } @Override diff --git a/ruoyi-service/ruoyi-other/pom.xml b/ruoyi-service/ruoyi-other/pom.xml index fc02643..2750aaa 100644 --- a/ruoyi-service/ruoyi-other/pom.xml +++ b/ruoyi-service/ruoyi-other/pom.xml @@ -15,6 +15,11 @@ </description> <dependencies> + <dependency> + <groupId>commons-httpclient</groupId> + <artifactId>commons-httpclient</artifactId> + <version>3.1</version> + </dependency> <!-- SpringCloud Alibaba Nacos --> <dependency> <groupId>com.alibaba.cloud</groupId> diff --git a/ruoyi-service/ruoyi-other/src/main/java/com/ruoyi/other/controller/TIntegralController.java b/ruoyi-service/ruoyi-other/src/main/java/com/ruoyi/other/controller/TIntegralController.java index 21f2f8a..b9fd638 100644 --- a/ruoyi-service/ruoyi-other/src/main/java/com/ruoyi/other/controller/TIntegralController.java +++ b/ruoyi-service/ruoyi-other/src/main/java/com/ruoyi/other/controller/TIntegralController.java @@ -1,5 +1,6 @@ package com.ruoyi.other.controller; +import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSONObject; import com.ruoyi.common.core.domain.R; import com.ruoyi.common.core.web.page.PageInfo; @@ -16,9 +17,14 @@ import com.ruoyi.other.util.ObsUploadUtil; import com.ruoyi.other.util.QRCodeUtil; import com.ruoyi.other.util.UUIDUtil; +import com.ruoyi.other.util.pay.CreateLinkStringByGet1; +import com.ruoyi.other.util.pay.HttpRequester; +import com.ruoyi.other.util.pay.HttpRespons; +import com.ruoyi.other.util.pay.Md5_Sign; import com.ruoyi.other.util.payment.wx.WechatPayService; import com.ruoyi.other.vo.IntegralListVO; import com.ruoyi.other.vo.IntegralVO; +import com.ruoyi.other.vo.PayDto; import com.ruoyi.system.api.domain.SysUser; import com.ruoyi.system.api.feignClient.SysUserClient; import io.swagger.annotations.ApiOperation; @@ -38,6 +44,7 @@ import java.text.SimpleDateFormat; import java.time.LocalDateTime; import java.util.Date; +import java.util.HashMap; import java.util.Map; /** @@ -78,23 +85,23 @@ integralVO.setIntegral(integral); return R.ok(integralVO); } - @PostMapping("/queryPayStatus") + @ApiOperation(tags = {"2.0-积分钱包"},value = "查询支付结果 true成功 false失败") - public R<Boolean> integralPageList(@RequestParam("code") String code) throws Exception { - Map<String, String> resMap = wechatPayService.queryOrder(code); - if("SUCCESS".equals(resMap.get("return_code"))){ + @PostMapping(value = "/queryPayStatus") + public R buy(@RequestParam Integer id) { + IntegralPay integralPay = integralPayService.getById(id); + if (integralPay.getPayStatus()==2){ return R.ok(true); - }else{ + }else { return R.ok(false); } } - @PostMapping("/nativePay") @ApiOperation(tags = {"2.0-积分钱包"},value = "获取支付二维码") - public R nativePay(@RequestParam("amount") String amount) throws Exception { + public R<PayDto> nativePay(@RequestParam("amount") String amount) throws Exception { SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmssSSS"); String code = sdf.format(new Date()) + UUIDUtil.getNumberRandom(5); - Map<String, String> res = wechatPayService.unifiedOrder(code, amount, "积分充值", "/other/wx/integralCallback"); +// Map<String, String> res = wechatPayService.unifiedOrder(code, amount, "积分充值", "/other/wx/integralCallback"); Long userid = tokenService.getLoginUser().getUserid(); R<SysUser> sysUser = sysUserClient.getSysUser(userid); SysUser data = sysUser.getData(); @@ -119,14 +126,50 @@ integralPay.setDelFlag(0); integralPay.setCreateTime(LocalDateTime.now()); integralPayService.save(integralPay); - String codeUrl = res.get("code_url"); - MyQrCodeUtil.createCodeToFile(codeUrl); - BufferedImage blueImage = QRCodeUtil.createImage(codeUrl); - MultipartFile blueFile = convert(blueImage, new Date().getTime() + UUIDUtil.getRandomCode(3) + ".PNG"); - String s = ObsUploadUtil.obsUpload(blueFile); - System.err.println(s); - return R.ok(s); +// String codeUrl = res.get("code_url"); +// MyQrCodeUtil.createCodeToFile(codeUrl); +// BufferedImage blueImage = QRCodeUtil.createImage(codeUrl); +// MultipartFile blueFile = convert(blueImage, new Date().getTime() + UUIDUtil.getRandomCode(3) + ".PNG"); +// String s = ObsUploadUtil.obsUpload(blueFile); +// System.err.println(s); + int money = new BigDecimal(amount).multiply(BigDecimal.valueOf(100)).intValue(); + String key = "ad273ceb5e1b49e68d5c565d28d1d305";/** md5密钥商户后台-商户中心-商户设置-密钥管理获取 必填!*/ + Map<String, String> map = new HashMap<String, String>(); + map.put("p0_Version", "2.5");/** 版本号 */ + map.put("p1_MerchantNo", "888122400007793");/** 商户编号 */ + map.put("p2_OrderNo", code); /**商户订单号*/ + map.put("p3_Amount", String.valueOf(money));/**订单金额*/ + map.put("p4_Cur", "1"); /**交易币种 */ + map.put("p5_ProductName", "充值"); /** 商品名称 */ + map.put("p6_ProductDesc", "积分充值"); /** 商品名称 */ +// map.put("p7_Mp", ""); /** 如果商户请求时传递了该参数,则返回给商户时会原值传 回。 */ + map.put("p9_NotifyUrl", "http://221.182.45.100:8084/other/wx/integralCallback"); /** 服务器异步通知地址 */ + map.put("q1_FrpCode", "WEIXIN_NATIVE"); /** 微信扫码(主扫)【注:此为用户主扫,商户被扫】*/ + map.put("q4_IsShowPic", "1"); /** 是否展示二 维码图片 1表示输出*/ + map.put("q7_AppId", "wx1a4a7760be53a835"); /** 交易类型*/ + map.put("qa_TradeMerchantNo", "777165000859101"); /** 777开头的报备商户号 必填!*/ + map.put("qi_FqSellerPercen", "0"); /** 卖家承担收 费比例 目前仅支持传入 0 ,即用户承 担手续费!*/ + String Strmap = CreateLinkStringByGet1.createLinkStringByGet(map); + // 签名 + String sign = ""; + sign = Md5_Sign.SignByMD5(Strmap, key); + map.put("hmac", sign);/** 签名数据 */ + System.out.println("发送:" + JSON.toJSONString(map).toString()); + + // post请求参数内容 + HttpRequester hr = new HttpRequester(); + HttpRespons HP = hr.sendPost("https://trade.joinpay.com/tradeRt/uniPay", map); + System.out.println("接收返回参数:" + HP.getContent()); + JSONObject resPay = JSONObject.parseObject(HP.getContent()); + String rcResult = resPay.getString("rd_Pic"); + Map<String, Object> map2 = new HashMap<>(); + map2.put("rcResult", rcResult); + PayDto payDto = new PayDto(); + payDto.setId(integralPay.getId()); + payDto.setQrCode(rcResult); + return R.ok(payDto); } + public static MultipartFile convert(BufferedImage bufferedImage, String fileName) throws IOException { // 将 BufferedImage 转换为字节数组 ByteArrayOutputStream baos = new ByteArrayOutputStream(); diff --git a/ruoyi-service/ruoyi-other/src/main/java/com/ruoyi/other/controller/TServiceController.java b/ruoyi-service/ruoyi-other/src/main/java/com/ruoyi/other/controller/TServiceController.java index 6e3d633..a4de64a 100644 --- a/ruoyi-service/ruoyi-other/src/main/java/com/ruoyi/other/controller/TServiceController.java +++ b/ruoyi-service/ruoyi-other/src/main/java/com/ruoyi/other/controller/TServiceController.java @@ -106,6 +106,7 @@ @PostMapping("/nativePay") @ApiOperation(tags = {"2.0-服务费"},value = "获取支付二维码") public R nativePay(@RequestParam("amount") String amount) throws Exception { + // todo 查询每个站点的年服务费 Long userid = tokenService.getLoginUser().getUserid(); R<SysUser> sysUser = sysUserClient.getSysUser(userid); SysUser data = sysUser.getData(); diff --git a/ruoyi-service/ruoyi-other/src/main/java/com/ruoyi/other/controller/WXCallBackController.java b/ruoyi-service/ruoyi-other/src/main/java/com/ruoyi/other/controller/WXCallBackController.java index 5b6e1fd..8b3dbc9 100644 --- a/ruoyi-service/ruoyi-other/src/main/java/com/ruoyi/other/controller/WXCallBackController.java +++ b/ruoyi-service/ruoyi-other/src/main/java/com/ruoyi/other/controller/WXCallBackController.java @@ -20,6 +20,7 @@ import com.ruoyi.system.api.feignClient.SysUserClient; import io.swagger.annotations.ApiOperation; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.transaction.annotation.Transactional; import org.springframework.web.bind.annotation.*; import javax.annotation.Resource; @@ -34,7 +35,7 @@ /** * <p> - * 微信回调 + * 微信回调 * </p> * * @author 无关风月 @@ -59,22 +60,41 @@ private WechatPayService wechatPayService; @Resource private TServicePayService servicePayService; + @ResponseBody @PostMapping("/integralCallback") - public void integralCallback(HttpServletRequest request, HttpServletResponse response){ - System.err.println("积分充值回调"); - PayResult payResult= null; - try { - payResult = wechatPayService.processNotify(request); - } catch (Exception e) { - throw new RuntimeException(e); + public R integralCallback(HttpServletRequest request, String r2_OrderNo) { +// System.err.println("积分充值回调"); +// PayResult payResult= null; +// try { +// payResult = wechatPayService.processNotify(request); +// } catch (Exception e) { +// throw new RuntimeException(e); +// } + System.err.println("======积分充值回调"); + System.err.println("======积分充值回调单号" + r2_OrderNo); + System.err.println("请求" + request.getParameterMap()); + Map<String, String[]> parameterMap = request.getParameterMap(); + String r6Status = request.getParameter("r6_Status"); + if (org.springframework.util.StringUtils.hasLength(r6Status)) { + if (r6Status.equals("101")) { + return R.fail("支付失败"); + } } - IntegralPay integralPay = integralPayService.lambdaQuery().eq(IntegralPay::getCode, payResult.getOrderNumber()).one(); - if (integralPay != null && integralPay.getPayStatus() == 1){ + // 循环打印 + for (Map.Entry<String, String[]> entry : parameterMap.entrySet()) { + String key = entry.getKey(); + String[] values = entry.getValue(); + for (String value : values) { + System.err.println("======回调开始" + key + ":" + value); + } + } + IntegralPay integralPay = integralPayService.lambdaQuery().eq(IntegralPay::getCode, r2_OrderNo).one(); + if (integralPay != null && integralPay.getPayStatus() == 1) { SysUser data = sysUserClient.getSysUser(integralPay.getUserId()).getData(); integralPay.setPayStatus(2); integralPay.setPayTime(LocalDateTime.now()); - integralPay.setOrderNumber(payResult.getTransactionId()); +// integralPay.setOrderNumber(payResult.getTransactionId()); integralPayService.updateById(integralPay); IntegralRecord integralRecord = new IntegralRecord(); integralRecord.setPayId(integralPay.getId()); @@ -85,42 +105,36 @@ integralRecord.setDelFlag(0); integralRecord.setCreateTime(LocalDateTime.now()); integralRecordService.save(integralRecord); - data.setIntegral(data.getIntegral()+integralPay.getIntegralCount()); + data.setIntegral(data.getIntegral() + integralPay.getIntegralCount()); sysUserClient.updateSysUser(data); + return R.ok(null, "success"); } - response.setStatus(200); - PrintWriter out = null; - try { - out = response.getWriter(); - } catch (IOException e) { - throw new RuntimeException(e); - } - out.println("success"); - out.flush(); - out.close(); + return R.ok(null, "error"); + } + @ResponseBody @PostMapping("/serviceCallback") - public void serviceCallback(HttpServletRequest request, HttpServletResponse response){ + public void serviceCallback(HttpServletRequest request, HttpServletResponse response) { System.err.println("服务费缴纳回调"); - PayResult payResult= null; + PayResult payResult = null; try { payResult = wechatPayService.processNotify(request); } catch (Exception e) { throw new RuntimeException(e); } ServicePay servicePay = servicePayService.lambdaQuery().eq(ServicePay::getCode, payResult.getOrderNumber()).one(); - if (servicePay != null && servicePay.getPayStatus() == 1){ + if (servicePay != null && servicePay.getPayStatus() == 1) { servicePay.setPayStatus(2); ServicePay servicePayBefore = servicePayService.lambdaQuery() .eq(ServicePay::getUserId, servicePay.getUserId()) - .eq(ServicePay::getPayStatus,2) + .eq(ServicePay::getPayStatus, 2) .orderByDesc(ServicePay::getCreateTime) .last("limit 1") .one(); - if (servicePayBefore!=null){ + if (servicePayBefore != null) { servicePay.setEndTime(servicePayBefore.getEndTime().plusDays(365)); - }else{ + } else { servicePay.setEndTime(LocalDateTime.now().plusDays(365)); } @@ -130,18 +144,17 @@ servicePay.setOrderNumber(payResult.getTransactionId()); servicePayService.updateById(servicePay); } - response.setStatus(200); - PrintWriter out = null; - try { - out = response.getWriter(); - } catch (IOException e) { - throw new RuntimeException(e); - } - out.println("success"); - out.flush(); - out.close(); + response.setStatus(200); + PrintWriter out = null; + try { + out = response.getWriter(); + } catch (IOException e) { + throw new RuntimeException(e); + } + out.println("success"); + out.flush(); + out.close(); } - } diff --git a/ruoyi-service/ruoyi-other/src/main/java/com/ruoyi/other/util/pay/Base64.java b/ruoyi-service/ruoyi-other/src/main/java/com/ruoyi/other/util/pay/Base64.java new file mode 100644 index 0000000..6955b2e --- /dev/null +++ b/ruoyi-service/ruoyi-other/src/main/java/com/ruoyi/other/util/pay/Base64.java @@ -0,0 +1,118 @@ +package com.ruoyi.other.util.pay; + +import java.io.ByteArrayOutputStream; + +/** + * base64 format encoding & decoding + */ +public class Base64 { + + private static char[] base64EncodeChars = new char[] { 'A', 'B', 'C', 'D', + 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', + 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd', + 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', + 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', '0', '1', '2', '3', + '4', '5', '6', '7', '8', '9', '+', '/' }; + + private static byte[] base64DecodeChars = new byte[] { -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, 62, -1, -1, -1, 63, 52, 53, 54, 55, 56, 57, 58, 59, + 60, 61, -1, -1, -1, -1, -1, -1, -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, + 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, -1, + -1, -1, -1, -1, -1, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, + 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, -1, -1, -1, + -1, -1 }; + + private Base64(){ + } + + public static String encode(byte[] data){ + StringBuffer sb = new StringBuffer(); + int len = data.length; + int i = 0; + int b1, b2, b3; + + while (i < len) { + b1 = data[i++] & 0xff; + if (i == len) { + sb.append(base64EncodeChars[b1 >>> 2]); + sb.append(base64EncodeChars[(b1 & 0x3) << 4]); + sb.append("=="); + break; + } + b2 = data[i++] & 0xff; + if (i == len) { + sb.append(base64EncodeChars[b1 >>> 2]); + sb.append(base64EncodeChars[((b1 & 0x03) << 4) + | ((b2 & 0xf0) >>> 4)]); + sb.append(base64EncodeChars[(b2 & 0x0f) << 2]); + sb.append("="); + break; + } + b3 = data[i++] & 0xff; + sb.append(base64EncodeChars[b1 >>> 2]); + sb.append(base64EncodeChars[((b1 & 0x03) << 4) + | ((b2 & 0xf0) >>> 4)]); + sb.append(base64EncodeChars[((b2 & 0x0f) << 2) + | ((b3 & 0xc0) >>> 6)]); + sb.append(base64EncodeChars[b3 & 0x3f]); + } + return sb.toString(); + } + + public static byte[] decode(String str){ + byte[] data = str.getBytes(); + int len = data.length; + ByteArrayOutputStream buf = new ByteArrayOutputStream(len); + int i = 0; + int b1, b2, b3, b4; + + while (i < len) { + + /* b1 */ + do { + b1 = base64DecodeChars[data[i++]]; + } while (i < len && b1 == -1); + if (b1 == -1) { + break; + } + + /* b2 */ + do { + b2 = base64DecodeChars[data[i++]]; + } while (i < len && b2 == -1); + if (b2 == -1) { + break; + } + buf.write(((b1 << 2) | ((b2 & 0x30) >>> 4))); + + /* b3 */ + do { + b3 = data[i++]; + if (b3 == 61) { + return buf.toByteArray(); + } + b3 = base64DecodeChars[b3]; + } while (i < len && b3 == -1); + if (b3 == -1) { + break; + } + buf.write((((b2 & 0x0f) << 4) | ((b3 & 0x3c) >>> 2))); + + /* b4 */ + do { + b4 = data[i++]; + if (b4 == 61) { + return buf.toByteArray(); + } + b4 = base64DecodeChars[b4]; + } while (i < len && b4 == -1); + if (b4 == -1) { + break; + } + buf.write((((b3 & 0x03) << 6) | b4)); + } + return buf.toByteArray(); + } +} diff --git a/ruoyi-service/ruoyi-other/src/main/java/com/ruoyi/other/util/pay/CreateLinkStringByGet1.java b/ruoyi-service/ruoyi-other/src/main/java/com/ruoyi/other/util/pay/CreateLinkStringByGet1.java new file mode 100644 index 0000000..84b7f4d --- /dev/null +++ b/ruoyi-service/ruoyi-other/src/main/java/com/ruoyi/other/util/pay/CreateLinkStringByGet1.java @@ -0,0 +1,37 @@ +package com.ruoyi.other.util.pay; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.Map; + +/** + * 参数的拼接整理 + * @author Lori + * @version 2018年6月04日 + */ +public class CreateLinkStringByGet1 { + public static String createLinkStringByGet(Map<String, String> params){ + List<String> keys = new ArrayList<String>(params.keySet()); + Collections.sort(keys); + String str1 =""; + for(int i=0;i<keys.size();i++) { + String key = keys.get(i); + + + Object value = params.get(key);//(String) 强制类型转换 + if(value instanceof Integer) { + value = (Integer)value; + } + if(i==keys.size()-1) { + + str1 = str1+value.toString(); + }else { + + str1 = str1+value; + } + } + System.out.println("整理"+str1); + return str1; + } +} diff --git a/ruoyi-service/ruoyi-other/src/main/java/com/ruoyi/other/util/pay/HttpClientPayUtil.java b/ruoyi-service/ruoyi-other/src/main/java/com/ruoyi/other/util/pay/HttpClientPayUtil.java new file mode 100644 index 0000000..e940cf6 --- /dev/null +++ b/ruoyi-service/ruoyi-other/src/main/java/com/ruoyi/other/util/pay/HttpClientPayUtil.java @@ -0,0 +1,39 @@ +package com.ruoyi.other.util.pay; + +/** + * 类HttpClientUtil + * + * @author Lori 2018年6月04日 下午16:10:04 + */ + +import org.apache.http.HttpEntity; +import org.apache.http.client.methods.CloseableHttpResponse; +import org.apache.http.client.methods.HttpPost; +import org.apache.http.entity.StringEntity; +import org.apache.http.impl.client.CloseableHttpClient; +import org.apache.http.impl.client.HttpClients; +import org.apache.http.util.EntityUtils; + +public class HttpClientPayUtil { + public static String sendHttpPost(String url, String body) throws Exception { + CloseableHttpClient httpClient = HttpClients.createDefault(); + HttpPost httpPost = new HttpPost(url); + httpPost.addHeader("Content-Type","application/json;charset=UTF-8"); + //UrlEncodedFormEntity setEntity = new UrlEncodedFormEntity(body, HTTP.UTF_8); + StringEntity setEntity = new StringEntity(body,"utf-8"); + setEntity.setContentType("application/json"); + setEntity.setContentEncoding("UTF-8"); + httpPost.setEntity(setEntity); + + + CloseableHttpResponse response = httpClient.execute(httpPost); + System.out.println(response.getStatusLine().getStatusCode() + "\n"); + HttpEntity entity = response.getEntity(); + String responseContent = EntityUtils.toString(entity, "UTF-8"); + System.out.println(responseContent); + + response.close(); + httpClient.close(); + return responseContent; + } +} diff --git a/ruoyi-service/ruoyi-other/src/main/java/com/ruoyi/other/util/pay/HttpRequester.java b/ruoyi-service/ruoyi-other/src/main/java/com/ruoyi/other/util/pay/HttpRequester.java new file mode 100644 index 0000000..b7dfba2 --- /dev/null +++ b/ruoyi-service/ruoyi-other/src/main/java/com/ruoyi/other/util/pay/HttpRequester.java @@ -0,0 +1,204 @@ +package com.ruoyi.other.util.pay; + +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.net.HttpURLConnection; +import java.net.URL; +import java.net.URLEncoder; +import java.nio.charset.Charset; +import java.util.Map; +import java.util.Vector; + +public class HttpRequester { + private String defaultContentEncoding; + + public HttpRequester() { + this.defaultContentEncoding = Charset.defaultCharset().name(); + } + + /** + * 发送POST请求 + * + * @param urlString + * URL地址 + * @return 响应对象 + * @throws IOException + */ + public HttpRespons sendPost(String urlString) throws IOException { + return this.send(urlString, "POST", null, null); + } + + /** + * 发送POST请求 + * + * @param urlString + * URL地址 + * @param params + * 参数集合 + * @return 响应对象 + * @throws IOException + */ + public HttpRespons sendPost(String urlString, Map<String, String> params) + throws IOException { + + for(String key : params.keySet()) { + if(params.get(key)!=null&&!"".equals(params.get(key))) { + params.put(key, (String)URLEncoder.encode(params.get(key),"utf-8")) ;//(String) 强制类型转换 + } + } + + + + return this.send(urlString, "POST", params, null); + } + + /** + * 发送POST请求 + * + * @param urlString + * URL地址 + * @param params + * 参数集合 + * @param propertys + * 请求属性 + * @return 响应对象 + * @throws IOException + */ + public HttpRespons sendPost(String urlString, Map<String, String> params, + Map<String, String> propertys) throws IOException { + return this.send(urlString, "POST", params, propertys); + } + + /** + * 发送HTTP请求 + * + * @param urlString + * @return 响映对象 + * @throws IOException + */ + private HttpRespons send(String urlString, String method, + Map<String, String> parameters, Map<String, String> propertys) + throws IOException { + HttpURLConnection urlConnection = null; + + if (method.equalsIgnoreCase("GET") && parameters != null) { + StringBuffer param = new StringBuffer(); + int i = 0; + for (String key : parameters.keySet()) { + if (i == 0) + param.append("?"); + else + param.append("&"); + param.append(key).append("=").append(parameters.get(key)); + i++; + } + urlString += param; + } + URL url = new URL(urlString); + urlConnection = (HttpURLConnection) url.openConnection(); + + urlConnection.setRequestMethod(method); + urlConnection.setDoOutput(true); + urlConnection.setDoInput(true); + urlConnection.setUseCaches(false); + + if (propertys != null) + for (String key : propertys.keySet()) { + urlConnection.addRequestProperty(key, propertys.get(key)); + } + + if (method.equalsIgnoreCase("POST") && parameters != null) { + StringBuffer param = new StringBuffer(); + for (String key : parameters.keySet()) { + param.append("&"); + param.append(key).append("=").append(parameters.get(key)); + } + urlConnection.getOutputStream().write(param.toString().getBytes()); + urlConnection.getOutputStream().flush(); + urlConnection.getOutputStream().close(); + } + + return this.makeContent(urlString, urlConnection); + } + + /** + * 得到响应对象 + * + * @param urlConnection + * @return 响应对象 + * @throws IOException + */ + private HttpRespons makeContent(String urlString, + HttpURLConnection urlConnection) throws IOException { + HttpRespons httpResponser = new HttpRespons(); + try { + InputStream in = urlConnection.getInputStream(); + BufferedReader bufferedReader = new BufferedReader( + new InputStreamReader(in)); + httpResponser.contentCollection = new Vector<String>(); + StringBuffer temp = new StringBuffer(); + String line = bufferedReader.readLine(); + while (line != null) { + httpResponser.contentCollection.add(line); + temp.append(line).append("\r\n"); + line = bufferedReader.readLine(); + } + bufferedReader.close(); + + String ecod = urlConnection.getContentEncoding(); + if (ecod == null) + ecod = this.defaultContentEncoding; + + httpResponser.urlString = urlString; + + httpResponser.defaultPort = urlConnection.getURL().getDefaultPort(); + httpResponser.file = urlConnection.getURL().getFile(); + httpResponser.host = urlConnection.getURL().getHost(); + httpResponser.path = urlConnection.getURL().getPath(); + httpResponser.port = urlConnection.getURL().getPort(); + httpResponser.protocol = urlConnection.getURL().getProtocol(); + httpResponser.query = urlConnection.getURL().getQuery(); + httpResponser.ref = urlConnection.getURL().getRef(); + httpResponser.userInfo = urlConnection.getURL().getUserInfo(); + + httpResponser.content = new String(temp.toString().getBytes(), ecod); + httpResponser.contentEncoding = ecod; + httpResponser.code = urlConnection.getResponseCode(); + httpResponser.message = urlConnection.getResponseMessage(); + httpResponser.contentType = urlConnection.getContentType(); + httpResponser.method = urlConnection.getRequestMethod(); + httpResponser.connectTimeout = urlConnection.getConnectTimeout(); + httpResponser.readTimeout = urlConnection.getReadTimeout(); + + return httpResponser; + } catch (IOException e) { + throw e; + } finally { + if (urlConnection != null) + urlConnection.disconnect(); + } + } + + /** + * 默认的响应字符集 + */ + public String getDefaultContentEncoding() { + return this.defaultContentEncoding; + } + + /** + * 设置默认的响应字符集 + */ + public void setDefaultContentEncoding(String defaultContentEncoding) { + this.defaultContentEncoding = defaultContentEncoding; + } + +} + + + + + + diff --git a/ruoyi-service/ruoyi-other/src/main/java/com/ruoyi/other/util/pay/HttpRespons.java b/ruoyi-service/ruoyi-other/src/main/java/com/ruoyi/other/util/pay/HttpRespons.java new file mode 100644 index 0000000..b82bb11 --- /dev/null +++ b/ruoyi-service/ruoyi-other/src/main/java/com/ruoyi/other/util/pay/HttpRespons.java @@ -0,0 +1,184 @@ +package com.ruoyi.other.util.pay; + + + +import org.apache.commons.httpclient.HttpClient; +import org.apache.commons.httpclient.methods.InputStreamRequestEntity; +import org.apache.commons.httpclient.methods.PostMethod; +import org.apache.commons.httpclient.methods.RequestEntity; + +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.util.Vector; + + + +public class HttpRespons { + String urlString; + + int defaultPort; + + String file; + + String host; + + String path; + + int port; + + String protocol; + + String query; + + String ref; + + String userInfo; + + String contentEncoding; + + String content; + + String contentType; + + int code; + + String message; + + String method; + + int connectTimeout; + + int readTimeout; + + Vector<String> contentCollection; + + public String getContent() { + return content; + } + + public String getContentType() { + return contentType; + } + + public int getCode() { + return code; + } + + public String getMessage() { + return message; + } + + public Vector<String> getContentCollection() { + return contentCollection; + } + + public String getContentEncoding() { + return contentEncoding; + } + + public String getMethod() { + return method; + } + + public int getConnectTimeout() { + return connectTimeout; + } + + public int getReadTimeout() { + return readTimeout; + } + + public String getUrlString() { + return urlString; + } + + public int getDefaultPort() { + return defaultPort; + } + + public String getFile() { + return file; + } + + public String getHost() { + return host; + } + + public String getPath() { + return path; + } + + public int getPort() { + return port; + } + + public String getProtocol() { + return protocol; + } + + public String getQuery() { + return query; + } + + public String getRef() { + return ref; + } + + public String getUserInfo() { + return userInfo; + } + + + public static String post(String params,String requestUrl) throws IOException { +// try { + //HttpRequester request = new HttpRequester(); + // request.setDefaultContentEncoding("utf-8"); + byte[] requestBytes = params.getBytes("utf-8"); // 将参数转为二进制流 + HttpClient httpClient = new HttpClient(); // 客户端实例化 + PostMethod postMethod = new PostMethod(requestUrl); + //设置请求头Authorization +// postMethod.setRequestHeader("Authorization", "Basic " + authorization); + // 设置请求头 Content-Type + postMethod.setRequestHeader("Content-Type", "application/json"); + InputStream inputStream = new ByteArrayInputStream(requestBytes, 0,requestBytes.length); + RequestEntity requestEntity = new InputStreamRequestEntity(inputStream, + requestBytes.length, "application/json; charset=utf-8"); // 请求体 + postMethod.setRequestEntity(requestEntity); + httpClient.executeMethod(postMethod);// 执行请求 + InputStream soapResponseStream = postMethod.getResponseBodyAsStream();// 获取返回的流 + byte[] datas = null; + try { + datas = readInputStream(soapResponseStream);// 从输入流中读取数据 + } catch (Exception e) { + e.printStackTrace(); + } + String result = new String(datas, "UTF-8");// 将二进制流转为String + // 打印返回结果 + // System.out.println(result); + + return result; + } + + + /** + * 从输入流中读取数据 + * + * @param inStream + * @return + * @throws Exception + */ + public static byte[] readInputStream(InputStream inStream) throws Exception { + ByteArrayOutputStream outStream = new ByteArrayOutputStream(); + byte[] buffer = new byte[1024]; + int len = 0; + while ((len = inStream.read(buffer)) != -1) { + outStream.write(buffer, 0, len); + } + byte[] data = outStream.toByteArray(); + outStream.close(); + inStream.close(); + return data; + } +} diff --git a/ruoyi-service/ruoyi-other/src/main/java/com/ruoyi/other/util/pay/Md5_Sign.java b/ruoyi-service/ruoyi-other/src/main/java/com/ruoyi/other/util/pay/Md5_Sign.java new file mode 100644 index 0000000..00c1bbb --- /dev/null +++ b/ruoyi-service/ruoyi-other/src/main/java/com/ruoyi/other/util/pay/Md5_Sign.java @@ -0,0 +1,27 @@ +package com.ruoyi.other.util.pay; + +import org.apache.commons.codec.digest.DigestUtils; + +/** + * 类MD5_Sign:MD5签名和验签 + * + * @author Lori 2018年6月04日 下午16:10:04 + */ +public class Md5_Sign { + + /** + * MD5签名 + * + * @param requestSign 请求签名串 + * @param merchantKey 商户秘钥 + */ + public static String SignByMD5(String requestSign, String merchantKey) { + + String reqHmac = ""; + try { + reqHmac = DigestUtils.md5Hex(requestSign + merchantKey).toUpperCase(); + } catch (Exception e) {} + + return reqHmac; + } +} diff --git a/ruoyi-service/ruoyi-other/src/main/java/com/ruoyi/other/util/pay/RSAUtils.java b/ruoyi-service/ruoyi-other/src/main/java/com/ruoyi/other/util/pay/RSAUtils.java new file mode 100644 index 0000000..eff336d --- /dev/null +++ b/ruoyi-service/ruoyi-other/src/main/java/com/ruoyi/other/util/pay/RSAUtils.java @@ -0,0 +1,229 @@ + +package com.ruoyi.other.util.pay; + +import java.io.*; +import java.security.*; +import java.security.cert.Certificate; +import java.security.cert.CertificateException; +import java.security.cert.CertificateFactory; +import java.security.spec.InvalidKeySpecException; +import java.security.spec.PKCS8EncodedKeySpec; +import java.security.spec.X509EncodedKeySpec; +import java.util.Enumeration; + +/** */ +/** + * <p> + * RSA公钥/私钥/签名工具包 + * </p> + * <p> + * 罗纳德·李维斯特(Ron [R]ivest)、阿迪·萨莫尔(Adi [S]hamir)和伦纳德·阿德曼(Leonard [A]dleman) + * </p> + * <p> + * 字符串格式的密钥在未在特殊说明情况下都为BASE64编码格式<br/> + * 由于非对称加密速度极其缓慢,一般文件不使用它来加密而是使用对称加密,<br/> + * 非对称加密算法可以用来对对称加密的密钥加密,这样保证密钥的安全也就保证了数据的安全 + * </p> + * + * @author IceWee + * @date 2012-4-26 + * @version 1.0 + */ +public class RSAUtils { + + /** */ + /** + * 加密算法RSA + */ + public static final String KEY_ALGORITHM = "RSA"; + + /** */ + /** + * 签名算法 + */ + public static final String SIGNATURE_ALGORITHM = "MD5withRSA"; + + /** + * 获取RSA私钥串 + * + * @param in + * RSA私钥证书文件流 + * @param fileSuffix + * RSA私钥名称,决定编码类型|PFX、JKS、PEM... + * @param password + * RSA私钥保护密钥|口令 + * @param keyAlgorithm + * 密钥算法 + * @return RSA私钥对象 + * @throws ServiceException + */ + public static String getRSAPrivateKeyByFileSuffix(InputStream in, String fileSuffix, String password, String keyAlgorithm) + throws Exception { + String keyType = ""; + if ("keystore".equalsIgnoreCase(fileSuffix)) { + keyType = "JKS"; + } else if ("pfx".equalsIgnoreCase(fileSuffix) || "p12".equalsIgnoreCase(fileSuffix)) { + keyType = "PKCS12"; + } else if ("jck".equalsIgnoreCase(fileSuffix)) { + keyType = "JCEKS"; + } else if ("pem".equalsIgnoreCase(fileSuffix) || "pkcs8".equalsIgnoreCase(fileSuffix)) { + keyType = "PKCS8"; + } /*else if ("pkcs1".equalsIgnoreCase(fileSuffix)) { + keyType = "PKCS1"; + } */else { + keyType = "JKS"; + } + + try { + PrivateKey priKey = null; + if ("JKS".equals(keyType) || "PKCS12".equals(keyType) || "JCEKS".equals(keyType)) { + KeyStore ks = KeyStore.getInstance(keyType); + if (password != null) { + char[] cPasswd = password.toCharArray(); + ks.load(in, cPasswd); + Enumeration<String> aliasenum = ks.aliases(); + String keyAlias = null; + while (aliasenum.hasMoreElements()) { + keyAlias = (String) aliasenum.nextElement(); + priKey = (PrivateKey) ks.getKey(keyAlias, cPasswd); + if (priKey != null) + break; + } + } + } else { + BufferedReader br = new BufferedReader(new InputStreamReader(in)); + StringBuilder sb = new StringBuilder(); + String readLine = null; + while ((readLine = br.readLine()) != null) { + if (readLine.charAt(0) == '-') { + continue; + } else { + sb.append(readLine); + sb.append('\r'); + } + } + + if ("PKCS8".equals(keyType)) { + System.out.println("1"); + PKCS8EncodedKeySpec priPKCS8 = new PKCS8EncodedKeySpec(Base64.decode(sb.toString())); + System.out.println("2"); + KeyFactory keyFactory = KeyFactory.getInstance(keyAlgorithm); + System.out.println("3"); + priKey = keyFactory.generatePrivate(priPKCS8); + System.out.println("4"); + + + } /*else if ("PKCS1".equals(keyType)) { + RSAPrivateKeyStructure asn1PrivKey = new RSAPrivateKeyStructure((ASN1Sequence) ASN1Sequence.fromByteArray(sb.toString().getBytes())); + KeySpec rsaPrivKeySpec = new RSAPrivateKeySpec(asn1PrivKey.getModulus(), asn1PrivKey.getPrivateExponent()); + KeyFactory keyFactory = KeyFactory.getInstance(keyAlgorithm); + priKey = keyFactory.generatePrivate(rsaPrivKeySpec); + }*/ + } + + if (priKey != null) { + return Base64.encode(priKey.getEncoded()); + } + else { + return null; + } + } catch (FileNotFoundException e) { + throw new FileNotFoundException("私钥路径文件不存在"); + } catch (KeyStoreException e) { + throw new KeyStoreException("获取KeyStore对象异常"); + } catch (IOException e) { + throw new IOException("读取私钥异常"); + } catch (NoSuchAlgorithmException e) { + throw new NoSuchAlgorithmException("生成私钥对象异常"); + } catch (CertificateException e) { + throw new CertificateException("加载私钥密码异常"); + } catch (UnrecoverableKeyException e) { + throw new UnrecoverableKeyException("生成私钥对象异常"); + } catch (InvalidKeySpecException e) { + throw new InvalidKeySpecException("生成私钥对象异常"); + } finally { + try { + if (in != null) { + in.close(); + } + } catch (IOException e) { + } + } + } + + /** */ + /** + * <p> + * 用私钥对信息生成数字签名 + * </p> + * + * @param data 已加密数据 + * @param privateKey 私钥(BASE64编码) + * @return + * @throws Exception + */ + public static String sign(byte[] data, String privateKey) throws Exception { + byte[] keyBytes = Base64.decode(privateKey); + PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(keyBytes); + KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM); + PrivateKey privateK = keyFactory.generatePrivate(pkcs8KeySpec); + Signature signature = Signature.getInstance(SIGNATURE_ALGORITHM); + signature.initSign(privateK); + signature.update(data); + return Base64.encode(signature.sign()); + } + + /** */ + /** + * <p> + * 校验数字签名 + * </p> + * + * @param data 已加密数据 + * @param publicKey 公钥(BASE64编码) + * @param sign 数字签名 + * @param keyType 编码格式 + * @return + * @throws Exception + */ + public static boolean verify(byte[] data, String publicKey, String sign, String keyType) + throws Exception { + if ("PKCS12".equals(keyType)) { + return verify(data, publicKey, sign); + } else if ("X.509".equals(keyType)) { + byte[] keyBytes = Base64.decode(publicKey); + CertificateFactory factory = CertificateFactory.getInstance(keyType); + Certificate cert = factory.generateCertificate(new ByteArrayInputStream(keyBytes)); + PublicKey pubKey = cert.getPublicKey(); + Signature signature = Signature.getInstance(SIGNATURE_ALGORITHM); + signature.initVerify(pubKey); + signature.update(data); + return signature.verify(Base64.decode(sign)); + } + throw new Exception("==>校验数字签名:未知的证书公钥编码格式!"); + } + + /** */ + /** + * <p> + * 校验数字签名 + * </p> + * + * @param data 已加密数据 + * @param publicKey 公钥(BASE64编码) + * @param sign 数字签名 + * @return + * @throws Exception + */ + public static boolean verify(byte[] data, String publicKey, String sign) + throws Exception { + byte[] keyBytes = Base64.decode(publicKey); + X509EncodedKeySpec keySpec = new X509EncodedKeySpec(keyBytes); + KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM); + PublicKey publicK = keyFactory.generatePublic(keySpec); + Signature signature = Signature.getInstance(SIGNATURE_ALGORITHM); + signature.initVerify(publicK); + signature.update(data); + return signature.verify(Base64.decode(sign)); + } +} diff --git a/ruoyi-service/ruoyi-other/src/main/java/com/ruoyi/other/vo/PayDto.java b/ruoyi-service/ruoyi-other/src/main/java/com/ruoyi/other/vo/PayDto.java new file mode 100644 index 0000000..46476e2 --- /dev/null +++ b/ruoyi-service/ruoyi-other/src/main/java/com/ruoyi/other/vo/PayDto.java @@ -0,0 +1,14 @@ +package com.ruoyi.other.vo; + +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +@Data +@ApiModel("积分支付获取支付二维码") +public class PayDto { + @ApiModelProperty("用于支付后轮询支付状态的id") + private Integer id; + @ApiModelProperty("二维码支付链接") + private String qrCode; +} -- Gitblit v1.7.1