增加店铺自配送下单保存逻辑
This commit is contained in:
parent
cbc47d14e4
commit
2040b57fb6
@ -100,7 +100,7 @@ public class LklTkController extends BaseControllerImpl {
|
|||||||
return CommonResult.failed(resp.getSecond());
|
return CommonResult.failed(resp.getSecond());
|
||||||
}
|
}
|
||||||
|
|
||||||
// https://mall.gpxscs.cn/api/mobile/shop/lakala/ledger/applyLedgerMerReceiverBindNotify
|
// https://mall.gpxscs.cn/api/mobile/shop/lakala/tk/registrationMerchantNotify
|
||||||
@ApiOperation(value = "拉卡拉进件申请异步回调通知", notes = "拉卡拉进件申请异步回调通知")
|
@ApiOperation(value = "拉卡拉进件申请异步回调通知", notes = "拉卡拉进件申请异步回调通知")
|
||||||
@RequestMapping(value = "/registrationMerchantNotify", method = {RequestMethod.POST})
|
@RequestMapping(value = "/registrationMerchantNotify", method = {RequestMethod.POST})
|
||||||
public ResponseEntity<JSONObject> registrationMerchantNotify(HttpServletRequest request) {
|
public ResponseEntity<JSONObject> registrationMerchantNotify(HttpServletRequest request) {
|
||||||
@ -112,6 +112,18 @@ public class LklTkController extends BaseControllerImpl {
|
|||||||
return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(resp);
|
return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(resp);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// https://mall.gpxscs.cn/api/mobile/shop/lakala/tk/updateMerchantNotify
|
||||||
|
@ApiOperation(value = "商户改件异步回调通知", notes = "商户改件异步回调通知")
|
||||||
|
@RequestMapping(value = "/updateMerchantNotify", method = {RequestMethod.POST})
|
||||||
|
public ResponseEntity<JSONObject> updateMerchantNotify(HttpServletRequest request) {
|
||||||
|
JSONObject resp = lklTkService.updateMerchantNotify(request);
|
||||||
|
if (resp != null && resp.get("code").equals("200")) {
|
||||||
|
return ResponseEntity.ok(resp);
|
||||||
|
}
|
||||||
|
|
||||||
|
return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(resp);
|
||||||
|
}
|
||||||
|
|
||||||
@ApiOperation(value = "上传文件", notes = "上传文件")
|
@ApiOperation(value = "上传文件", notes = "上传文件")
|
||||||
@RequestMapping(value = "/uploadOcrImg", method = RequestMethod.POST)
|
@RequestMapping(value = "/uploadOcrImg", method = RequestMethod.POST)
|
||||||
public CommonResult uploadOcrImg(@RequestParam(name = "upfile") MultipartFile file,
|
public CommonResult uploadOcrImg(@RequestParam(name = "upfile") MultipartFile file,
|
||||||
|
|||||||
@ -9,6 +9,7 @@
|
|||||||
package com.suisung.mall.shop.lakala.service.impl;
|
package com.suisung.mall.shop.lakala.service.impl;
|
||||||
|
|
||||||
import cn.hutool.core.collection.CollUtil;
|
import cn.hutool.core.collection.CollUtil;
|
||||||
|
import cn.hutool.core.convert.Convert;
|
||||||
import cn.hutool.core.util.ObjectUtil;
|
import cn.hutool.core.util.ObjectUtil;
|
||||||
import cn.hutool.core.util.StrUtil;
|
import cn.hutool.core.util.StrUtil;
|
||||||
import cn.hutool.json.JSONArray;
|
import cn.hutool.json.JSONArray;
|
||||||
@ -69,6 +70,12 @@ public class LklTkServiceImpl {
|
|||||||
@Value("${lakala.tk.notify_pub_key_path}")
|
@Value("${lakala.tk.notify_pub_key_path}")
|
||||||
private String notifyPubKeyPath;
|
private String notifyPubKeyPath;
|
||||||
|
|
||||||
|
@Value("${lakala.tk.api_pub_key_path}")
|
||||||
|
private String apiPubKeyPath;
|
||||||
|
|
||||||
|
@Value("${lakala.tk.api_pri_key_path}")
|
||||||
|
private String apiPriKeyPath;
|
||||||
|
|
||||||
@Value("${lakala.tk.activity_id}")
|
@Value("${lakala.tk.activity_id}")
|
||||||
private Integer activityId;
|
private Integer activityId;
|
||||||
|
|
||||||
@ -353,7 +360,6 @@ public class LklTkServiceImpl {
|
|||||||
urlPath = "/auth/oauth/token";
|
urlPath = "/auth/oauth/token";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
String response = RestTemplateHttpUtil.sendPostFormData(buildLklTkUrl(urlPath), null, formData, String.class);
|
String response = RestTemplateHttpUtil.sendPostFormData(buildLklTkUrl(urlPath), null, formData, String.class);
|
||||||
if (ObjectUtil.isEmpty(response)) {
|
if (ObjectUtil.isEmpty(response)) {
|
||||||
return "";
|
return "";
|
||||||
@ -774,6 +780,325 @@ public class LklTkServiceImpl {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 商户改件异步回调通知
|
||||||
|
*
|
||||||
|
* @param request
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public JSONObject updateMerchantNotify(HttpServletRequest request) {
|
||||||
|
logger.info("开始处理拉卡拉增终异步通知");
|
||||||
|
|
||||||
|
try {
|
||||||
|
// 解密请求参数
|
||||||
|
String requestBody = LakalaUtil.getBody(request);
|
||||||
|
logger.debug("拉卡拉增终异步通知原始参数:{}", requestBody);
|
||||||
|
|
||||||
|
if (StrUtil.isBlank(requestBody)) {
|
||||||
|
logger.warn("拉卡拉增终异步通知参数为空");
|
||||||
|
return new JSONObject().set("code", "400").set("message", "返回参数为空");
|
||||||
|
}
|
||||||
|
|
||||||
|
JSONObject reqBodyJSON = JSONUtil.parseObj(requestBody);
|
||||||
|
if (reqBodyJSON.isEmpty() || reqBodyJSON.get("data") == null) {
|
||||||
|
logger.warn("拉卡拉增终异步通知参数格式有误,无法解析: {}", requestBody);
|
||||||
|
return new JSONObject().set("code", "400").set("message", "参数格式有误,无法解析");
|
||||||
|
}
|
||||||
|
|
||||||
|
String srcData = reqBodyJSON.getStr("data");
|
||||||
|
if (StrUtil.isBlank(srcData)) {
|
||||||
|
logger.warn("拉卡拉增终异步通知关键参数为空值");
|
||||||
|
return new JSONObject().set("code", "400").set("message", "关键参数为空值");
|
||||||
|
}
|
||||||
|
|
||||||
|
// 公钥解密出来的数据
|
||||||
|
logger.debug("开始解密拉卡拉通知数据");
|
||||||
|
String notifyPubKey = LakalaUtil.getResourceFile(notifyPubKeyPath, false, false);
|
||||||
|
String data = LakalaUtil.decryptNotifyData(notifyPubKey, srcData);
|
||||||
|
if (StrUtil.isBlank(data)) {
|
||||||
|
logger.error("拉卡拉增终异步通知数据解密失败");
|
||||||
|
return new JSONObject().set("code", "400").set("message", "数据解密出错!");
|
||||||
|
}
|
||||||
|
|
||||||
|
logger.info("拉卡拉进件异步通知数据解密成功,开始处理业务逻辑");
|
||||||
|
|
||||||
|
// 逻辑处理
|
||||||
|
JSONObject dataJSON = JSONUtil.parseObj(data);
|
||||||
|
String reviewPass = dataJSON.getStr("reviewPass");
|
||||||
|
String merCupNo = dataJSON.getStr("externalCustomerNo"); //拉卡拉外部商户号
|
||||||
|
String merInnerNo = dataJSON.getStr("customerNo"); //拉卡拉内部商户号
|
||||||
|
String termNos = dataJSON.getStr("termNos"); //拉卡拉分配的业务终端号
|
||||||
|
|
||||||
|
logger.debug("解析通知数据完成 - 审核状态: {},外部商户号: {},内部商户号: {},终端号: {}",
|
||||||
|
reviewPass, merCupNo, merInnerNo, termNos);
|
||||||
|
|
||||||
|
// 合并参数校验
|
||||||
|
if (dataJSON.isEmpty() ||
|
||||||
|
StrUtil.isBlank(reviewPass) ||
|
||||||
|
StrUtil.isBlank(merCupNo) ||
|
||||||
|
StrUtil.isBlank(merInnerNo) ||
|
||||||
|
StrUtil.isBlank(termNos)) {
|
||||||
|
logger.warn("拉卡拉进件异步通知参数解析出错,数据: {}", data);
|
||||||
|
return new JSONObject().set("code", "500").set("message", "参数解析出错");
|
||||||
|
}
|
||||||
|
|
||||||
|
// 给商家入驻表增加拉卡拉的商户号和拉卡拉返回的数据
|
||||||
|
logger.debug("开始查询商户入驻信息,内部商户号: {}", merInnerNo);
|
||||||
|
ShopMchEntry shopMchEntry = shopMchEntryService.getShopMerchEntryByMerInnerNo(merInnerNo);
|
||||||
|
if (shopMchEntry == null) {
|
||||||
|
logger.error("拉卡拉增终异步通知:{}内部商户号入驻信息不存在!", merInnerNo);
|
||||||
|
return new JSONObject().put("code", "500").put("message", merInnerNo + "内部商户号入驻信息不存在");
|
||||||
|
}
|
||||||
|
|
||||||
|
Long mchId = shopMchEntry.getId();
|
||||||
|
logger.info("找到商户入驻信息,商户ID: {}", mchId);
|
||||||
|
|
||||||
|
// 校验审核状态: PREPARE:待提交; PASS:通过; UNPASS:未通过; PASSING:审核中;
|
||||||
|
logger.debug("校验审核状态: {}", reviewPass);
|
||||||
|
if (!"PASS".equals(reviewPass)) {
|
||||||
|
String reviewResult = dataJSON.getStr("reviewResult");
|
||||||
|
logger.warn("拉卡拉增终审核未通过,审核状态: {},备注: {}", reviewPass, reviewResult);
|
||||||
|
shopMchEntryService.updateMerchEntryApprovalByMchId(mchId, CommonConstant.MCH_APPR_STA_LKL_NOPASS, "增终失败:" + reviewResult);
|
||||||
|
return new JSONObject().set("code", "FAIL").set("message", "返回审核状态有误");
|
||||||
|
}
|
||||||
|
|
||||||
|
logger.info("拉卡拉增终审核通过,商户ID: {},开始更新商户信息", mchId);
|
||||||
|
|
||||||
|
// RMK 拉卡拉进价提交成功,边处理周边的数据,边等待审核异步通知
|
||||||
|
|
||||||
|
// 更新已进件成功的商户号和设备号
|
||||||
|
logger.debug("开始更新商户拉卡拉审核状态");
|
||||||
|
Boolean success = shopMchEntryService.updateMerchEntryLklAuditStatusByLklMerCupNo(
|
||||||
|
merInnerNo, merCupNo, termNos, CommonConstant.Enable, null, data);
|
||||||
|
|
||||||
|
if (!Boolean.TRUE.equals(success)) {
|
||||||
|
logger.error("拉卡拉进件审核通过但更新商户号失败,商户ID: {}", mchId);
|
||||||
|
shopMchEntryService.updateMerchEntryApprovalByMchId(mchId, CommonConstant.MCH_APPR_STA_LKL_NOPASS, "进件时更新商户号失败");
|
||||||
|
return new JSONObject().set("code", "500").set("message", "更新商户号失败");
|
||||||
|
}
|
||||||
|
|
||||||
|
logger.info("商户拉卡拉审核状态更新成功,商户ID: {}", mchId);
|
||||||
|
|
||||||
|
shopMchEntryService.updateMerchEntryApprovalByMchId(shopMchEntry.getId(), CommonConstant.MCH_APPR_STA_LKL_PADDING,
|
||||||
|
"进件、申请分账业务、创建分账接收方均已成功,等待拉卡拉审核分账业务请求!");
|
||||||
|
|
||||||
|
//密集操作:进件审核通过之后,要下一步流程操作:申请分账业务、创建分账接收方
|
||||||
|
logger.info("开始执行进件后续操作,商户ID: {},拉卡拉商户号: {}", mchId, merCupNo);
|
||||||
|
registrationMerchantAfterHook(mchId, merCupNo);
|
||||||
|
|
||||||
|
logger.info("拉卡拉进件异步通知处理完成,商户ID: {}", mchId);
|
||||||
|
return new JSONObject().set("code", "200").set("message", "处理成功");
|
||||||
|
|
||||||
|
} catch (Exception e) {
|
||||||
|
logger.error("处理拉卡拉增终异步通知异常", e);
|
||||||
|
return new JSONObject().set("code", "500").set("message", "处理异常:" + e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public JSONObject openMerchantAddTerm(String externalCustomerNo) {
|
||||||
|
logger.debug("开始获取拉卡拉商户信息,externalCustomerNo={}", externalCustomerNo);
|
||||||
|
|
||||||
|
try {
|
||||||
|
// 构造请求参数并加密
|
||||||
|
JSONObject requestParams = new JSONObject();
|
||||||
|
requestParams.set("externalCustomerNo", externalCustomerNo);
|
||||||
|
requestParams.set("bzPos", "WECHAT_PAY");
|
||||||
|
requestParams.set("termNum", 1);
|
||||||
|
|
||||||
|
Long shopId = getLklShopId(externalCustomerNo, null);
|
||||||
|
if (shopId == null) {
|
||||||
|
logger.error("拉卡拉商户ID不存在,externalCustomerNo={}", externalCustomerNo);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
requestParams.set("shopId", shopId);
|
||||||
|
|
||||||
|
JSONObject feeInfoDto = new JSONObject();
|
||||||
|
feeInfoDto.set("topFee", Convert.toDouble(wxFee));
|
||||||
|
feeInfoDto.set("fee", Convert.toDouble(wxFee));
|
||||||
|
feeInfoDto.set("feeType", "WECHAT");
|
||||||
|
|
||||||
|
requestParams.set("fees", feeInfoDto);
|
||||||
|
|
||||||
|
|
||||||
|
String privateKey = LakalaUtil.getResourceFile(apiPriKeyPath, false, false);
|
||||||
|
if (StrUtil.isBlank(privateKey)) {
|
||||||
|
logger.error("获取拉卡拉私钥失败,apiPriKeyPath={}", apiPriKeyPath);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
String encryptedParams = LakalaUtil.encryptByPrivateKey(requestParams.toString(), privateKey);
|
||||||
|
logger.warn("请求参数加密完成");
|
||||||
|
|
||||||
|
// 获取认证信息
|
||||||
|
String authorization = getLklTkAuthorization();
|
||||||
|
if (StrUtil.isBlank(authorization)) {
|
||||||
|
logger.error("获取拉卡拉token失败");
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 构造请求头和请求体
|
||||||
|
JSONObject header = new JSONObject().set("Authorization", authorization);
|
||||||
|
JSONObject requestBody = new JSONObject().set("data", encryptedParams);
|
||||||
|
|
||||||
|
// 发送请求
|
||||||
|
String urlPath = "/htkmerchants/open/merchant/addTerm";
|
||||||
|
JSONObject response = RestTemplateHttpUtil.sendLklPost(
|
||||||
|
buildLklTkUrl(urlPath), header, requestBody, JSONObject.class);
|
||||||
|
|
||||||
|
// 检查响应结果
|
||||||
|
if (response == null || !"000000".equals(response.getStr("code")) || response.get("data") == null) {
|
||||||
|
logger.error("拉卡拉商户信息获取失败,response={}", response);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 解密响应数据
|
||||||
|
String publicKey = LakalaUtil.getResourceFile(apiPubKeyPath, false, false);
|
||||||
|
if (StrUtil.isBlank(publicKey)) {
|
||||||
|
logger.error("获取拉卡拉公钥失败,apiPubKeyPath={}", apiPubKeyPath);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
String responseData = LakalaUtil.decryptByPublicKey(response.getStr("data"), publicKey);
|
||||||
|
logger.warn("响应数据解密完成");
|
||||||
|
|
||||||
|
return JSONUtil.parseObj(responseData);
|
||||||
|
|
||||||
|
} catch (Exception e) {
|
||||||
|
logger.error("获取拉卡拉商户信息异常,externalCustomerNo={}", externalCustomerNo, e);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 商家进件成功,拉卡拉商户号获取商户信息(需加密)
|
||||||
|
*
|
||||||
|
* @param externalCustomerNo 外部商户号(优先使用)
|
||||||
|
* @param customerNo 内部商户号(备选)
|
||||||
|
* @return 商户信息JSONObject,获取失败返回null
|
||||||
|
*/
|
||||||
|
public JSONObject openMerchantInfo(String externalCustomerNo, String customerNo) {
|
||||||
|
logger.debug("开始获取拉卡拉商户信息,externalCustomerNo={}, customerNo={}", externalCustomerNo, customerNo);
|
||||||
|
|
||||||
|
try {
|
||||||
|
// 构造请求参数并加密(至少需要一个参数)
|
||||||
|
JSONObject requestParams = new JSONObject();
|
||||||
|
if (StrUtil.isNotBlank(externalCustomerNo)) {
|
||||||
|
requestParams.set("externalCustomerNo", externalCustomerNo);
|
||||||
|
}
|
||||||
|
if (StrUtil.isNotBlank(customerNo)) {
|
||||||
|
requestParams.set("customerNo", customerNo);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 检查参数是否有效
|
||||||
|
if (requestParams.isEmpty()) {
|
||||||
|
logger.warn("拉卡拉商户信息查询参数为空");
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
String privateKey = LakalaUtil.getResourceFile(apiPriKeyPath, false, false);
|
||||||
|
if (StrUtil.isBlank(privateKey)) {
|
||||||
|
logger.error("获取拉卡拉私钥失败,apiPriKeyPath={}", apiPriKeyPath);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
String encryptedParams = LakalaUtil.encryptByPrivateKey(requestParams.toString(), privateKey);
|
||||||
|
logger.debug("请求参数加密完成");
|
||||||
|
|
||||||
|
// 获取认证信息
|
||||||
|
String authorization = getLklTkAuthorization();
|
||||||
|
if (StrUtil.isBlank(authorization)) {
|
||||||
|
logger.error("获取拉卡拉token失败");
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 构造请求头和请求体
|
||||||
|
JSONObject header = new JSONObject().set("Authorization", authorization);
|
||||||
|
JSONObject requestBody = new JSONObject().set("data", encryptedParams);
|
||||||
|
|
||||||
|
// 发送请求
|
||||||
|
String urlPath = "/htkmerchants/open/merchant/info";
|
||||||
|
JSONObject response = RestTemplateHttpUtil.sendLklPost(
|
||||||
|
buildLklTkUrl(urlPath), header, requestBody, JSONObject.class);
|
||||||
|
|
||||||
|
// 检查响应结果
|
||||||
|
if (response == null || !"000000".equals(response.getStr("code")) || response.get("data") == null) {
|
||||||
|
logger.warn("拉卡拉商户信息获取失败,response={}", response);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 解密响应数据
|
||||||
|
String publicKey = LakalaUtil.getResourceFile(apiPubKeyPath, false, false);
|
||||||
|
if (StrUtil.isBlank(publicKey)) {
|
||||||
|
logger.error("获取拉卡拉公钥失败,apiPubKeyPath={}", apiPubKeyPath);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
String responseData = LakalaUtil.decryptByPublicKey(response.getStr("data"), publicKey);
|
||||||
|
logger.debug("响应数据解密完成");
|
||||||
|
|
||||||
|
return JSONUtil.parseObj(responseData);
|
||||||
|
|
||||||
|
} catch (Exception e) {
|
||||||
|
logger.error("获取拉卡拉商户信息异常,externalCustomerNo={}, customerNo={}", externalCustomerNo, customerNo, e);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取拉卡拉商户的 shopId
|
||||||
|
*
|
||||||
|
* @param externalCustomerNo 外部商户号(优先使用)
|
||||||
|
* @param customerNo 内部商户号(备选)
|
||||||
|
* @return 拉卡拉商户的shopId,获取失败返回null
|
||||||
|
*/
|
||||||
|
private Long getLklShopId(String externalCustomerNo, String customerNo) {
|
||||||
|
logger.debug("开始获取拉卡拉商户shopId,externalCustomerNo={}, customerNo={}", externalCustomerNo, customerNo);
|
||||||
|
|
||||||
|
try {
|
||||||
|
JSONObject response = openMerchantInfo(externalCustomerNo, customerNo);
|
||||||
|
if (response == null) {
|
||||||
|
logger.warn("获取拉卡拉商户信息失败,externalCustomerNo={}, customerNo={}", externalCustomerNo, customerNo);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 检查响应中的code字段是否表示成功
|
||||||
|
if (!"000000".equals(response.getStr("code"))) {
|
||||||
|
logger.warn("拉卡拉商户信息获取失败,code={},response={}", response.getStr("code"), response);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 检查shopInfoList是否存在且不为空
|
||||||
|
JSONArray shopInfoList = response.getJSONArray("shopInfoList");
|
||||||
|
if (CollUtil.isEmpty(shopInfoList)) {
|
||||||
|
logger.warn("拉卡拉商户信息中shopInfoList为空或不存在,response={}", response);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获取第一个shopInfo中的shopId
|
||||||
|
JSONObject firstShopInfo = shopInfoList.getJSONObject(0);
|
||||||
|
if (firstShopInfo == null) {
|
||||||
|
logger.warn("拉卡拉商户信息中第一个shopInfo为空,shopInfoList={}", shopInfoList);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
Long shopId = firstShopInfo.getLong("shopId");
|
||||||
|
if (shopId == null) {
|
||||||
|
logger.warn("拉卡拉商户信息中shopId为空,firstShopInfo={}", firstShopInfo);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
logger.debug("成功获取拉卡拉商户shopId: {}", shopId);
|
||||||
|
return shopId;
|
||||||
|
|
||||||
|
} catch (Exception e) {
|
||||||
|
logger.error("获取拉卡拉商户shopId异常,externalCustomerNo={}, customerNo={}", externalCustomerNo, customerNo, e);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 进件审核通过之后,要下一步流程操作:申请分账业务、创建分账接收方
|
* 进件审核通过之后,要下一步流程操作:申请分账业务、创建分账接收方
|
||||||
*
|
*
|
||||||
|
|||||||
@ -44,6 +44,38 @@ import java.util.regex.Pattern;
|
|||||||
@Slf4j
|
@Slf4j
|
||||||
public class LakalaUtil {
|
public class LakalaUtil {
|
||||||
|
|
||||||
|
public static final String KEY_ALGORITHM = "RSA";
|
||||||
|
/**
|
||||||
|
* RSA最大加密密文大小
|
||||||
|
*/
|
||||||
|
private static final int MAX_ENCRYPT_BLOCK = 117;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* RSA最大解密密文大小
|
||||||
|
*/
|
||||||
|
private static final int MAX_DECRYPT_BLOCK = 128;
|
||||||
|
|
||||||
|
|
||||||
|
public static void main(String[] args) {
|
||||||
|
try {
|
||||||
|
String publicK = "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCp5aV3ZiXG2R8Yd8Nxocv+cF7VAUHBc0TF4MNne7mI8wM2yEP2QgI+rK1qDf6G7ZFPhutpIHKQchpolbSuC0vgaHpSjO9OUs1fpnK/JjZq9o8DatUsA0n4Fccec9NBbV5dy5yrwro7xmDpsevp1/IeiIssi1+iD+nBWqqVFx7GVQIDAQAB";
|
||||||
|
String privateK = "MIICdgIBADANBgkqhkiG9w0BAQEFAASCAmAwggJcAgEAAoGBAKnlpXdmJcbZHxh3w3Ghy/5wXtUBQcFzRMXgw2d7uYjzAzbIQ/ZCAj6srWoN/obtkU+G62kgcpByGmiVtK4LS+BoelKM705SzV+mcr8mNmr2jwNq1SwDSfgVxx5z00FtXl3LnKvCujvGYOmx6+nX8h6IiyyLX6IP6cFaqpUXHsZVAgMBAAECgYA4NpeM7etJ48T6H4Y3LsWEJkH6UDQlgbIblsaQkstMmLtTgOebrzN28UNfd8njcu9FVOrHGclOKbK7L+1cOLiduWsZKc/c/gAy9wAR4EhoLvlerH9EEPiPWFxdEDbMxPqlkpqLOo+PxHrhTn4vU4CaPdJtL2ujKn7nmsUdUDWo8QJBANS1TlM6nhPt2XlzN5kGfsJ4kBYNjuLXNA2YdNuC2ttYvEXHJ9T70FN/GnRBBIZu47uHH3Ie5nfep+qMk6a8RP8CQQDMecIyI0z1kVt+tOfWKw2ZFLsi74708qTaeR4W1ABtkngj1+bxoWWXr3KqhjqJkWxnhioSfXqu7CScNzjdM1CrAkAQd+ESjI1EmbumrYb2cAxMXi05p98SLPs4uj8B58WuCda5yEuLL9vXOxX/PjFtfxRepn2GxmGtki2J+UxNMnJdAkAFoORjlO0tZU7rcfdfwdeh+xwbnhSFUZiQGv1lC3jnizybX/oPdK3jOwUhBIjf+IzPXLYTxDh4UC/BzRNXo235AkEAhgYBk6H7RU2iIuvwz1c6CtE1gJ8DvEp1F0KOMWMFB0KCpDXUToix0dlMz962FozYENi4X4zYQo6nFwlXeS3Pfw==";
|
||||||
|
byte[] privateKey = Base64.decodeBase64(privateK);
|
||||||
|
byte[] publicKey = Base64.decodeBase64(publicK);
|
||||||
|
|
||||||
|
|
||||||
|
String aaa = "中文怎么样";
|
||||||
|
String bytes = encryptByPrivateKey(aaa, privateK);
|
||||||
|
|
||||||
|
System.out.println(bytes);
|
||||||
|
String bytes1 = decryptByPublicKey(bytes, publicK);
|
||||||
|
System.out.println("result:" + bytes1);
|
||||||
|
|
||||||
|
} catch (Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 初始化 拉卡拉 SDK(全局只需设置一次)
|
* 初始化 拉卡拉 SDK(全局只需设置一次)
|
||||||
*
|
*
|
||||||
@ -496,6 +528,109 @@ public class LakalaUtil {
|
|||||||
return Pair.of(true, requestBody);
|
return Pair.of(true, requestBody);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 拉卡拉拓客 第三方接口 加密
|
||||||
|
*
|
||||||
|
* @param data 待加密的数据(明文字符串)
|
||||||
|
* @param priKey Base64编码的私钥字符串
|
||||||
|
* @return Base64编码的加密数据
|
||||||
|
*/
|
||||||
|
public static String encryptByPrivateKey(String data, String priKey) {
|
||||||
|
log.debug("开始使用私钥进行数据加密,数据长度: {}", data.length());
|
||||||
|
|
||||||
|
try {
|
||||||
|
// 将Base64编码的私钥转换为字节数组
|
||||||
|
byte[] keyBytes = Base64.decodeBase64(priKey);
|
||||||
|
// 将明文数据转换为字节数组
|
||||||
|
byte[] dataBytes = data.getBytes(StandardCharsets.UTF_8);
|
||||||
|
|
||||||
|
PKCS8EncodedKeySpec pkcs8EncodedKeySpec = new PKCS8EncodedKeySpec(keyBytes);
|
||||||
|
KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
|
||||||
|
PrivateKey privateKey = keyFactory.generatePrivate(pkcs8EncodedKeySpec);
|
||||||
|
Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());
|
||||||
|
cipher.init(Cipher.ENCRYPT_MODE, privateKey);
|
||||||
|
|
||||||
|
int inputLen = dataBytes.length;
|
||||||
|
ByteArrayOutputStream out = new ByteArrayOutputStream();
|
||||||
|
int offSet = 0;
|
||||||
|
byte[] cache;
|
||||||
|
int i = 0;
|
||||||
|
|
||||||
|
// 对数据分段加密
|
||||||
|
while (inputLen - offSet > 0) {
|
||||||
|
if (inputLen - offSet > MAX_ENCRYPT_BLOCK) {
|
||||||
|
cache = cipher.doFinal(dataBytes, offSet, MAX_ENCRYPT_BLOCK);
|
||||||
|
} else {
|
||||||
|
cache = cipher.doFinal(dataBytes, offSet, inputLen - offSet);
|
||||||
|
}
|
||||||
|
out.write(cache, 0, cache.length);
|
||||||
|
i++;
|
||||||
|
offSet = i * MAX_ENCRYPT_BLOCK;
|
||||||
|
}
|
||||||
|
|
||||||
|
byte[] encryptedData = out.toByteArray();
|
||||||
|
// 将加密后的字节数组转换为Base64编码字符串
|
||||||
|
String result = Base64.encodeBase64String(encryptedData);
|
||||||
|
log.debug("数据加密完成,加密后数据长度: {}", result.length());
|
||||||
|
return result;
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("使用私钥加密数据时发生异常", e);
|
||||||
|
throw new RuntimeException("私钥加密失败", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 拉卡拉拓客 第三方接口 解密
|
||||||
|
*
|
||||||
|
* @param data 待解密的数据(Base64编码的加密字符串)
|
||||||
|
* @param pubKey Base64编码的公钥字符串
|
||||||
|
* @return 解密后的明文数据
|
||||||
|
*/
|
||||||
|
public static String decryptByPublicKey(String data, String pubKey) {
|
||||||
|
log.debug("开始使用公钥进行数据解密,数据长度: {}", data.length());
|
||||||
|
|
||||||
|
try {
|
||||||
|
// 将Base64编码的公钥和数据转换为字节数组
|
||||||
|
byte[] keyBytes = Base64.decodeBase64(pubKey);
|
||||||
|
byte[] dataBytes = Base64.decodeBase64(data);
|
||||||
|
|
||||||
|
X509EncodedKeySpec x509EncodedKeySpec = new X509EncodedKeySpec(keyBytes);
|
||||||
|
KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
|
||||||
|
PublicKey publicKey = keyFactory.generatePublic(x509EncodedKeySpec);
|
||||||
|
|
||||||
|
Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());
|
||||||
|
cipher.init(Cipher.DECRYPT_MODE, publicKey);
|
||||||
|
|
||||||
|
int inputLen = dataBytes.length;
|
||||||
|
ByteArrayOutputStream out = new ByteArrayOutputStream();
|
||||||
|
int offSet = 0;
|
||||||
|
byte[] cache;
|
||||||
|
int i = 0;
|
||||||
|
|
||||||
|
// 对数据分段解密
|
||||||
|
while (inputLen - offSet > 0) {
|
||||||
|
if (inputLen - offSet > MAX_DECRYPT_BLOCK) {
|
||||||
|
cache = cipher.doFinal(dataBytes, offSet, MAX_DECRYPT_BLOCK);
|
||||||
|
} else {
|
||||||
|
cache = cipher.doFinal(dataBytes, offSet, inputLen - offSet);
|
||||||
|
}
|
||||||
|
out.write(cache, 0, cache.length);
|
||||||
|
i++;
|
||||||
|
offSet = i * MAX_DECRYPT_BLOCK;
|
||||||
|
}
|
||||||
|
|
||||||
|
byte[] decryptedData = out.toByteArray();
|
||||||
|
// 将解密后的字节数组转换为明文字符串
|
||||||
|
String result = new String(decryptedData, StandardCharsets.UTF_8);
|
||||||
|
log.debug("数据解密完成,解密后数据长度: {}", result.length());
|
||||||
|
return result;
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("使用公钥解密数据时发生异常", e);
|
||||||
|
throw new RuntimeException("公钥解密失败", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 构建拉卡拉接口公共参数
|
* 构建拉卡拉接口公共参数
|
||||||
* <p>
|
* <p>
|
||||||
|
|||||||
@ -1422,6 +1422,7 @@ public class ShopOrderBaseServiceImpl extends BaseServiceImpl<ShopOrderBaseMappe
|
|||||||
Map checkoutRow = new HashMap();
|
Map checkoutRow = new HashMap();
|
||||||
// 配送方式:5-门店自提;10-普通快递;16-同城配送;
|
// 配送方式:5-门店自提;10-普通快递;16-同城配送;
|
||||||
Integer deliveryTypeId = getParameter("delivery_type_id", StateCode.DELIVERY_TYPE_SAME_CITY);
|
Integer deliveryTypeId = getParameter("delivery_type_id", StateCode.DELIVERY_TYPE_SAME_CITY);
|
||||||
|
|
||||||
logger.debug("提交订单时,配送方式 delivery_type_id:{}", deliveryTypeId);
|
logger.debug("提交订单时,配送方式 delivery_type_id:{}", deliveryTypeId);
|
||||||
|
|
||||||
if (getParameter("checkout_row") == null) {
|
if (getParameter("checkout_row") == null) {
|
||||||
@ -1488,7 +1489,8 @@ public class ShopOrderBaseServiceImpl extends BaseServiceImpl<ShopOrderBaseMappe
|
|||||||
}
|
}
|
||||||
|
|
||||||
cartRow.put("user_id", userId);
|
cartRow.put("user_id", userId);
|
||||||
cartRow.put("store_id", productRow.getStore_id());
|
Integer storeId = productRow.getStore_id();
|
||||||
|
cartRow.put("store_id", storeId);
|
||||||
cartRow.put("item_id", itemId);
|
cartRow.put("item_id", itemId);
|
||||||
cartRow.put("cart_quantity", cartQuantity);
|
cartRow.put("cart_quantity", cartQuantity);
|
||||||
cartRow.put("single_activity", shopUserCartService.ifSingleActivity());
|
cartRow.put("single_activity", shopUserCartService.ifSingleActivity());
|
||||||
@ -6342,7 +6344,7 @@ public class ShopOrderBaseServiceImpl extends BaseServiceImpl<ShopOrderBaseMappe
|
|||||||
if (address_row == null) {
|
if (address_row == null) {
|
||||||
// 默认配送地址
|
// 默认配送地址
|
||||||
QueryWrapper<ShopUserDeliveryAddress> addressQueryWrapper = new QueryWrapper<>();
|
QueryWrapper<ShopUserDeliveryAddress> addressQueryWrapper = new QueryWrapper<>();
|
||||||
addressQueryWrapper.eq("ud_is_default", 1).eq("user_id", buyer_user_id);
|
addressQueryWrapper.eq("ud_is_default", CommonConstant.Enable).eq("user_id", buyer_user_id);
|
||||||
ShopUserDeliveryAddress deliveryAddress = userDeliveryAddressService.findOne(addressQueryWrapper);
|
ShopUserDeliveryAddress deliveryAddress = userDeliveryAddressService.findOne(addressQueryWrapper);
|
||||||
cart_data.put("address_row", Convert.toMap(String.class, Object.class, deliveryAddress));
|
cart_data.put("address_row", Convert.toMap(String.class, Object.class, deliveryAddress));
|
||||||
}
|
}
|
||||||
@ -6594,8 +6596,13 @@ public class ShopOrderBaseServiceImpl extends BaseServiceImpl<ShopOrderBaseMappe
|
|||||||
BigDecimal order_money_select_items = Convert.toBigDecimal(store_item.get("order_money_select_items"));
|
BigDecimal order_money_select_items = Convert.toBigDecimal(store_item.get("order_money_select_items"));
|
||||||
BigDecimal freight = Convert.toBigDecimal(store_item.get("freight"));
|
BigDecimal freight = Convert.toBigDecimal(store_item.get("freight"));
|
||||||
|
|
||||||
// TODO 注:配送方式:5-到店自提;10-普通快递;16-同城配送;
|
// TODO 注:配送方式:5-到店自提;10-普通快递;16-同城配送;15-商家自配送
|
||||||
Integer delivery_type_id = Convert.toInt(checkout_row.get("delivery_type_id")); //StateCode.DELIVERY_TYPE_SAME_CITY;
|
Integer delivery_type_id = Convert.toInt(checkout_row.get("delivery_type_id"));
|
||||||
|
|
||||||
|
// 判断这家店是不是自己配送?
|
||||||
|
if (shopStoreInfoService.isDeliverySelf(_store_id)) {
|
||||||
|
delivery_type_id = StateCode.DELIVERY_TYPE_IN_STORE_SERVICE;
|
||||||
|
}
|
||||||
|
|
||||||
// 店铺统一设置的打包费(formatCartRows 方法里计算好的)
|
// 店铺统一设置的打包费(formatCartRows 方法里计算好的)
|
||||||
BigDecimal packingFee = Convert.toBigDecimal(store_item.get("packing_fee"));
|
BigDecimal packingFee = Convert.toBigDecimal(store_item.get("packing_fee"));
|
||||||
|
|||||||
@ -47,4 +47,12 @@ public interface ShopStoreInfoService extends IBaseService<ShopStoreInfo> {
|
|||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
Integer getStoreShippingFeeInner(Integer storeId);
|
Integer getStoreShippingFeeInner(Integer storeId);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取店铺的配送方式是否 自配送
|
||||||
|
*
|
||||||
|
* @param storeId
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
Boolean isDeliverySelf(Integer storeId);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -2,8 +2,10 @@ package com.suisung.mall.shop.store.service.impl;
|
|||||||
|
|
||||||
import cn.hutool.core.convert.Convert;
|
import cn.hutool.core.convert.Convert;
|
||||||
import cn.hutool.core.util.ObjectUtil;
|
import cn.hutool.core.util.ObjectUtil;
|
||||||
|
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||||
|
import com.suisung.mall.common.constant.CommonConstant;
|
||||||
import com.suisung.mall.common.feignService.AccountService;
|
import com.suisung.mall.common.feignService.AccountService;
|
||||||
import com.suisung.mall.common.modules.account.AccountUserBase;
|
import com.suisung.mall.common.modules.account.AccountUserBase;
|
||||||
import com.suisung.mall.common.modules.store.ShopStoreAnalytics;
|
import com.suisung.mall.common.modules.store.ShopStoreAnalytics;
|
||||||
@ -160,4 +162,38 @@ public class ShopStoreInfoServiceImpl extends BaseServiceImpl<ShopStoreInfoMappe
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取店铺的配送方式是否自配送
|
||||||
|
*
|
||||||
|
* @param storeId 店铺ID
|
||||||
|
* @return true表示自配送,false表示非自配送或店铺不存在
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public Boolean isDeliverySelf(Integer storeId) {
|
||||||
|
// 参数校验
|
||||||
|
if (storeId == null) {
|
||||||
|
log.warn("店铺ID为空,无法判断配送方式");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
LambdaQueryWrapper<ShopStoreInfo> queryWrapper = new LambdaQueryWrapper<>();
|
||||||
|
queryWrapper.eq(ShopStoreInfo::getStore_id, storeId)
|
||||||
|
.select(ShopStoreInfo::getIs_delivery_self);
|
||||||
|
ShopStoreInfo shopStoreInfo = findOne(queryWrapper);
|
||||||
|
|
||||||
|
// 店铺不存在或配送方式字段为空时返回false
|
||||||
|
if (shopStoreInfo == null || shopStoreInfo.getIs_delivery_self() == null) {
|
||||||
|
log.debug("店铺信息不存在或配送方式未设置,storeId: {}", storeId);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return CommonConstant.Enable.equals(shopStoreInfo.getIs_delivery_self());
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("查询店铺配送方式异常,storeId: {}", storeId, e);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user