From 3cc8093733d705ed5415e37eb82d909509590c4b Mon Sep 17 00:00:00 2001 From: xuhy <3313886187@qq.com> Date: 星期四, 18 九月 2025 09:01:33 +0800 Subject: [PATCH] Merge remote-tracking branch 'origin/master' --- ruoyi-admin/src/main/java/com/ruoyi/web/controller/api/TSysOrderController.java | 635 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 files changed, 633 insertions(+), 2 deletions(-) diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/api/TSysOrderController.java b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/api/TSysOrderController.java index 18f17c5..eef2033 100644 --- a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/api/TSysOrderController.java +++ b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/api/TSysOrderController.java @@ -1,8 +1,63 @@ package com.ruoyi.web.controller.api; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RestController; +import cn.hutool.http.HttpRequest; +import cn.hutool.http.HttpResponse; +import cn.hutool.http.HttpUtil; +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONArray; +import com.alibaba.fastjson.JSONObject; +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.lkl.laop.sdk.exception.SDKException; +import com.ruoyi.common.core.domain.R; +import com.ruoyi.common.core.domain.entity.SysUser; +import com.ruoyi.common.utils.DateUtils; +import com.ruoyi.common.utils.ip.IpUtils; +import com.ruoyi.framework.web.service.TokenService; +import com.ruoyi.system.model.TCrmSupplier; +import com.ruoyi.system.model.TErpProcurement; +import com.ruoyi.system.model.TErpProcurementGoods; +import com.ruoyi.system.query.TErpGoodsWarehouseQuery; +import com.ruoyi.system.service.*; +import com.ruoyi.web.core.config.LakalaConfig; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import lombok.SneakyThrows; +import org.apache.commons.codec.binary.Base64; +import org.apache.commons.io.IOUtils; +import org.apache.http.client.HttpClient; +import org.apache.http.client.methods.HttpPost; +import org.apache.http.conn.ClientConnectionManager; +import org.apache.http.conn.scheme.Scheme; +import org.apache.http.conn.scheme.SchemeRegistry; +import org.apache.http.conn.ssl.SSLSocketFactory; +import org.apache.http.entity.StringEntity; +import org.apache.http.impl.client.DefaultHttpClient; +import org.apache.poi.ss.formula.functions.T; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.*; + +import javax.net.ssl.SSLContext; +import javax.net.ssl.TrustManager; +import javax.net.ssl.X509TrustManager; +import javax.servlet.http.HttpServletRequest; +import javax.validation.Valid; +import java.io.*; +import java.math.BigDecimal; +import java.math.RoundingMode; +import java.nio.charset.StandardCharsets; +import java.security.*; +import java.security.cert.*; +import java.security.spec.InvalidKeySpecException; +import java.security.spec.PKCS8EncodedKeySpec; +import java.time.LocalDateTime; +import java.time.format.DateTimeFormatter; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.concurrent.ThreadPoolExecutor; +import java.util.stream.Collectors; /** * <p> @@ -14,7 +69,583 @@ */ @RestController @RequestMapping("/t-sys-order") +@Api(tags = "订单管理") public class TSysOrderController { + private final TErpProcurementService erpProcurementService; + private final TErpProcurementGoodsService erpProcurementGoodsService; + private final TCrmSupplierService crmSupplierService; + + private final TokenService tokenService; + + + @Autowired + public TSysOrderController(TErpProcurementService erpProcurementService, TokenService tokenService, TErpProcurementGoodsService erpProcurementGoodsService, TCrmSupplierService crmSupplierService) { + this.erpProcurementService = erpProcurementService; + this.tokenService = tokenService; + this.erpProcurementGoodsService = erpProcurementGoodsService; + this.crmSupplierService = crmSupplierService; + } + + private static final String SYMBOLS = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"; + + /** + * API schema ,固定 LKLAPI-SHA256withRSA + */ + public final static String SCHEMA = "LKLAPI-SHA256withRSA"; + + /** + * 字符集固定 utf-8 + */ + public static final String ENCODING = "utf-8"; + + + private static final SecureRandom RANDOM = new SecureRandom(); + + + @ApiOperation(value = "支付") + @PostMapping(value = "/payOrder") + @SneakyThrows + public R<?> payOrder(@RequestParam String id, String type, HttpServletRequest request) { + try { + + // 查出采购单 算出价格 下单 算出应该分佣金额 应该分给谁 + TErpProcurement erpProcurement = erpProcurementService.getById(id); + if (erpProcurement.getStatus()>2) { + return R.fail("订单已支付"); + } + String ipAddr = IpUtils.getIpAddr(request); + String time = DateUtils.dateTimeNow(); + + // SYMBOLS 随机取4位数 + String nonce = ""; + for (int i = 0; i < 6; i++) { + nonce += SYMBOLS.charAt(RANDOM.nextInt(SYMBOLS.length())); + } + String outTradeNo = time + nonce; + String amount = String.valueOf(erpProcurement.getPayMoney().multiply(new BigDecimal("100")).intValue()); + + + String apiPath = "sit/api/v3/labs/trans/preorder"; + String body = "{\n" + + "\t\"req_time\": \"" + time + "\",\n" + + "\t\"version\": \"3.0\",\n" + + "\t\"req_data\": {\n" + + "\t\t\"out_trade_no\": \"" + outTradeNo + "\",\n" + + "\t\t\"merchant_no\": \"822290059430BF9\",\n" + + "\t\t\"term_no\": \"A9358698\",\n" + + "\t\t\"notify_url\": \"http://221.182.45.100:8089/t-sys-order/messageHandle\",\n" + + "\t\t\"location_info\": {\n" + + "\t\t\t\"request_ip\": \"" + ipAddr + "\"\n" + + "\t\t},\n" + + "\t\t\"subject\": \"商品采购\",\n" + + "\t\t\"settle_type\": \"1\",\n" + + "\t\t\"total_amount\": " + amount + ",\n" + + "\t\t\"account_type\": \"" + type + "\",\n" + + "\t\t\"trans_type\": \"41\"\n" + + "\t}\n" + + "}"; + String authorization = getAuthorization(body); + org.apache.http.HttpResponse response = post(LakalaConfig.getServerUrl() + apiPath, body, authorization); + if (response.getStatusLine().getStatusCode() != 200) { + return R.fail(500, "请求失败,statusCode " + response.getStatusLine() + + IOUtils.toString(response.getEntity().getContent(), ENCODING)); + } + String responseStr = IOUtils.toString(response.getEntity().getContent(), ENCODING); + + + erpProcurement.setPayNumber(outTradeNo); + JSONObject jsonObject = JSONObject.parseObject(responseStr); + JSONObject jsonObject1 = jsonObject.getJSONObject("resp_data"); + String code = jsonObject1.getString("log_no"); + erpProcurement.setPayTransactionId(code); + erpProcurement.setStatus(2); + erpProcurement.setTermNo("A9358698"); + erpProcurement.setAccountType(type); + erpProcurement.setTransType("41"); + erpProcurementService.updateById(erpProcurement); + + return R.ok(responseStr); + } catch (SDKException e) { + e.printStackTrace(); + } + return R.fail(500, "调用支付宝支付预下单接口错误"); + } + + + + @RequestMapping("/messageHandle") + @ApiOperation(value = "拉卡拉支付信息回调接口") + public Object messageHandle(HttpServletRequest request) throws Exception { + String body = this.getBody(request); + String authorization = request.getHeader("Authorization"); + String timestamp = null; + String nonce = null; + String signature = null; + authorization = authorization.replaceAll("LKLAPI-SHA256withRSA ", ""); + String[] split = authorization.split(","); + for (String s : split) { + if (s.startsWith("timestamp")) { + timestamp = s.split("=")[1].replaceAll("\"", ""); + } + if (s.startsWith("nonce")) { + nonce = s.split("=")[1].replaceAll("\"", ""); + } + if (s.startsWith("signature")) { + // 取出签名 + signature = s.split("signature=")[1].replaceAll("\"", ""); + } + } + X509Certificate lklCertificate = loadCertificate(new FileInputStream(new File(LakalaConfig.getLklNotifyCerStr()))); + String preSignData = timestamp + "\n" + nonce + "\n" + body + "\n"; + boolean verify = verify(lklCertificate, preSignData.getBytes(ENCODING), signature); + // 先处理支付完成 修改状态 后处理分账 后走分账回调 + JSONObject jsonObject1 = JSONObject.parseObject(body); + Object o = jsonObject1.get("out_trade_no"); + TErpProcurement erpProcurement = erpProcurementService.getOne(new LambdaQueryWrapper<TErpProcurement>().eq(TErpProcurement::getPayNumber, o)); + if (verify && erpProcurement.getStatus()==2) { + erpProcurement.setPayTime(LocalDateTime.now()); + erpProcurement.setStatus(3); + + List<TErpProcurementGoods> list = erpProcurementGoodsService.list(new LambdaQueryWrapper<TErpProcurementGoods>().eq(TErpProcurementGoods::getProcurementId, erpProcurement.getId())); + + + // 操作分账 + HttpRequest post = HttpUtil.createPost(LakalaConfig.getServerUrl() + "sit/api/v3/sacs/separate"); + + HashMap<String, Object> reqMap = new HashMap<>(); + reqMap.put("version", "3.0"); + reqMap.put("req_time", DateUtils.dateTimeNow()); + + + HashMap<String, Object> map = new HashMap<>(); + map.put("merchant_no", "822290059430BF9"); + map.put("log_no", erpProcurement.getPayTransactionId()); + map.put("log_date", DateUtils.dateTime()); + map.put("notify_url", "http://221.182.45.100:8089/t-sys-order/messageSeparateHandle"); + String time = DateUtils.dateTimeNow(); + + // SYMBOLS 随机取4位数 + String str = ""; + for (int i = 0; i < 6; i++) { + str += SYMBOLS.charAt(RANDOM.nextInt(SYMBOLS.length())); + } + String outTradeNo = time + str; + map.put("out_separate_no", outTradeNo); + map.put("total_amt", erpProcurement.getPayMoney().multiply(BigDecimal.valueOf(100)).intValue() + ""); + // 平台应得分账 + BigDecimal allMoney = erpProcurement.getPayMoney(); + BigDecimal payMoney = erpProcurement.getPayMoney(); + ArrayList<HashMap<String, Object>> objects = new ArrayList<>(); + // 根据供应商id分组 + Map<String, List<TErpProcurementGoods>> collect = list.stream().collect(Collectors.groupingBy(TErpProcurementGoods::getSupplierId)); + for (Map.Entry<String, List<TErpProcurementGoods>> entry : collect.entrySet()) { + HashMap<String, Object> map1 = new HashMap<>(); + String supplierId = entry.getKey(); + TCrmSupplier supplier = crmSupplierService.getById(supplierId); + List<TErpProcurementGoods> value = entry.getValue(); + BigDecimal reduce = value.stream().map(TErpProcurementGoods::getSupplierMoney).reduce(BigDecimal.ZERO, BigDecimal::add); + payMoney = payMoney.subtract(reduce); + map1.put("recv_no", supplier.getRecvMerchantNo()); + map1.put("separate_value", reduce.multiply(BigDecimal.valueOf(100)).intValue() + ""); + objects.add(map1); + } + HashMap<String, Object> map1 = new HashMap<>(); + map1.put("recv_merchant_no", "822641048160MMJ"); + // 手续费 + BigDecimal bigDecimal = allMoney.multiply(new BigDecimal("0.038")).setScale(2, RoundingMode.HALF_UP); + payMoney = payMoney.subtract(bigDecimal); + + map1.put("separate_value", payMoney.multiply(BigDecimal.valueOf(100)).intValue() + ""); + if(payMoney.doubleValue()>0){ + objects.add(map1); + } + erpProcurement.setMoney(payMoney); + erpProcurement.setOutSeparateNo(outTradeNo); + erpProcurementService.updateById(erpProcurement); + // 添加平台的 + map.put("recv_datas", objects); + + reqMap.put("req_data", map); + + + String jsonString = JSON.toJSONString(reqMap); + post.body(jsonString); + HttpResponse response = post.execute(); + String responseStr = response.body(); + JSONObject jsonObject = JSONObject.parseObject(responseStr); + if ("成功".equals(jsonObject.getString("msg"))) { + Object o1 = jsonObject.get("resp_data"); + JSONObject jsonObject2 = JSONObject.parseObject(o1.toString()); + String separate_no = jsonObject2.getString("separate_no"); + erpProcurement.setSeparateNo(separate_no); + erpProcurementService.updateById(erpProcurement); + } + + // 响应success + JSONObject responseJsonObject = new JSONObject(); + responseJsonObject.put("code", "SUCCESS"); + responseJsonObject.put("message", "执行成功"); + return responseJsonObject; + } + return null; + } + + @RequestMapping("/messageSeparateHandle") + @ApiOperation(value = "拉卡拉分账信息回调接口") + public Object messageSeparateHandle(HttpServletRequest request) throws Exception { + String body = this.getBody(request); + // 先处理支付完成 修改状态 后处理分账 后走分账回调 + JSONObject jsonObject1 = JSONObject.parseObject(body); + Object o = jsonObject1.get("out_separate_no"); + Object status = jsonObject1.get("status"); + Object cmd_type = jsonObject1.get("cmd_type"); + Object detail_datas = jsonObject1.get("detail_datas"); + JSONArray jsonArray = JSONArray.parseArray(detail_datas.toString()); + if("SEPARATE".equals(cmd_type.toString())){ + TErpProcurement erpProcurement = erpProcurementService.getOne(new LambdaQueryWrapper<TErpProcurement>().eq(TErpProcurement::getOutSeparateNo, o.toString())); + if ( erpProcurement!=null && "SUCCESS".equals(status)) { + erpProcurement.setRefundStatus(1); + erpProcurementService.updateById(erpProcurement); + // 修改分账状态 + List<TErpProcurementGoods> list1 = erpProcurementGoodsService.list(new LambdaQueryWrapper<TErpProcurementGoods>().eq(TErpProcurementGoods::getProcurementId, erpProcurement.getId())); + list1.stream().forEach(e->e.setStatus(1)); + erpProcurementGoodsService.updateBatchById(list1); + + + // 响应success + JSONObject jsonObject = new JSONObject(); + jsonObject.put("code", "SUCCESS"); + jsonObject.put("message", "执行成功"); + return jsonObject; + } + }else if("FALLBACK".equals(cmd_type.toString())){ + TErpProcurement erpProcurement = erpProcurementService.getOne(new LambdaQueryWrapper<TErpProcurement>().eq(TErpProcurement::getRefundOutSeparateNo, o.toString())); + if ( erpProcurement!=null && "SUCCESS".equals(status) && erpProcurement.getRefundStatus()==1) { + erpProcurement.setRefundStatus(2); + erpProcurementService.updateById(erpProcurement); + List<TErpProcurementGoods> list1 = erpProcurementGoodsService.list(new LambdaQueryWrapper<TErpProcurementGoods>().eq(TErpProcurementGoods::getProcurementId, erpProcurement.getId())); + list1.stream().forEach(e->e.setStatus(2)); + erpProcurementGoodsService.updateBatchById(list1); + + + // 发起退款 + String time = DateUtils.dateTimeNow(); + String ipAddr = IpUtils.getIpAddr(request); + // SYMBOLS 随机取4位数 + String str = ""; + for (int i = 0; i < 6; i++) { + str += SYMBOLS.charAt(RANDOM.nextInt(SYMBOLS.length())); + } + String outTradeNo = time + str; + String refund_amount = erpProcurement.getPayMoney().multiply(BigDecimal.valueOf(100)).intValue() + ""; + + String apiPath = "sit/api/v3/rfd/refund_front/refund"; + String body1 = "{\n" + + "\t\"req_time\": \"" + time + "\",\n" + + "\t\"version\": \"3.0\",\n" + + "\t\"req_data\": {\n" + + "\t\t\"merchant_no\": \"822290059430BF9\",\n" + + "\t\t\"term_no\": \""+erpProcurement.getTermNo()+"\",\n" + + "\t\t\"refund_amount\": " + refund_amount + ",\n" + + "\t\t\"out_trade_no\": \"" + outTradeNo + "\",\n" + + "\t\t\"notify_url\": \"" + "http://221.182.45.100:8089/t-sys-order/messageRefundHandle" + "\",\n" + + "\t\t\"origin_log_no\": \"" + erpProcurement.getPayTransactionId() + "\",\n" + + "\t\t\"location_info\": {\n" + + "\t\t\t\"request_ip\": \"" + ipAddr + "\"\n" + + "\t\t},\n" + + "\t}\n" + + "}"; + String authorization = getAuthorization(body1); + org.apache.http.HttpResponse response = post(LakalaConfig.getServerUrl() + apiPath, body1, authorization); + if (response.getStatusLine().getStatusCode() != 200) { + return R.fail(500, "请求失败,statusCode " + response.getStatusLine() + + IOUtils.toString(response.getEntity().getContent(), ENCODING)); + } + String responseStr = IOUtils.toString(response.getEntity().getContent(), ENCODING); + JSONObject jsonObject = JSONObject.parseObject(responseStr); + JSONObject jsonObject2 = jsonObject.getJSONObject("resp_data"); + String code = jsonObject2.getString("log_no"); + erpProcurement.setRefundLogNo(code); + erpProcurement.setRefundNo(outTradeNo); + erpProcurementService.updateById(erpProcurement); + + + + + // 响应success + JSONObject jsonObject3 = new JSONObject(); + jsonObject3.put("code", "SUCCESS"); + jsonObject3.put("message", "执行成功"); + return jsonObject3; + } + } + + return null; + } + @RequestMapping("/messageRefundHandle") + @ApiOperation(value = "拉卡拉退款信息回调接口") + public Object messageRefundHandle(HttpServletRequest request) throws Exception { + String body = this.getBody(request); + // 先处理支付完成 修改状态 后处理分账 后走分账回调 + JSONObject jsonObject1 = JSONObject.parseObject(body); + Object status = jsonObject1.get("trade_status"); + Object out_trade_no = jsonObject1.get("out_trade_no"); + if(status !=null && "SUCCESS".equals(status.toString())){ + TErpProcurement erpProcurement = erpProcurementService.getOne(new LambdaQueryWrapper<TErpProcurement>().eq(TErpProcurement::getRefundNo, out_trade_no.toString())); + if ( erpProcurement!=null && "SUCCESS".equals(status)) { + erpProcurement.setStatus(6); + erpProcurementService.updateById(erpProcurement); + // 响应success + JSONObject jsonObject = new JSONObject(); + jsonObject.put("code", "SUCCESS"); + jsonObject.put("message", "执行成功"); + return jsonObject; + } + } + + return null; + } + + + + + @ApiOperation(value = "退款") + @PostMapping(value = "/refundOrder") + @SneakyThrows + public R<?> refundOrder(@RequestParam String id, String type, HttpServletRequest request) { + SysUser user = tokenService.getLoginUser().getUser(); + try { + // 先退分账 在退订单 + // 查出采购单 算出价格 下单 算出应该分佣金额 应该分给谁 + TErpProcurement erpProcurement = erpProcurementService.getById(id); + // 还未分账成功不能退款 + + if(erpProcurement.getStatus()==null || erpProcurement.getStatus()!=1){ + return R.fail("订单处理中,请稍后操作"); + } + + + String time = DateUtils.dateTimeNow(); + + // SYMBOLS 随机取4位数 + String str = ""; + for (int i = 0; i < 6; i++) { + str += SYMBOLS.charAt(RANDOM.nextInt(SYMBOLS.length())); + } + String outTradeNo = time + str; + + // 操作分账 + HttpRequest post = HttpUtil.createPost(LakalaConfig.getServerUrl() + "sit/api/v3/sacs/fallback"); + HashMap<String, Object> reqMap = new HashMap<>(); + reqMap.put("version", "3.0"); + reqMap.put("req_time", DateUtils.dateTimeNow()); + + + + HashMap<String, Object> map = new HashMap<>(); + map.put("merchant_no", "822290059430BF9"); + map.put("origin_separate_no", erpProcurement.getSeparateNo()); + map.put("out_separate_no",outTradeNo); + erpProcurement.setRefundOutSeparateNo(outTradeNo); + erpProcurementService.updateById(erpProcurement); + + + List<TErpProcurementGoods> list = erpProcurementGoodsService.list(new LambdaQueryWrapper<TErpProcurementGoods>().eq(TErpProcurementGoods::getProcurementId, erpProcurement.getId())); + + // 根据供应商id分组 + Map<String, List<TErpProcurementGoods>> collect = list.stream().collect(Collectors.groupingBy(TErpProcurementGoods::getSupplierId)); + ArrayList<HashMap<String, Object>> objects = new ArrayList<>(); + BigDecimal allMoney = list.stream().map(TErpProcurementGoods::getSupplierMoney).reduce(BigDecimal.ZERO, BigDecimal::add); + for (Map.Entry<String, List<TErpProcurementGoods>> entry : collect.entrySet()) { + HashMap<String, Object> map1 = new HashMap<>(); + List<TErpProcurementGoods> value = entry.getValue(); + BigDecimal reduce = value.stream().map(TErpProcurementGoods::getSupplierMoney).reduce(BigDecimal.ZERO, BigDecimal::add); + String recv_no = value.stream().map(TErpProcurementGoods::getRecvNo).collect(Collectors.toList()).get(0); + map1.put("recv_no", recv_no); + map1.put("amt", reduce.multiply(BigDecimal.valueOf(100)).intValue() + ""); + objects.add(map1); + } + BigDecimal add = allMoney.add(erpProcurement.getMoney()).multiply(BigDecimal.valueOf(100)); + map.put("total_amt",add); + map.put("origin_recv_datas",objects); + reqMap.put("req_data", map); + + + String jsonString = JSON.toJSONString(reqMap); + post.body(jsonString); + HttpResponse response = post.execute(); + String responseStr = response.body(); + + + return R.ok(responseStr); + } catch (Exception e) { + e.printStackTrace(); + } + return R.fail(500, "调用支付宝支付预下单接口错误"); + } + + + + + + + + + public org.apache.http.HttpResponse post(String url, String message, String authorization) throws Exception { + SSLContext ctx = SSLContext.getInstance("TLS"); + X509TrustManager tm = new X509TrustManager() { + public X509Certificate[] getAcceptedIssuers() { + return null; + } + + public void checkClientTrusted(X509Certificate[] xcs, String str) { + } + + public void checkServerTrusted(X509Certificate[] xcs, String str) { + } + }; + HttpClient http = new DefaultHttpClient(); + ClientConnectionManager ccm = http.getConnectionManager(); + ctx.init(null, new TrustManager[]{tm}, null); + SSLSocketFactory ssf = new SSLSocketFactory(ctx); + ssf.setHostnameVerifier(SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER); + SchemeRegistry registry = ccm.getSchemeRegistry(); + registry.register(new Scheme("https", ssf, 443)); + HttpPost post = new HttpPost(url); + StringEntity myEntity = new StringEntity(message, ENCODING); + post.setEntity(myEntity); + post.setHeader("Authorization", SCHEMA + " " + authorization); + post.setHeader("Accept", "application/json"); + post.setHeader("Content-Type", "application/json"); + return http.execute(post); + } + + public final String getAuthorization(String body) throws IOException { + String nonceStr = generateNonceStr(); + long timestamp = generateTimestamp(); + + String message = LakalaConfig.getAppId() + "\n" + LakalaConfig.getMerchantNo() + "\n" + timestamp + "\n" + nonceStr + "\n" + body + "\n"; + + System.out.println("getToken message : " + message); + + PrivateKey merchantPrivateKey = loadPrivateKey(new FileInputStream(new File(LakalaConfig.getPriKeyStr()))); + + String signature = this.sign(message.getBytes(ENCODING), merchantPrivateKey); + + String authorization = "appid=\"" + LakalaConfig.getAppId() + "\"," + "serial_no=\"" + LakalaConfig.getMerchantNo() + "\"," + "timestamp=\"" + + timestamp + "\"," + "nonce_str=\"" + nonceStr + "\"," + "signature=\"" + signature + "\""; + System.out.println("authorization message :" + authorization); + + return authorization; + } + + public long generateTimestamp() { + return System.currentTimeMillis() / 1000; + } + + public String generateNonceStr() { + char[] nonceChars = new char[32]; + for (int index = 0; index < nonceChars.length; ++index) { + nonceChars[index] = SYMBOLS.charAt(RANDOM.nextInt(SYMBOLS.length())); + } + return new String(nonceChars); + } + + public static PrivateKey loadPrivateKey(InputStream inputStream) { + try { + ByteArrayOutputStream array = new ByteArrayOutputStream(); + byte[] buffer = new byte[1024]; + int length; + while ((length = inputStream.read(buffer)) != -1) { + array.write(buffer, 0, length); + } + + String privateKey = array.toString("utf-8").replace("-----BEGIN PRIVATE KEY-----", "") + .replace("-----END PRIVATE KEY-----", "").replaceAll("\\s+", ""); + KeyFactory kf = KeyFactory.getInstance("RSA"); + return kf.generatePrivate(new PKCS8EncodedKeySpec(Base64.decodeBase64(privateKey))); + } catch (NoSuchAlgorithmException e) { + throw new RuntimeException("当前Java环境不支持RSA", e); + } catch (InvalidKeySpecException e) { + throw new RuntimeException("无效的密钥格式"); + } catch (IOException e) { + throw new RuntimeException("无效的密钥"); + } + } + + public String sign(byte[] message, PrivateKey privateKey) { + try { + Signature sign = Signature.getInstance("SHA256withRSA"); + sign.initSign(privateKey); + sign.update(message); + return new String(Base64.encodeBase64(sign.sign())); + } catch (NoSuchAlgorithmException e) { + throw new RuntimeException("当前Java环境不支持SHA256withRSA", e); + } catch (SignatureException e) { + throw new RuntimeException("签名计算失败", e); + } catch (InvalidKeyException e) { + throw new RuntimeException("无效的私钥", e); + } + } + + + public final String getBody(HttpServletRequest request) { + InputStreamReader in = null; + try { + in = new InputStreamReader(request.getInputStream(), StandardCharsets.UTF_8); + StringBuffer bf = new StringBuffer(); + int len; + char[] chs = new char[1024]; + while ((len = in.read(chs)) != -1) { + bf.append(new String(chs, 0, len)); + } + return bf.toString(); + } catch (Exception e) { + e.printStackTrace(); + } finally { + if (null != in) { + try { + in.close(); + } catch (Exception e) { + } + } + } + return null; + } + + public static X509Certificate loadCertificate(InputStream inputStream) { + try { + CertificateFactory cf = CertificateFactory.getInstance("X509"); + X509Certificate cert = (X509Certificate) cf.generateCertificate(inputStream); + + cert.checkValidity(); + return cert; + } catch (CertificateExpiredException e) { + throw new RuntimeException("证书已过期", e); + } catch (CertificateNotYetValidException e) { + throw new RuntimeException("证书尚未生效", e); + } catch (CertificateException e) { + throw new RuntimeException("无效的证书", e); + } + } + + private static boolean verify(X509Certificate certificate, byte[] message, String signature) { + try { + Signature sign = Signature.getInstance("SHA256withRSA"); + sign.initVerify(certificate); + sign.update(message); + byte[] signatureB = Base64.decodeBase64(signature); + return sign.verify(signatureB); + } catch (NoSuchAlgorithmException e) { + throw new RuntimeException("当前Java环境不支持SHA256withRSA", e); + } catch (SignatureException e) { + throw new RuntimeException("签名验证过程发生了错误", e); + } catch (InvalidKeyException e) { + throw new RuntimeException("无效的证书", e); + } + } + + } -- Gitblit v1.7.1