修正顺丰退款的问题,全部退款或退部分款必须可用。
This commit is contained in:
parent
52e5f24913
commit
5da423e50b
@ -74,6 +74,8 @@ public class ShopOrderLkl implements Serializable {
|
||||
|
||||
private String lkl_term_no;
|
||||
|
||||
private String wx_transaction_id; // 微信用户交易单号, 确认收货时使用
|
||||
|
||||
private String notify_url;
|
||||
|
||||
private String receive_notify_url;
|
||||
|
||||
@ -473,10 +473,12 @@
|
||||
<includeSystemScope>true</includeSystemScope>
|
||||
</configuration>
|
||||
</plugin>
|
||||
|
||||
<plugin>
|
||||
<groupId>com.spotify</groupId>
|
||||
<artifactId>docker-maven-plugin</artifactId>
|
||||
</plugin>
|
||||
|
||||
<plugin>
|
||||
<artifactId>maven-resources-plugin</artifactId>
|
||||
<version>3.1.0</version>
|
||||
|
||||
@ -569,36 +569,47 @@ public class LakalaApiServiceImpl implements LakalaApiService {
|
||||
/**
|
||||
* 商户分账业务开通申请
|
||||
*
|
||||
* @param merCupNo
|
||||
* @return
|
||||
* <p>向拉卡拉提交商户分账业务开通申请,包括上传分账授权委托书等必要文件。
|
||||
*
|
||||
* @param merCupNo 拉卡拉商户号(银联商户号)
|
||||
* @return Pair对象,第一个元素表示操作是否成功,第二个元素为操作结果信息
|
||||
*/
|
||||
@Override
|
||||
public Pair<Boolean, String> innerApplyLedgerMer(String merCupNo) {
|
||||
log.debug("商户分账业务申请开始");
|
||||
log.info("开始执行商户分账业务申请流程,商户号: {}", merCupNo);
|
||||
|
||||
// 参数校验
|
||||
if (StringUtils.isBlank(merCupNo)) {
|
||||
log.warn("商户分账业务申请失败:商户号不能为空");
|
||||
return Pair.of(false, I18nUtil._("商户号不能为空!"));
|
||||
}
|
||||
|
||||
// 获取商户入驻记录
|
||||
log.debug("开始查询商户入驻信息,商户号: {}", merCupNo);
|
||||
ShopMchEntry shopMchEntry = shopMchEntryService.getShopMerchEntryByMerCupNo(merCupNo);
|
||||
if (shopMchEntry == null) {
|
||||
log.warn("商户分账业务申请失败:商家入驻信息不存在,商户号: {}", merCupNo);
|
||||
return Pair.of(false, I18nUtil._("商家入驻信息不存在!"));
|
||||
}
|
||||
|
||||
// 判断是否已经申请过?
|
||||
log.debug("检查商户是否已申请过分账业务,商户号: {}", merCupNo);
|
||||
LklLedgerMember lklLedgerMember = lklLedgerMemberService.getByMerCupNo(merCupNo);
|
||||
if (lklLedgerMember != null && lklLedgerMember.getAudit_status() == 1) {
|
||||
if (lklLedgerMember != null && Integer.valueOf(1).equals(lklLedgerMember.getAudit_status())) {
|
||||
log.info("商户已申请过分账业务,无需重复申请,商户号: {}", merCupNo);
|
||||
return Pair.of(true, I18nUtil._("商家已经申请过了!"));
|
||||
}
|
||||
|
||||
// 检查更新店铺初始化状态
|
||||
log.debug("检查并更新店铺初始化状态,商户ID: {}", shopMchEntry.getId());
|
||||
shopMchEntryService.checkMchEntryStoreStatus(shopMchEntry.getId(), shopMchEntry);
|
||||
|
||||
// 1. 配置初始化
|
||||
log.debug("初始化拉卡拉SDK");
|
||||
initLKLSDK();
|
||||
|
||||
//2. 装配数据
|
||||
log.debug("装配分账业务申请请求参数");
|
||||
V2MmsOpenApiLedgerApplyLedgerMerRequest req = new V2MmsOpenApiLedgerApplyLedgerMerRequest();
|
||||
req.setVersion("2.0");
|
||||
req.setOrderNo(StringUtils.genLklOrderNo(8));// 14位年月日时(24小时制)分秒+8位的随机数
|
||||
@ -624,26 +635,32 @@ public class LakalaApiServiceImpl implements LakalaApiService {
|
||||
String retUrl = domain + "/mobile/shop/lakala/ledger/applyLedgerMerNotify";
|
||||
req.setRetUrl(retUrl);
|
||||
|
||||
log.debug("商户分账业务申请请求参数:{}", JSONUtil.toJsonStr(req));
|
||||
log.debug("商户分账业务申请请求参数: {}", JSONUtil.toJsonStr(req));
|
||||
|
||||
try {
|
||||
//3. 发送请求
|
||||
log.info("开始向拉卡拉提交分账业务申请,订单号: {}", req.getOrderNo());
|
||||
String responseStr = LKLSDK.httpPost(req);
|
||||
if (StrUtil.isBlank(responseStr)) {
|
||||
log.error("申请拉卡拉分账业务无返回值,订单号: {}", req.getOrderNo());
|
||||
return Pair.of(false, I18nUtil._("申请拉卡拉分账业务无返回值!"));
|
||||
}
|
||||
|
||||
log.debug("商户分账业务申请响应数据:{}", responseStr);
|
||||
log.debug("商户分账业务申请响应数据: {}", responseStr);
|
||||
|
||||
// 成功返回示例:{'retCode':'000000','retMsg':'申请已受理,请等待审核结果','respData':{'version':'1.0','orderNo':'KFPT20230223181025407788734','orgCode':'1','applyId':681201215598657536}}
|
||||
JSONObject lakalaRespJSON = JSONUtil.parseObj(responseStr);
|
||||
if (lakalaRespJSON == null) {
|
||||
log.error("申请拉卡拉分账业务返回值异常,订单号: {}", req.getOrderNo());
|
||||
return Pair.of(false, I18nUtil._("申请拉卡拉分账业务返回值异常!"));
|
||||
}
|
||||
|
||||
Object applyId = lakalaRespJSON.getByPath("respData.applyId");
|
||||
if (!lakalaRespJSON.getStr("retCode").equals(lklSuccessCode) || applyId == null) {
|
||||
return Pair.of(false, lakalaRespJSON.getStr("retMsg"));
|
||||
if (!lklSuccessCode.equals(lakalaRespJSON.getStr("retCode")) || applyId == null) {
|
||||
String retMsg = lakalaRespJSON.getStr("retMsg");
|
||||
log.warn("拉卡拉分账业务申请被拒绝,订单号: {},返回码: {},返回信息: {}",
|
||||
req.getOrderNo(), lakalaRespJSON.getStr("retCode"), retMsg);
|
||||
return Pair.of(false, retMsg);
|
||||
}
|
||||
|
||||
JSONObject paramsJSON = new JSONObject();
|
||||
@ -670,15 +687,21 @@ public class LakalaApiServiceImpl implements LakalaApiService {
|
||||
|
||||
// 新增数据
|
||||
// 将 JSON 对象的键名转换为下划线命名
|
||||
log.debug("准备保存分账业务申请记录");
|
||||
LklLedgerMember lklLedgerMemberNew = JSONUtil.toBean(StringUtils.convertCamelToSnake(paramsJSON.toString()), LklLedgerMember.class);
|
||||
if (!lklLedgerMemberService.addOrUpdateByMerCupNo(lklLedgerMemberNew)) {
|
||||
log.error("新增或更改拉卡拉分账业务申请信息失败,订单号: {}", req.getOrderNo());
|
||||
return Pair.of(false, I18nUtil._("新增或更改拉卡拉分账业务申请信息失败!"));
|
||||
}
|
||||
|
||||
log.info("商户分账业务申请提交成功,等待审核,订单号: {},申请ID: {}", req.getOrderNo(), applyId);
|
||||
return Pair.of(true, I18nUtil._("商户申请拉卡拉分账业务,提交成功,待审核中!"));
|
||||
} catch (SDKException e) {
|
||||
log.error("申请拉卡拉分账业务出错:", e);
|
||||
log.error("申请拉卡拉分账业务出错,订单号: {}", req.getOrderNo(), e);
|
||||
return Pair.of(false, I18nUtil._("申请拉卡拉分账业务出错!"));
|
||||
} catch (Exception e) {
|
||||
log.error("申请拉卡拉分账业务出现未预期异常,订单号: {}", req.getOrderNo(), e);
|
||||
return Pair.of(false, I18nUtil._("申请拉卡拉分账业务出现未预期异常!"));
|
||||
}
|
||||
}
|
||||
|
||||
@ -1359,49 +1382,56 @@ public class LakalaApiServiceImpl implements LakalaApiService {
|
||||
|
||||
/**
|
||||
* 内部调用分账关系绑定申请(优化版)
|
||||
* 参考:https://o.lakala.com/#/home/document/detail?id=386
|
||||
*
|
||||
* @param paramsJSON 包含绑定参数的JSON对象 {merCupNo}
|
||||
* @return 操作结果及提示信息
|
||||
*/
|
||||
/**
|
||||
* 内部调用分账关系绑定申请(优化版)
|
||||
* 参考:https://o.lakala.com/#/home/document/detail?id=386
|
||||
* <p>参考:https://o.lakala.com/#/home/document/detail?id=386
|
||||
* 为商户绑定分账接收方,包括平台方和代理商(如有)。
|
||||
*
|
||||
* @param paramsJSON 包含绑定参数的JSON对象 {merCupNo}
|
||||
* @return 操作结果及提示信息
|
||||
* @return Pair对象,第一个元素表示操作是否成功,第二个元素为操作结果信息
|
||||
*/
|
||||
public Pair<Boolean, String> innerApplyLedgerMerReceiverBind(JSONObject paramsJSON) {
|
||||
log.debug("商家绑定分账接收方申请开始:{}", paramsJSON);
|
||||
log.info("开始执行商家绑定分账接收方申请");
|
||||
|
||||
// 1. 参数校验(提前失败)
|
||||
if (paramsJSON == null) {
|
||||
log.warn("商家绑定分账接收方申请失败:绑定参数为空");
|
||||
return Pair.of(false, I18nUtil._("绑定参数为空"));
|
||||
}
|
||||
|
||||
String merCupNo = paramsJSON.getStr("merCupNo");
|
||||
if (StrUtil.isBlank(merCupNo)) {
|
||||
log.warn("商家绑定分账接收方申请失败:商户号(merCupNo)为空");
|
||||
return Pair.of(false, I18nUtil._("商户号(merCupNo)为空"));
|
||||
}
|
||||
|
||||
log.debug("商家绑定分账接收方申请参数:{}", paramsJSON);
|
||||
|
||||
// 2. 基础数据查询(提前失败)
|
||||
log.debug("开始查询商户入驻信息,商户号: {}", merCupNo);
|
||||
ShopMchEntry shopMchEntry = shopMchEntryService.getShopMerchEntryByMerCupNo(merCupNo);
|
||||
if (shopMchEntry == null) {
|
||||
log.warn("商家绑定分账接收方申请失败:商户入驻记录不存在,商户号: {}", merCupNo);
|
||||
return Pair.of(false, I18nUtil._("商户入驻记录不存在"));
|
||||
}
|
||||
|
||||
// 进件记录
|
||||
log.debug("开始查询分账业务申请记录,商户号: {}", merCupNo);
|
||||
LklLedgerMember lklLedgerMember = lklLedgerMemberService.getByMerCupNo(merCupNo);
|
||||
if (lklLedgerMember == null || !CommonConstant.Enable.equals(lklLedgerMember.getAudit_status())) {
|
||||
log.warn("商家绑定分账接收方申请失败:商家尚未申请分账业务或审核未通过,商户号: {}", merCupNo);
|
||||
return Pair.of(false, I18nUtil._("商家尚未申请分账业务"));
|
||||
}
|
||||
|
||||
// 分账接收方列表
|
||||
log.debug("开始查询分账接收方列表");
|
||||
List<LklLedgerReceiver> receiverList = lklLedgerReceiverService.selectPlatformAnDistributorList();
|
||||
if (CollectionUtil.isEmpty(receiverList)) {
|
||||
log.warn("商家绑定分账接收方申请失败:分账接收方信息为空");
|
||||
return Pair.of(false, I18nUtil._("分账接收方信息为空"));
|
||||
}
|
||||
|
||||
log.info("获取到 {} 个分账接收方,开始处理绑定申请", receiverList.size());
|
||||
|
||||
// 3. 公共参数准备(避免循环内重复计算)
|
||||
// 正式上线的时候,调整 api 地址
|
||||
String domain = projectDomain;
|
||||
@ -1418,19 +1448,26 @@ public class LakalaApiServiceImpl implements LakalaApiService {
|
||||
int totalCount = receiverList.size();
|
||||
|
||||
// 5. 初始化SDK(建议移至类初始化或统一配置)
|
||||
log.debug("初始化拉卡拉SDK");
|
||||
initLKLSDK();
|
||||
|
||||
// 4. 循环处理接收方绑定
|
||||
for (LklLedgerReceiver receiver : receiverList) {
|
||||
try {
|
||||
log.debug("开始处理分账接收方绑定,接收方编号: {}", receiver.getReceiver_no());
|
||||
|
||||
// 跳过已存在的绑定关系
|
||||
if (lklLedgerMerReceiverBindService.getByCondition(merCupNo, receiver.getReceiver_no()) != null) {
|
||||
log.warn("分账绑定关系已存在:merCupNo={}, receiverNo={}", merCupNo, receiver.getReceiver_no());
|
||||
LklLedgerMerReceiverBind existingBind = lklLedgerMerReceiverBindService.getByCondition(merCupNo, receiver.getReceiver_no());
|
||||
if (existingBind != null) {
|
||||
log.info("分账绑定关系已存在,跳过处理:merCupNo={}, receiverNo={}", merCupNo, receiver.getReceiver_no());
|
||||
successCount++; // 已存在的绑定视为成功
|
||||
continue;
|
||||
}
|
||||
|
||||
// 6. 构建请求参数
|
||||
String orderNo = StringUtils.genLklOrderNo(8);
|
||||
log.debug("生成订单号: {}", orderNo);
|
||||
|
||||
V2MmsOpenApiLedgerApplyBindRequest request = new V2MmsOpenApiLedgerApplyBindRequest();
|
||||
request.setOrderNo(orderNo);
|
||||
request.setOrgCode(orgCode);
|
||||
@ -1443,17 +1480,23 @@ public class LakalaApiServiceImpl implements LakalaApiService {
|
||||
request.setRetUrl(retUrl);
|
||||
|
||||
// 7. 记录请求参数
|
||||
log.debug("商家绑定分账接收方参数:{}", JSONUtil.toJsonStr(request));
|
||||
log.debug("商家绑定分账接收方请求参数:{}", JSONUtil.toJsonStr(request));
|
||||
|
||||
// 8. 发送请求并处理响应
|
||||
log.info("向拉卡拉提交分账接收方绑定申请,订单号: {},商户号: {},接收方: {}",
|
||||
orderNo, merCupNo, receiver.getReceiver_no());
|
||||
String responseStr = LKLSDK.httpPost(request);
|
||||
JSONObject respJson = JSONUtil.parseObj(responseStr);
|
||||
|
||||
if (respJson == null || !lklSuccessCode.equals(respJson.getStr("retCode"))) {
|
||||
log.error("绑定接收方拉卡拉响应失败:{}", respJson != null ? respJson.getStr("retMsg") : "无响应数据");
|
||||
String errorMsg = respJson != null ? respJson.getStr("retMsg") : "无响应数据";
|
||||
log.error("绑定接收方拉卡拉响应失败,订单号: {},错误信息: {}", orderNo, errorMsg);
|
||||
continue; // 单个失败不影响其他接收方处理
|
||||
}
|
||||
|
||||
log.info("拉卡拉分账接收方绑定申请提交成功,订单号: {},申请ID: {}",
|
||||
orderNo, respJson.getByPath("respData.applyId"));
|
||||
|
||||
// 9. 更新参数并保存记录
|
||||
paramsJSON.set("orderNo", orderNo);
|
||||
paramsJSON.set("apply_id", respJson.getByPath("respData.applyId"));
|
||||
@ -1468,20 +1511,25 @@ public class LakalaApiServiceImpl implements LakalaApiService {
|
||||
String snakeJson = StringUtils.convertCamelToSnake(paramsJSON.toString());
|
||||
LklLedgerMerReceiverBind bindRecord = JSONUtil.toBean(snakeJson, LklLedgerMerReceiverBind.class);
|
||||
|
||||
log.debug("准备保存分账绑定记录");
|
||||
if (lklLedgerMerReceiverBindService.addOrUpdateByMerCupNoReceiverNo(bindRecord)) {
|
||||
successCount++;
|
||||
log.info("分账绑定记录保存成功,订单号: {}", orderNo);
|
||||
} else {
|
||||
log.warn("绑定记录保存失败:merCupNo={}, receiverNo={}", merCupNo, receiver.getReceiver_no());
|
||||
log.warn("分账绑定记录保存失败,订单号: {},商户号: {},接收方: {}",
|
||||
orderNo, merCupNo, receiver.getReceiver_no());
|
||||
}
|
||||
|
||||
} catch (Exception e) {
|
||||
log.error("处理分账绑定失败:merCupNo={}, receiverNo={}", merCupNo, receiver.getReceiver_no(), e);
|
||||
log.error("处理分账绑定异常,商户号: {},接收方: {}", merCupNo, receiver.getReceiver_no(), e);
|
||||
// 单个接收方处理失败,继续处理其他接收方
|
||||
}
|
||||
}
|
||||
|
||||
// 10. 返回结果
|
||||
log.info("分账接收方绑定处理完成,成功: {},总数: {}", successCount, totalCount);
|
||||
if (successCount == 0) {
|
||||
log.error("商家绑定分账接收方全部失败");
|
||||
if (lklLedgerMember != null) {
|
||||
shopMchEntryService.updateMerchEntryApprovalByMchId(
|
||||
lklLedgerMember.getMch_id(), CommonConstant.MCH_APPR_STA_NOPASS, "商家绑定分账接收方失败"
|
||||
@ -1489,9 +1537,13 @@ public class LakalaApiServiceImpl implements LakalaApiService {
|
||||
}
|
||||
return Pair.of(false, "商家绑定分账接收方失败");
|
||||
} else if (successCount < totalCount) {
|
||||
return Pair.of(true, "商家绑定分账接收方,部分提交成功(" + successCount + "/" + totalCount + "),待审核通知");
|
||||
String message = "商家绑定分账接收方,部分提交成功(" + successCount + "/" + totalCount + "),待审核通知";
|
||||
log.info(message);
|
||||
return Pair.of(true, message);
|
||||
} else {
|
||||
return Pair.of(true, "商家绑定分账接收方,全部提交成功,待审核通知");
|
||||
String message = "商家绑定分账接收方,全部提交成功,待审核通知";
|
||||
log.info(message);
|
||||
return Pair.of(true, message);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -318,44 +318,54 @@ public class LklTkServiceImpl {
|
||||
}
|
||||
|
||||
/**
|
||||
* (重要) 请求拉卡拉进件,
|
||||
* TODO 已经进件过了,一般不涉及更改企业(小微)的信息,可以不要重新进件了
|
||||
* <p>
|
||||
* 参考拉卡拉给的独立文档:2、拓客SAAS商户管理接口(新).docx
|
||||
* (重要) 请求拉卡拉进件
|
||||
*
|
||||
* @param mchId 入驻商家自增Id
|
||||
* @return
|
||||
* <p>此方法用于向拉卡拉提交商户进件申请,包括完整的商户信息和相关附件。
|
||||
* 已经进件过的商户一般不涉及更改企业(小微)的信息,可以不要重新进件。
|
||||
*
|
||||
* <p>参考拉卡拉给的独立文档:2、拓客SAAS商户管理接口(新).docx
|
||||
*
|
||||
* @param mchId 入驻商家自增Id,不能为空
|
||||
* @return Pair对象,第一个元素表示操作是否成功,第二个元素为操作结果信息
|
||||
*/
|
||||
public Pair<Boolean, String> registrationMerchant(Long mchId) {
|
||||
logger.info("开始执行拉卡拉商户进件流程,商户ID: {}", mchId);
|
||||
|
||||
// 参数校验
|
||||
if (ObjectUtil.isEmpty(mchId)) {
|
||||
logger.warn("商户进件失败:入驻商户Id不能为空");
|
||||
return Pair.of(false, "入驻商户Id不能为空");
|
||||
}
|
||||
|
||||
String authorization = getLklTkAuthorization();
|
||||
if (StrUtil.isBlank(authorization)) {
|
||||
logger.error("商户进件失败:获取拉卡拉token失败");
|
||||
return Pair.of(false, "获取拉卡拉token失败");
|
||||
}
|
||||
|
||||
JSONObject header = new JSONObject();
|
||||
header.put("Authorization", getLklTkAuthorization());
|
||||
header.put("Authorization", authorization);
|
||||
|
||||
// 获取商家入驻信息,组成请求参数
|
||||
ShopMchEntry shopMchEntry = shopMchEntryService.shopMerchEntryById(mchId);
|
||||
if (ObjectUtil.isEmpty(shopMchEntry)) {
|
||||
logger.warn("商户进件失败:商家入驻信息不存在,商户ID: {}", mchId);
|
||||
return Pair.of(false, "商家入驻信息不存在");
|
||||
}
|
||||
|
||||
if (!CommonConstant.Enable.equals(shopMchEntry.getHas_ec_signed())
|
||||
|| StrUtil.isBlank(shopMchEntry.getContract_download_url())) {
|
||||
logger.warn("商户进件失败:商家未签署合同,商户ID: {}", mchId);
|
||||
return Pair.of(false, "商家先签署合同,再来进件!");
|
||||
}
|
||||
|
||||
// 判断是否已经进件过?进件过,执行下一步操作(进件异步通知的相关操作)
|
||||
|
||||
//密集操作:进件审核通过之后,要下一步流程操作:申请分账业务、创建分账接收方
|
||||
if (CommonConstant.Enable.equals(shopMchEntry.getHas_apply_mer()) && CheckUtil.isNotEmpty(shopMchEntry.getDistributor_id())
|
||||
// 密集操作:进件审核通过之后,要下一步流程操作:申请分账业务、创建分账接收方
|
||||
if (CommonConstant.Enable.equals(shopMchEntry.getHas_apply_mer())
|
||||
&& CheckUtil.isNotEmpty(shopMchEntry.getDistributor_id())
|
||||
&& StrUtil.isAllNotBlank(shopMchEntry.getLkl_mer_cup_no(), shopMchEntry.getLkl_term_no())) {
|
||||
// 已经进件过了,执行下一步操作
|
||||
logger.info("商户已进件,执行后续操作,商户ID: {}", mchId);
|
||||
registrationMerchantAfterHook(mchId, shopMchEntry.getLkl_mer_cup_no(), shopMchEntry.getDistributor_id());
|
||||
return Pair.of(true, "请勿重复提交,拉卡拉已进件成功了,准备提交分账业务申请!");
|
||||
}
|
||||
@ -475,60 +485,87 @@ public class LklTkServiceImpl {
|
||||
reqJsonBody.put("bizContent", bizContent);
|
||||
|
||||
// 附件文件相关开始
|
||||
logger.debug("开始处理商户附件文件,商户ID: {}", mchId);
|
||||
JSONArray attachments = new JSONArray();
|
||||
if (isQy) {
|
||||
if (Boolean.TRUE.equals(isQy)) {
|
||||
JSONObject SETTLE_ID_CARD_FRONT = updatePhoto(shopMchEntry.getLegal_person_id_images(), "FR_ID_CARD_FRONT", false);
|
||||
if (SETTLE_ID_CARD_FRONT != null) {
|
||||
attachments.put(SETTLE_ID_CARD_FRONT); // 法人身份证正面
|
||||
logger.debug("成功添加法人身份证正面图片");
|
||||
} else {
|
||||
logger.warn("法人身份证正面图片添加失败");
|
||||
}
|
||||
|
||||
JSONObject SETTLE_ID_CARD_BEHIND = updatePhoto(shopMchEntry.getLegal_person_id_images2(), "FR_ID_CARD_BEHIND", false);
|
||||
if (SETTLE_ID_CARD_BEHIND != null) {
|
||||
attachments.put(SETTLE_ID_CARD_BEHIND); // 法人身份证国徽面
|
||||
logger.debug("成功添加法人身份证国徽面图片");
|
||||
} else {
|
||||
logger.warn("法人身份证国徽面图片添加失败");
|
||||
}
|
||||
|
||||
JSONObject BUSINESS_LICENCE = updatePhoto(shopMchEntry.getBiz_license_image(), "BUSINESS_LICENCE", false);
|
||||
if (BUSINESS_LICENCE != null) {
|
||||
attachments.put(BUSINESS_LICENCE); // 营业执照
|
||||
logger.debug("成功添加营业执照图片");
|
||||
} else {
|
||||
logger.warn("营业执照图片添加失败");
|
||||
}
|
||||
|
||||
} else {
|
||||
JSONObject ID_CARD_FRONT = updatePhoto(shopMchEntry.getIndividual_id_images(), "ID_CARD_FRONT", false);
|
||||
if (ID_CARD_FRONT != null) {
|
||||
attachments.put(ID_CARD_FRONT); // 身份证正面
|
||||
logger.debug("成功添加身份证正面图片");
|
||||
} else {
|
||||
logger.warn("身份证正面图片添加失败");
|
||||
}
|
||||
|
||||
JSONObject ID_CARD_BEHIND = updatePhoto(shopMchEntry.getIndividual_id_images2(), "ID_CARD_BEHIND", false);
|
||||
if (ID_CARD_BEHIND != null) {
|
||||
attachments.put(ID_CARD_BEHIND); // 身份证国徽面
|
||||
logger.debug("成功添加身份证国徽面图片");
|
||||
} else {
|
||||
logger.warn("身份证国徽面图片添加失败");
|
||||
}
|
||||
}
|
||||
|
||||
JSONObject SHOP_OUTSIDE_IMG = updatePhoto(shopMchEntry.getFront_facade_image(), "SHOP_OUTSIDE_IMG", false);
|
||||
if (SHOP_OUTSIDE_IMG != null) {
|
||||
attachments.put(SHOP_OUTSIDE_IMG); // 门店门面图片
|
||||
logger.debug("成功添加门店门面图片");
|
||||
} else {
|
||||
logger.warn("门店门面图片添加失败");
|
||||
}
|
||||
|
||||
JSONObject SHOP_INSIDE_IMG = updatePhoto(shopMchEntry.getEnvironment_image(), "SHOP_INSIDE_IMG", false);
|
||||
if (SHOP_INSIDE_IMG != null) {
|
||||
attachments.put(SHOP_INSIDE_IMG); // 门店内部图片
|
||||
logger.debug("成功添加门店内部图片");
|
||||
} else {
|
||||
logger.warn("门店内部图片添加失败");
|
||||
}
|
||||
|
||||
JSONObject BANK_CARD = updatePhoto(shopMchEntry.getBank_image(), "BANK_CARD", false);
|
||||
if (BANK_CARD != null) {
|
||||
attachments.put(BANK_CARD); // 银行卡图片
|
||||
logger.debug("成功添加银行卡图片");
|
||||
} else {
|
||||
logger.warn("银行卡图片添加失败");
|
||||
}
|
||||
reqJsonBody.put("attchments", attachments);
|
||||
logger.debug("商户附件文件处理完成,共添加 {} 个附件", attachments.size());
|
||||
// 附件文件相关结束
|
||||
|
||||
String urlPath = "/sit/htkregistration/merchant";
|
||||
if (isLklProd) {
|
||||
if (Boolean.TRUE.equals(isLklProd)) {
|
||||
// 生产环境启用
|
||||
urlPath = "/registration/merchant";
|
||||
}
|
||||
|
||||
try {
|
||||
logger.info("进件请求参数:{}", JSONUtil.toJsonStr(reqJsonBody));
|
||||
logger.info("准备提交拉卡拉进件请求,商户ID: {}", mchId);
|
||||
logger.debug("进件请求参数:{}", JSONUtil.toJsonStr(reqJsonBody));
|
||||
|
||||
JSONObject response = RestTemplateHttpUtil.sendLklPost(buildLklTkUrl(urlPath), header, reqJsonBody, JSONObject.class);
|
||||
logger.debug("拉卡拉进件响应参数:{}", response);
|
||||
@ -538,6 +575,7 @@ public class LklTkServiceImpl {
|
||||
|| !"000000".equals(response.getStr("retCode"))) {
|
||||
|
||||
String errMsg = response.getStr("retMsg") == null ? "提交拉卡拉进件,出现未知错误" : response.getStr("retMsg");
|
||||
logger.error("拉卡拉进件失败,商户ID: {},错误信息: {}", mchId, errMsg);
|
||||
shopMchEntryService.updateMerchEntryApprovalByMchId(shopMchEntry.getId(), CommonConstant.MCH_APPR_STA_LKL_NOPASS, "提交拉卡拉进件失败:" + errMsg);
|
||||
return Pair.of(false, "提交拉卡拉进件失败:" + errMsg);
|
||||
|
||||
@ -546,19 +584,24 @@ public class LklTkServiceImpl {
|
||||
// {"merchantNo": "100132349","status": "WAIT_AUDI","state": "1"}
|
||||
JSONObject rawData = response.getJSONObject("rawData"); // 进件这个接口比较特殊,不按照常规返回数据
|
||||
String lklMerInnerNo = rawData.getStr("merchantNo"); //拉卡拉内部商户号
|
||||
|
||||
logger.info("拉卡拉进件成功,商户ID: {},拉卡拉商户号: {}", mchId, lklMerInnerNo);
|
||||
|
||||
// 表中的内部外部商户号暂时都传同一个内部商户号,以便异步通知更改记录
|
||||
Boolean success = shopMchEntryService.updateMerchEntryLklMerCupNo(mchId, CommonConstant.Disable2, lklMerInnerNo, lklMerInnerNo, reqJsonBody.toString(), rawData.toString());
|
||||
if (!success) {
|
||||
if (!Boolean.TRUE.equals(success)) {
|
||||
logger.error("进件成功但更新商户号失败,商户ID: {}", mchId);
|
||||
shopMchEntryService.updateMerchEntryApprovalByMchId(shopMchEntry.getId(), CommonConstant.MCH_APPR_STA_LKL_NOPASS, "进件成功,但更新商户号失败!");
|
||||
return Pair.of(false, "提交进件成功,但更新商户号失败!");
|
||||
}
|
||||
|
||||
} catch (Exception e) {
|
||||
logger.error("拉卡拉进件异常:{}", e.getMessage());
|
||||
logger.error("拉卡拉进件异常,商户ID: {}", mchId, e);
|
||||
shopMchEntryService.updateMerchEntryApprovalByMchId(shopMchEntry.getId(), CommonConstant.MCH_APPR_STA_LKL_NOPASS, "进件失败:" + e.getMessage());
|
||||
return Pair.of(false, "提交拉卡拉进件失败:" + e.getMessage());
|
||||
}
|
||||
|
||||
logger.info("拉卡拉进件提交成功,等待审核,商户ID: {}", mchId);
|
||||
shopMchEntryService.updateMerchEntryApprovalByMchId(shopMchEntry.getId(), CommonConstant.MCH_APPR_STA_LKL_PADDING, "提交拉卡拉进件成功,正进一步审核!");
|
||||
return Pair.of(true, "提交拉卡拉进件成功,正进一步审核!");
|
||||
}
|
||||
@ -566,91 +609,117 @@ public class LklTkServiceImpl {
|
||||
/**
|
||||
* (重要)拉卡拉进件异步通知
|
||||
*
|
||||
* @param request
|
||||
* @return
|
||||
* <p>处理拉卡拉平台发送的商户进件结果异步通知,包括解密通知数据、更新商户状态等操作。
|
||||
*
|
||||
* @param request HTTP请求对象,包含拉卡拉发送的异步通知数据
|
||||
* @return JSONObject 响应结果,包含处理状态码和消息
|
||||
*/
|
||||
// @Transactional
|
||||
public JSONObject registrationMerchantNotify(HttpServletRequest request) {
|
||||
logger.debug("拉卡拉进件异步通知开始");
|
||||
logger.info("开始处理拉卡拉进件异步通知");
|
||||
|
||||
// 解密请求参数
|
||||
String requestBody = LakalaUtil.getBody(request);
|
||||
logger.debug("拉卡拉进件异步通知返回参数:{}", requestBody);
|
||||
try {
|
||||
// 解密请求参数
|
||||
String requestBody = LakalaUtil.getBody(request);
|
||||
logger.debug("拉卡拉进件异步通知原始参数:{}", requestBody);
|
||||
|
||||
if (StrUtil.isBlank(requestBody)) {
|
||||
return new JSONObject().set("code", "400").set("message", "返回参数为空");
|
||||
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 auditStatus = dataJSON.getStr("status");
|
||||
String merCupNo = dataJSON.getStr("externalCustomerNo"); //拉卡拉外部商户号
|
||||
String merInnerNo = dataJSON.getStr("customerNo"); //拉卡拉内部商户号
|
||||
String termNos = dataJSON.getStr("termNos"); //拉卡拉分配的业务终端号
|
||||
|
||||
logger.debug("解析通知数据完成 - 审核状态: {},外部商户号: {},内部商户号: {},终端号: {}",
|
||||
auditStatus, merCupNo, merInnerNo, termNos);
|
||||
|
||||
// 合并参数校验
|
||||
if (dataJSON.isEmpty() ||
|
||||
StrUtil.isBlank(auditStatus) ||
|
||||
StrUtil.isBlank(merCupNo) ||
|
||||
StrUtil.isBlank(merInnerNo)) {
|
||||
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);
|
||||
|
||||
// 校验审核状态
|
||||
logger.debug("校验审核状态: {}", auditStatus);
|
||||
if (!"SUCCESS".equals(auditStatus) && !"REVIEW_PASS".equals(auditStatus)) {
|
||||
String remark = dataJSON.getStr("remark");
|
||||
logger.warn("拉卡拉进件审核未通过,审核状态: {},备注: {}", auditStatus, remark);
|
||||
shopMchEntryService.updateMerchEntryApprovalByMchId(mchId, CommonConstant.MCH_APPR_STA_LKL_NOPASS, "进件失败:" + remark);
|
||||
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, shopMchEntry.getDistributor_id());
|
||||
|
||||
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());
|
||||
}
|
||||
|
||||
JSONObject reqBodyJSON = JSONUtil.parseObj(requestBody);
|
||||
if (reqBodyJSON.isEmpty() || reqBodyJSON.get("data") == null) {
|
||||
return new JSONObject().set("code", "400").set("message", "参数格式有误,无法解析");
|
||||
}
|
||||
|
||||
String srcData = reqBodyJSON.getStr("data");
|
||||
if (StrUtil.isBlank(srcData)) {
|
||||
return new JSONObject().set("code", "400").set("message", "关键参数为空值");
|
||||
}
|
||||
|
||||
// 公钥解密出来的数据
|
||||
String notifyPubKey = LakalaUtil.getResourceFile(notifyPubKeyPath, false, false);
|
||||
String data = LakalaUtil.decryptNotifyData(notifyPubKey, srcData);
|
||||
if (StrUtil.isBlank(data)) {
|
||||
return new JSONObject().set("code", "400").set("message", "数据解密出错!");
|
||||
}
|
||||
|
||||
logger.debug("拉卡拉进件异步通知data解密成功,开始处理逻辑");
|
||||
|
||||
// 逻辑处理
|
||||
JSONObject dataJSON = JSONUtil.parseObj(data);
|
||||
String auditStatus = dataJSON.getStr("status");
|
||||
String merCupNo = dataJSON.getStr("externalCustomerNo"); //拉卡拉外部商户号
|
||||
String merInnerNo = dataJSON.getStr("customerNo"); //拉卡拉内部商户号
|
||||
String termNos = dataJSON.getStr("termNos"); //拉卡拉分配的业务终端号
|
||||
|
||||
// 合并参数校验
|
||||
if (dataJSON.isEmpty() ||
|
||||
StrUtil.isBlank(auditStatus) ||
|
||||
StrUtil.isBlank(merCupNo) ||
|
||||
StrUtil.isBlank(merInnerNo)) {
|
||||
return new JSONObject().set("code", "500").set("message", "参数解析出错");
|
||||
}
|
||||
|
||||
// 给商家入驻表增加拉卡拉的商户号和拉卡拉返回的数据
|
||||
ShopMchEntry shopMchEntry = shopMchEntryService.getShopMerchEntryByMerInnerNo(merInnerNo);
|
||||
if (shopMchEntry == null) {
|
||||
logger.error("拉卡拉进件异步通知:{}内部商户号入驻信息不存在!", merInnerNo);
|
||||
return new JSONObject().put("code", "500").put("message", merInnerNo + "内部商户号入驻信息不存在");
|
||||
}
|
||||
|
||||
Long mchId = shopMchEntry.getId();
|
||||
|
||||
|
||||
// 校验审核状态
|
||||
if (!"SUCCESS".equals(auditStatus) && !"REVIEW_PASS".equals(auditStatus)) {
|
||||
logger.debug("返回的审核状态:{}", auditStatus);
|
||||
shopMchEntryService.updateMerchEntryApprovalByMchId(mchId, CommonConstant.MCH_APPR_STA_LKL_NOPASS, "进件失败:" + dataJSON.getStr("remark"));
|
||||
return new JSONObject().set("code", "FAIL").set("message", "返回审核状态有误");
|
||||
}
|
||||
|
||||
// RMK 拉卡拉进价提交成功,边处理周边的数据,边等待审核异步通知
|
||||
|
||||
// 更新已进件成功的商户号和设备号
|
||||
Boolean success = shopMchEntryService.updateMerchEntryLklAuditStatusByLklMerCupNo(
|
||||
merInnerNo, merCupNo, termNos, CommonConstant.Enable, null, data);
|
||||
|
||||
if (!success) {
|
||||
shopMchEntryService.updateMerchEntryApprovalByMchId(mchId, CommonConstant.MCH_APPR_STA_LKL_NOPASS, "进件时更新商户号失败");
|
||||
return new JSONObject().set("code", "500").set("message", "更新商户号失败");
|
||||
}
|
||||
|
||||
|
||||
shopMchEntryService.updateMerchEntryApprovalByMchId(shopMchEntry.getId(), CommonConstant.MCH_APPR_STA_LKL_PADDING,
|
||||
"进件、申请分账业务、创建分账接收方均已成功,等待拉卡拉审核分账业务请求!");
|
||||
|
||||
//密集操作:进件审核通过之后,要下一步流程操作:申请分账业务、创建分账接收方
|
||||
registrationMerchantAfterHook(mchId, merCupNo, shopMchEntry.getDistributor_id());
|
||||
|
||||
return new JSONObject().set("code", "200").set("message", "处理成功");
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@ -211,7 +211,7 @@ public class ShopOrderReturnController extends BaseControllerImpl {
|
||||
* {"order_id":"DD-20250701-1","reason":"商家协商退款","order_return_vo":{"order_id":"DD-20250701-1","return_items":[{"order_item_id":1,"return_item_num":1,"return_refund_amount":"0.01"}]}}
|
||||
* @return CommonResult 处理结果
|
||||
*/
|
||||
@ApiOperation(value = "商家退货退款", notes = "商家退货退款,支持整单或个别商品退货")
|
||||
@ApiOperation(value = "商家退款", notes = "商家退款,支持整单或个别商品退货")
|
||||
@RequestMapping(value = "/mch/order/doRefund", method = RequestMethod.POST)
|
||||
public CommonResult doRefundForMch(@RequestBody JSONObject params) {
|
||||
return shopOrderReturnService.doRefundForMch(params);
|
||||
|
||||
@ -764,7 +764,7 @@ public class ShopOrderBaseServiceImpl extends BaseServiceImpl<ShopOrderBaseMappe
|
||||
ShopOrderLkl shopOrderLkl = shopOrderLklService.getByStoreIdAndOrderId(shopOrderInfo.getStore_id(), order_id);
|
||||
if (shopOrderLkl != null) {
|
||||
base_row.put("lkl_merchant_no", shopOrderLkl.getLkl_merchant_no());
|
||||
base_row.put("lkl_trade_no", shopOrderLkl.getLkl_sub_trade_no());
|
||||
base_row.put("lkl_trade_no", shopOrderLkl.getWx_transaction_id());
|
||||
base_row.put("lkl_log_no", shopOrderLkl.getLkl_sub_log_no());
|
||||
}
|
||||
|
||||
@ -8092,7 +8092,7 @@ public class ShopOrderBaseServiceImpl extends BaseServiceImpl<ShopOrderBaseMappe
|
||||
ShopOrderLkl shopOrderLkl = shopOrderLklService.getByStoreIdAndOrderId(store_id, order_id);
|
||||
if (shopOrderLkl != null) {
|
||||
order_info_row.put("lkl_merchant_no", shopOrderLkl.getLkl_merchant_no());
|
||||
order_info_row.put("lkl_trade_no", shopOrderLkl.getLkl_sub_trade_no());
|
||||
order_info_row.put("lkl_trade_no", shopOrderLkl.getWx_transaction_id());
|
||||
order_info_row.put("lkl_log_no", shopOrderLkl.getLkl_sub_log_no());
|
||||
}
|
||||
|
||||
|
||||
@ -51,7 +51,6 @@ public class ShopOrderLklServiceImpl extends BaseServiceImpl<ShopOrderLklMapper,
|
||||
@Resource
|
||||
private ShopOrderDataService shopOrderDataService;
|
||||
|
||||
|
||||
@Override
|
||||
public Boolean addOrUpdateByStoreOrder(ShopOrderLkl record) {
|
||||
if (record == null
|
||||
@ -244,7 +243,7 @@ public class ShopOrderLklServiceImpl extends BaseServiceImpl<ShopOrderLklMapper,
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据拉卡拉支付通知数据保存或更新拉卡拉订单记录
|
||||
* 根据拉卡拉支付异步回调通知数据保存或更新拉卡拉订单记录
|
||||
* 该方法用于处理拉卡拉支付平台发送的支付通知,将通知中的数据保存到shop_order_lkl表中
|
||||
*
|
||||
* @param lklPayNotifyDataJson 拉卡拉支付通知的JSON数据
|
||||
@ -287,9 +286,11 @@ public class ShopOrderLklServiceImpl extends BaseServiceImpl<ShopOrderLklMapper,
|
||||
// 设置可选字段
|
||||
String tradeNo = lklPayNotifyDataJson.getStr("trade_no");
|
||||
String tradeStatus = lklPayNotifyDataJson.getStr("trade_status");
|
||||
String accTradeNo = lklPayNotifyDataJson.getStr("acc_trade_no");
|
||||
record.setLkl_trade_no(tradeNo);
|
||||
record.setTrade_status(tradeStatus);
|
||||
log.debug("[拉卡拉订单更新] 设置可选字段: tradeNo={} tradeStatus={}", tradeNo, tradeStatus);
|
||||
record.setWx_transaction_id(accTradeNo); //账户端交易订单号 对应微信的用户交易单号
|
||||
log.debug("[拉卡拉订单更新] 设置可选字段: tradeNo={} accTradeNo={} tradeStatus={}", tradeNo,accTradeNo, tradeStatus);
|
||||
|
||||
// 新增的订单字段,lkl_sub_log_no,out_separate_no,split_amt 四个字段无值,就给主单的值
|
||||
String outSeparateNo = JsonUtil.getJsonValueSmart(lklPayNotifyDataJson, "out_separate_no");
|
||||
|
||||
@ -58,7 +58,10 @@ import com.suisung.mall.shop.sfexpress.service.SFExpressApiService;
|
||||
import com.suisung.mall.shop.store.service.ShopStoreBaseService;
|
||||
import com.suisung.mall.shop.store.service.ShopStoreConfigService;
|
||||
import com.suisung.mall.shop.store.service.ShopStoreShippingAddressService;
|
||||
import io.seata.core.context.RootContext;
|
||||
import io.seata.core.exception.TransactionException;
|
||||
import io.seata.spring.annotation.GlobalTransactional;
|
||||
import io.seata.tm.api.GlobalTransactionContext;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
@ -418,15 +421,16 @@ public class ShopOrderReturnServiceImpl extends BaseServiceImpl<ShopOrderReturnM
|
||||
/**
|
||||
* 添加退款退货-发货退货,卖家也可以决定不退货退款,买家申请退款不支持。卖家可以主动退款。
|
||||
*
|
||||
* @param orderReturnInputVo
|
||||
* @param needSendMsg 是否需要发(站内 推送)消息
|
||||
* @return
|
||||
* @param orderReturnInputVo 退款申请输入参数
|
||||
* @param needSendMsg 是否需要发送消息通知
|
||||
* @return CommonResult 退款申请结果
|
||||
*/
|
||||
@Override
|
||||
@Transactional
|
||||
public CommonResult addItem(OrderReturnInputVo orderReturnInputVo, Boolean needSendMsg) {
|
||||
Map data = new HashMap();
|
||||
|
||||
// 获取用户ID
|
||||
Integer user_id = orderReturnInputVo.getUser_id();
|
||||
if (CheckUtil.isEmpty(user_id)) {
|
||||
UserDto user = getCurrentUser();
|
||||
@ -436,30 +440,36 @@ public class ShopOrderReturnServiceImpl extends BaseServiceImpl<ShopOrderReturnM
|
||||
user_id = user.getId();
|
||||
}
|
||||
|
||||
//是否有店铺
|
||||
// 获取买家店铺ID(如果有)
|
||||
Integer buyer_store_id = shopStoreBaseService.getStoreId(user_id);
|
||||
|
||||
// 获取订单信息
|
||||
String order_id = orderReturnInputVo.getOrder_id();
|
||||
List<Long> order_item_ids = orderReturnInputVo.getReturn_items().stream().map(OrderReturnItemInputVo::getOrder_item_id).distinct().collect(Collectors.toList());
|
||||
ShopOrderInfo shopOrderInfo = shopOrderInfoService.get(order_id);
|
||||
List<Long> order_item_ids = orderReturnInputVo.getReturn_items().stream()
|
||||
.map(OrderReturnItemInputVo::getOrder_item_id)
|
||||
.distinct()
|
||||
.collect(Collectors.toList());
|
||||
|
||||
ShopOrderInfo shopOrderInfo = shopOrderInfoService.get(order_id);
|
||||
if (shopOrderInfo == null) {
|
||||
throw new ApiException(I18nUtil._("此订单信息数据有误!"));
|
||||
}
|
||||
|
||||
ShopOrderBase orderBase = shopOrderBaseService.get(order_id);
|
||||
|
||||
if (orderBase == null) {
|
||||
throw new ApiException(I18nUtil._("此订单详细信息数据有误!"));
|
||||
}
|
||||
|
||||
// 判断此订单商品是否有正在审核的退款单。
|
||||
// 判断此订单商品是否有正在审核的退款单
|
||||
QueryWrapper<ShopOrderReturn> returnQueryWrapper = new QueryWrapper<>();
|
||||
returnQueryWrapper.eq("order_id", order_id).eq("return_state_id", StateCode.RETURN_PROCESS_CHECK);
|
||||
returnQueryWrapper.eq("order_id", order_id)
|
||||
.eq("return_state_id", StateCode.RETURN_PROCESS_CHECK);
|
||||
List<ShopOrderReturn> order_return_rows = find(returnQueryWrapper);
|
||||
|
||||
if (CollUtil.isNotEmpty(order_return_rows)) {
|
||||
List<String> return_ids = order_return_rows.stream().map(ShopOrderReturn::getReturn_id).collect(Collectors.toList());
|
||||
List<String> return_ids = order_return_rows.stream()
|
||||
.map(ShopOrderReturn::getReturn_id)
|
||||
.collect(Collectors.toList());
|
||||
|
||||
QueryWrapper<ShopOrderReturnItem> returnItemQueryWrapper = new QueryWrapper<>();
|
||||
returnItemQueryWrapper.in("order_item_id", order_item_ids)
|
||||
@ -471,13 +481,14 @@ public class ShopOrderReturnServiceImpl extends BaseServiceImpl<ShopOrderReturnM
|
||||
}
|
||||
}
|
||||
|
||||
// todo 检测该订单使用的优惠券等情况
|
||||
// 检查数据权限
|
||||
if (!CheckUtil.checkDataRights(user_id, orderBase, ShopOrderBase::getBuyer_user_id)) {
|
||||
throw new ApiException(ResultCode.FORBIDDEN);
|
||||
}
|
||||
|
||||
// 获取退款申请参数
|
||||
String return_id = orderReturnInputVo.getReturn_id();
|
||||
Integer return_reason_id = orderReturnInputVo.getReturn_reason_id();
|
||||
Integer return_reason_id = orderReturnInputVo.getReturn_reason_id() == null ? 0 : orderReturnInputVo.getReturn_reason_id();
|
||||
String return_buyer_message = orderReturnInputVo.getReturn_buyer_message();
|
||||
Integer store_id = Convert.toInt(orderBase.getStore_id());
|
||||
String return_tel = orderReturnInputVo.getReturn_tel();
|
||||
@ -489,8 +500,8 @@ public class ShopOrderReturnServiceImpl extends BaseServiceImpl<ShopOrderReturnM
|
||||
|
||||
Date curTime = new Date();
|
||||
|
||||
// 构建退款单主表信息
|
||||
ShopOrderReturn orderReturn = new ShopOrderReturn();
|
||||
|
||||
orderReturn.setReturn_id(return_id);
|
||||
orderReturn.setOrder_id(order_id);
|
||||
orderReturn.setBuyer_user_id(user_id);
|
||||
@ -505,29 +516,34 @@ public class ShopOrderReturnServiceImpl extends BaseServiceImpl<ShopOrderReturnM
|
||||
orderReturn.setReturn_year(DateUtil.year(curTime)); // 退单年份-索引查询
|
||||
orderReturn.setReturn_month(DateUtil.month(curTime) + 1); // 退单月份-索引查询
|
||||
orderReturn.setReturn_day(DateUtil.dayOfMonth(curTime)); // 退单日-索引查询
|
||||
orderReturn.setReturn_reason_id(0);
|
||||
orderReturn.setReturn_reason_id(0); // 注意:这里覆盖了前面设置的return_reason_id
|
||||
orderReturn.setReturn_store_user_id(0);
|
||||
orderReturn.setReturn_mobile(0L);
|
||||
orderReturn.setReturn_telephone("");
|
||||
orderReturn.setSubsite_id(shopOrderInfo.getSubsite_id());
|
||||
|
||||
// 构建退款单明细信息
|
||||
List<ShopOrderReturnItem> shopOrderReturnItems = new ArrayList<>();
|
||||
for (OrderReturnItemInputVo returnItemInputVo : orderReturnInputVo.getReturn_items()) {
|
||||
// 获取订单商品信息
|
||||
ShopOrderItem shopOrderItem = shopOrderItemService.get(returnItemInputVo.getOrder_item_id());
|
||||
|
||||
if (shopOrderItem == null) {
|
||||
throw new ApiException(I18nUtil._("此订单商品订单数据有误!"));
|
||||
}
|
||||
ShopProductIndex shopProductIndex = shopProductIndexService.get(shopOrderItem.getProduct_id());
|
||||
|
||||
// 获取商品索引信息
|
||||
ShopProductIndex shopProductIndex = shopProductIndexService.get(shopOrderItem.getProduct_id());
|
||||
if (shopProductIndex == null) {
|
||||
throw new ApiException(I18nUtil._("此订单商品数据有误!"));
|
||||
}
|
||||
|
||||
// 检查是否允许退货
|
||||
boolean is_denyreturn = ifDenyReturn(shopOrderInfo, shopOrderItem, shopProductIndex);
|
||||
if (is_denyreturn) {
|
||||
throw new ApiException(I18nUtil._("此商品不允许退货!"));
|
||||
}
|
||||
|
||||
// 构建退款单明细
|
||||
ShopOrderReturnItem orderReturnItem = new ShopOrderReturnItem();
|
||||
Integer return_item_num = returnItemInputVo.getReturn_item_num();
|
||||
|
||||
@ -536,61 +552,43 @@ public class ShopOrderReturnServiceImpl extends BaseServiceImpl<ShopOrderReturnM
|
||||
}
|
||||
|
||||
BigDecimal return_refund_amount = returnItemInputVo.getReturn_refund_amount();
|
||||
String return_item_image = ObjectUtil.defaultIfBlank(orderReturnInputVo.getRefund_pic(), orderReturnInputVo.getUpload_img());
|
||||
String return_item_image = ObjectUtil.defaultIfBlank(
|
||||
orderReturnInputVo.getRefund_pic(),
|
||||
orderReturnInputVo.getUpload_img());
|
||||
|
||||
orderReturnItem.setOrder_item_id(returnItemInputVo.getOrder_item_id()); // 退货商品编号(DOT):0为退款
|
||||
orderReturnItem.setOrder_id(order_id); // 订单编号
|
||||
orderReturnItem.setReturn_item_num(return_item_num); // 退货商品编号(DOT):0为退款
|
||||
orderReturnItem.setReturn_item_subtotal(return_refund_amount); // 退款金额 = goods_payment_amount/goods_quantity, 因为涉及到折扣等等 或者为订单中 order_payment_amount
|
||||
orderReturnItem.setReturn_reason_id(return_reason_id); // 退款理由id
|
||||
orderReturnItem.setReturn_item_note(return_buyer_message); // 买家退货备注
|
||||
orderReturnItem.setOrder_item_id(returnItemInputVo.getOrder_item_id());
|
||||
orderReturnItem.setOrder_id(order_id);
|
||||
orderReturnItem.setReturn_item_num(return_item_num);
|
||||
orderReturnItem.setReturn_item_subtotal(return_refund_amount);
|
||||
orderReturnItem.setReturn_reason_id(return_reason_id);
|
||||
orderReturnItem.setReturn_item_note(return_buyer_message);
|
||||
orderReturnItem.setReturn_item_image(return_item_image);
|
||||
orderReturnItem.setReturn_state_id(StateCode.RETURN_PROCESS_CHECK);
|
||||
orderReturnItem.setReturn_reason_id(0);
|
||||
|
||||
shopOrderReturnItems.add(orderReturnItem);
|
||||
}
|
||||
|
||||
// 保存退款单
|
||||
if (!addReturnByItem(orderReturn, shopOrderReturnItems)) {
|
||||
throw new ApiException(ResultCode.FAILED);
|
||||
}
|
||||
|
||||
|
||||
data.put("return", orderReturn);
|
||||
data.put("items", shopOrderReturnItems);
|
||||
|
||||
//暂时注释
|
||||
// 七天无理由自动退货
|
||||
/*if (contractTypeIds.contains(StateCode.CONTRACT_TYPE_7_RETURN) && shopOrderInfo.getOrder_is_out().equals(StateCode.ORDER_PICKING_STATE_NO)) {
|
||||
ShopOrderReturn shopOrderReturn = new ShopOrderReturn();
|
||||
shopOrderReturn.setReturn_id(orderReturn.getReturn_id());
|
||||
shopOrderReturn.setReturn_flag(0);
|
||||
shopOrderReturn.setReturn_store_message(I18nUtil._("七天无理由自动退货"));
|
||||
shopOrderReturn.setStore_id(store_id);
|
||||
// 退单审核
|
||||
shopOrderReturnService.review(shopOrderReturn, 0);
|
||||
}*/
|
||||
|
||||
if (needSendMsg) {
|
||||
// 发送消息通知
|
||||
if (needSendMsg != null && needSendMsg) {
|
||||
// 退款提醒商家
|
||||
// 退货单提交成功,对商家进行提醒
|
||||
// String message_id = "return-reminder";
|
||||
// Map args = new HashMap();
|
||||
// args.put("order_id", return_id);
|
||||
// args.put("id", order_id);
|
||||
// args.put("return_id", return_id);
|
||||
// args.put("order_item", String.format(("退货商品编号:[%s]"), order_item_id));
|
||||
// messageService.sendNoticeMsg(0, store_id, message_id, args);
|
||||
|
||||
String message_id = "refund-reminder";
|
||||
Map args = new HashMap();
|
||||
args.put("order_id", orderReturn.getReturn_id());
|
||||
messageService.sendNoticeMsg(0, store_id, message_id, args);
|
||||
|
||||
// 发送unipush 消息
|
||||
|
||||
// 发送unipush消息
|
||||
String title = "您有一个退款的订单,请及时前往后台审核!";
|
||||
String content = String.format("订单号:%s 退单号:[%s],时间:%s,请及时前往后台审核!", order_id, orderReturn.getReturn_id(), DateTimeUtils.formatDateTime(LocalDateTime.now(), "yyyy-MM-dd HH:mm:ss"));
|
||||
String content = String.format("订单号:%s 退单号:[%s],时间:%s,请及时前往后台审核!",
|
||||
order_id, orderReturn.getReturn_id(),
|
||||
DateTimeUtils.formatDateTime(LocalDateTime.now(), "yyyy-MM-dd HH:mm:ss"));
|
||||
JSONObject payload = new JSONObject();
|
||||
payload.put("category", CommonConstant.PUSH_MSG_CATE_MCH_RETURN_ORDER_LIST);
|
||||
payload.put("orderId", order_id);
|
||||
@ -598,9 +596,7 @@ public class ShopOrderReturnServiceImpl extends BaseServiceImpl<ShopOrderReturnM
|
||||
pushMessageService.noticeMerchantEmployeeOrderAction(store_id, order_id, title, content, payload);
|
||||
}
|
||||
|
||||
|
||||
data.put("order_item_ids", order_item_ids);
|
||||
|
||||
return CommonResult.success(data);
|
||||
}
|
||||
|
||||
@ -945,7 +941,7 @@ public class ShopOrderReturnServiceImpl extends BaseServiceImpl<ShopOrderReturnM
|
||||
String remark = "同城配送异常自动退款!";
|
||||
|
||||
// 先整单退货申请
|
||||
CommonResult commonResult = addWholeItems(shopOrderId, true, remark);
|
||||
CommonResult commonResult = addRemainingItems(shopOrderId, true, remark);
|
||||
commonResult.checkFenResult();
|
||||
logger.debug("[顺丰超时自动退款] 整单退货申请创建成功: shopOrderId={}", shopOrderId);
|
||||
|
||||
@ -974,6 +970,12 @@ public class ShopOrderReturnServiceImpl extends BaseServiceImpl<ShopOrderReturnM
|
||||
return result;
|
||||
} catch (Exception e) {
|
||||
logger.error("[顺丰超时自动退款] 处理过程中发生异常: shopOrderId={}", shopOrderId, e);
|
||||
// 手动触发Seata事务回滚
|
||||
try {
|
||||
GlobalTransactionContext.reload(RootContext.getXID()).rollback();
|
||||
} catch (TransactionException transactionException) {
|
||||
logger.error("[顺丰超时自动退款] Seata事务回滚异常: shopOrderId={}", shopOrderId, transactionException);
|
||||
}
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
@ -1241,6 +1243,7 @@ public class ShopOrderReturnServiceImpl extends BaseServiceImpl<ShopOrderReturnM
|
||||
|
||||
// 2. 根据退货标志处理不同流程
|
||||
if (ObjectUtil.equal(shopOrderReturn.getReturn_flag(), 0)) {
|
||||
|
||||
// 2.1 无需退货流程
|
||||
if (!edit(shopOrderReturn)) {
|
||||
throw new ApiException(I18nUtil._("修改订单信息失败!"));
|
||||
@ -1248,6 +1251,7 @@ public class ShopOrderReturnServiceImpl extends BaseServiceImpl<ShopOrderReturnM
|
||||
if (!processReviewList(return_ids, orderReturns, StateCode.RETURN_PROCESS_CHECK, StateCode.RETURN_PROCESS_FINISH)) {
|
||||
throw new ApiException(I18nUtil._("审核失败!"));
|
||||
}
|
||||
|
||||
} else {
|
||||
// 2.2 需要退货流程
|
||||
ShopStoreShippingAddress address = shopStoreShippingAddressService.get(receiving_address);
|
||||
@ -1278,6 +1282,7 @@ public class ShopOrderReturnServiceImpl extends BaseServiceImpl<ShopOrderReturnM
|
||||
}});
|
||||
|
||||
return true;
|
||||
|
||||
} catch (Exception e) {
|
||||
logger.error("退货单审核处理异常", e);
|
||||
throw e instanceof ApiException ? (ApiException) e :
|
||||
@ -1409,7 +1414,7 @@ public class ShopOrderReturnServiceImpl extends BaseServiceImpl<ShopOrderReturnM
|
||||
* RETURN_PROCESS_CANCEL = 3135; //-买家取消退款
|
||||
* @param return_rows 退货订单列表
|
||||
* @param return_next_state_id 下一个退单状态
|
||||
* @return
|
||||
* @return boolean 处理结果
|
||||
*/
|
||||
@GlobalTransactional
|
||||
private boolean editNextState(List<String> return_ids, Integer store_id, Integer return_state_id, List<ShopOrderReturn> return_rows, Integer return_next_state_id) {
|
||||
@ -1434,15 +1439,17 @@ public class ShopOrderReturnServiceImpl extends BaseServiceImpl<ShopOrderReturnM
|
||||
ShopOrderInfo shopOrderInfo = shopOrderInfoService.get(order_id);
|
||||
|
||||
if (shopOrderInfo == null) {
|
||||
logger.error("该订单详情信息不存在!订单ID: {}", order_id);
|
||||
throw new ApiException(I18nUtil._("该订单详情信息不存在!"));
|
||||
}
|
||||
|
||||
// 查询订单表是否出库
|
||||
if (shopOrderInfo.getOrder_is_out().equals(StateCode.ORDER_PICKING_STATE_YES)) {
|
||||
if (ObjectUtil.equal(shopOrderInfo.getOrder_is_out(), StateCode.ORDER_PICKING_STATE_YES)) {
|
||||
Long orderItemId = returnItem.getOrder_item_id();
|
||||
ShopOrderItem shopOrderItem = shopOrderItemService.get(orderItemId);
|
||||
|
||||
if (shopOrderItem == null) {
|
||||
logger.error("该订单商品表信息不存在!订单项ID: {}", orderItemId);
|
||||
throw new ApiException(I18nUtil._("该订单商品表信息不存在!"));
|
||||
}
|
||||
|
||||
@ -1451,15 +1458,22 @@ public class ShopOrderReturnServiceImpl extends BaseServiceImpl<ShopOrderReturnM
|
||||
ShopProductItem productItem = shopProductItemService.get(itemId);
|
||||
|
||||
if (productItem == null) {
|
||||
logger.error("该订单商品表-SKU表信息不存在!商品项ID: {}", itemId);
|
||||
throw new ApiException(I18nUtil._("该订单商品表-SKU表信息不存在!"));
|
||||
}
|
||||
|
||||
productItem.setItem_quantity(productItem.getItem_quantity() + returnItem.getReturn_item_num());
|
||||
|
||||
if (!shopProductItemService.edit(productItem)) {
|
||||
throw new ApiException(I18nUtil._("增加库存失败!"));
|
||||
// 增加库存
|
||||
Integer returnNum = returnItem.getReturn_item_num();
|
||||
if (returnNum != null) {
|
||||
productItem.setItem_quantity(productItem.getItem_quantity() + returnNum);
|
||||
if (!shopProductItemService.edit(productItem)) {
|
||||
logger.error("增加库存失败!商品项ID: {}", itemId);
|
||||
throw new ApiException(I18nUtil._("增加库存失败!"));
|
||||
}
|
||||
logger.debug("成功增加商品库存,商品项ID: {}, 增加数量: {}", itemId, returnNum);
|
||||
} else {
|
||||
logger.warn("退货数量为空,无法增加库存,订单项ID: {}", orderItemId);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1486,55 +1500,92 @@ public class ShopOrderReturnServiceImpl extends BaseServiceImpl<ShopOrderReturnM
|
||||
//退货类型(BOOL): 0-退款单;1-退运费单
|
||||
Integer return_is_shipping_fee = return_row.getReturn_is_shipping_fee();
|
||||
|
||||
if (CheckUtil.isEmpty(return_is_shipping_fee)) {
|
||||
// 处理非退运费单的情况
|
||||
if (CheckUtil.isEmpty(return_is_shipping_fee) || return_is_shipping_fee != 1) {
|
||||
// 所有单品退款额度
|
||||
QueryWrapper<ShopOrderItem> orderItemQueryWrapper = new QueryWrapper<>();
|
||||
orderItemQueryWrapper.eq("order_id", order_id);
|
||||
List<ShopOrderItem> orderItemList = shopOrderItemService.find(orderItemQueryWrapper);
|
||||
|
||||
// 累计订单项支付总金额
|
||||
BigDecimal order_item_payment_amount = orderItemList.stream().map(s -> s.getOrder_item_payment_amount()).reduce(BigDecimal::add).get();
|
||||
BigDecimal order_item_payment_amount = BigDecimal.ZERO;
|
||||
if (CollUtil.isNotEmpty(orderItemList)) {
|
||||
order_item_payment_amount = orderItemList.stream()
|
||||
.map(ShopOrderItem::getOrder_item_payment_amount)
|
||||
.filter(Objects::nonNull)
|
||||
.reduce(BigDecimal.ZERO, BigDecimal::add);
|
||||
}
|
||||
|
||||
// 当前已经同意退款额度 = 所有单品退款额度
|
||||
QueryWrapper<ShopOrderReturnItem> returnItemQueryWrapper = new QueryWrapper<>();
|
||||
returnItemQueryWrapper.eq("order_id", order_id).in("return_state_id", StateCode.RETURN_PROCESS_RECEIVED, StateCode.RETURN_PROCESS_REFUND, StateCode.RETURN_PROCESS_RECEIPT_CONFIRMATION, StateCode.RETURN_PROCESS_FINISH);
|
||||
returnItemQueryWrapper.eq("order_id", order_id)
|
||||
.in("return_state_id", Arrays.asList(
|
||||
StateCode.RETURN_PROCESS_RECEIVED,
|
||||
StateCode.RETURN_PROCESS_REFUND,
|
||||
StateCode.RETURN_PROCESS_RECEIPT_CONFIRMATION,
|
||||
StateCode.RETURN_PROCESS_FINISH));
|
||||
List<ShopOrderReturnItem> returnItemList = orderReturnItemService.find(returnItemQueryWrapper);
|
||||
BigDecimal return_item_subtotal = returnItemList.stream().map(s -> s.getReturn_item_subtotal()).reduce(BigDecimal::add).get();
|
||||
|
||||
BigDecimal return_item_subtotal = BigDecimal.ZERO;
|
||||
if (CollUtil.isNotEmpty(returnItemList)) {
|
||||
return_item_subtotal = returnItemList.stream()
|
||||
.map(ShopOrderReturnItem::getReturn_item_subtotal)
|
||||
.filter(Objects::nonNull)
|
||||
.reduce(BigDecimal.ZERO, BigDecimal::add);
|
||||
}
|
||||
|
||||
// 订单所有商品退款的情况
|
||||
if (ObjectUtil.compare(order_item_payment_amount, return_item_subtotal) == 0) {
|
||||
if (order_item_payment_amount.compareTo(return_item_subtotal) == 0) {
|
||||
logger.debug("订单所有商品均已退款,订单ID: {}", order_id);
|
||||
|
||||
ShopOrderData shopOrderData = new ShopOrderData();
|
||||
shopOrderData.setOrder_id(order_id);
|
||||
shopOrderData.setOrder_refund_status(2); //退款状态:0-是无退款;1-是部分退款;2-是全部退款
|
||||
if (!shopOrderDataService.edit(shopOrderData)) {
|
||||
logger.error("修改订单退款状态失败!订单ID: {}", order_id);
|
||||
throw new ApiException(ResultCode.FAILED);
|
||||
}
|
||||
|
||||
// 取消订单
|
||||
ShopOrderInfo info_row = shopOrderInfoService.get(order_id);
|
||||
if (info_row == null) {
|
||||
logger.error("获取订单信息失败!订单ID: {}", order_id);
|
||||
throw new ApiException(I18nUtil._("订单信息不存在!"));
|
||||
}
|
||||
|
||||
// 当前订单状态
|
||||
Integer order_state_id = info_row.getOrder_state_id();
|
||||
|
||||
// 没有发货没有完成订单之前,允许取消订单和退运费
|
||||
if (!Arrays.asList(StateCode.ORDER_STATE_SHIPPED, StateCode.ORDER_STATE_RECEIVED, StateCode.ORDER_STATE_FINISH).contains(order_state_id)) {
|
||||
|
||||
List<Integer> forbiddenStates = Arrays.asList(
|
||||
StateCode.ORDER_STATE_SHIPPED,
|
||||
StateCode.ORDER_STATE_RECEIVED,
|
||||
StateCode.ORDER_STATE_FINISH);
|
||||
if (order_state_id != null && !forbiddenStates.contains(order_state_id)) {
|
||||
// 取消订单,更改订单的状态为已取消
|
||||
shopOrderBaseService.cancel(order_id, info_row, false);
|
||||
// logger.info("全部退款完成,取消订单:{}", order_id);
|
||||
logger.info("全部退款完成,订单已取消:{}", order_id);
|
||||
|
||||
// 未发货,退运费 - 判断运费是否存在
|
||||
ShopOrderData order_data_row = shopOrderDataService.get(order_id);
|
||||
|
||||
// 如果有打包费,最后的退款订单的退款金额加上 打包费
|
||||
if (order_data_row != null && order_data_row.getPacking_fee().compareTo(BigDecimal.ZERO) > 0) {
|
||||
if (order_data_row != null &&
|
||||
order_data_row.getPacking_fee() != null &&
|
||||
order_data_row.getPacking_fee().compareTo(BigDecimal.ZERO) > 0) {
|
||||
// 退款金额+打包费
|
||||
BigDecimal order_refund_amount_add_fee = NumberUtil.add(order_data_row.getOrder_refund_amount(), order_data_row.getPacking_fee());
|
||||
BigDecimal order_refund_amount_add_fee = NumberUtil.add(
|
||||
order_data_row.getOrder_refund_amount(),
|
||||
order_data_row.getPacking_fee());
|
||||
// 最后一个退款订单如果有打包费,加上打包费
|
||||
return_row.setReturn_refund_amount(order_refund_amount_add_fee);
|
||||
logger.debug("已添加打包费到退款金额,订单ID: {}", order_id);
|
||||
}
|
||||
|
||||
// 有运费的订单
|
||||
if (order_data_row != null && order_data_row.getOrder_shipping_fee().compareTo(BigDecimal.ZERO) > 0) {
|
||||
if (order_data_row != null &&
|
||||
order_data_row.getOrder_shipping_fee() != null &&
|
||||
order_data_row.getOrder_shipping_fee().compareTo(BigDecimal.ZERO) > 0) {
|
||||
// 运费大于0的, 执行退运费操作, 有两种方案,1、生成退运费售后服务单; 2、直接执行退款
|
||||
// 1、生成独立退运费售后服务单,需注意运费是退给运费代理商的,需要获取代理商的交易单号
|
||||
|
||||
@ -1544,8 +1595,8 @@ public class ShopOrderReturnServiceImpl extends BaseServiceImpl<ShopOrderReturnM
|
||||
Integer storeId = info_row.getStore_id();
|
||||
// 订单运费
|
||||
BigDecimal order_shipping_fee = order_data_row.getOrder_shipping_fee();
|
||||
BigDecimal order_points_fee = order_data_row.getOrder_points_fee();
|
||||
BigDecimal order_refund_agree_points = order_data_row.getOrder_refund_agree_points();
|
||||
BigDecimal order_points_fee = ObjectUtil.defaultIfNull(order_data_row.getOrder_points_fee(), BigDecimal.ZERO);
|
||||
BigDecimal order_refund_agree_points = ObjectUtil.defaultIfNull(order_data_row.getOrder_refund_agree_points(), BigDecimal.ZERO);
|
||||
BigDecimal return_refund_point = NumberUtil.round(NumberUtil.sub(order_points_fee, order_refund_agree_points), 2);
|
||||
|
||||
return_order_shipping_fee_row.setOrder_id(order_id); // 订单编号
|
||||
@ -1559,7 +1610,7 @@ public class ShopOrderReturnServiceImpl extends BaseServiceImpl<ShopOrderReturnM
|
||||
return_order_shipping_fee_row.setReturn_add_time(now); // 添加时间
|
||||
return_order_shipping_fee_row.setReturn_tel("");
|
||||
// 店铺审核操作员
|
||||
Integer storeUserId = user == null ? 0 : user.getId();
|
||||
Integer storeUserId = user != null ? user.getId() : 0;
|
||||
return_order_shipping_fee_row.setReturn_store_user_id(storeUserId);
|
||||
return_order_shipping_fee_row.setReturn_telephone("");
|
||||
return_order_shipping_fee_row.setSubsite_id(info_row.getSubsite_id());
|
||||
@ -1581,11 +1632,14 @@ public class ShopOrderReturnServiceImpl extends BaseServiceImpl<ShopOrderReturnM
|
||||
String type_code = stateCodeService.getCode(StateCode.ORDER_TYPE_FX, "state_code_code");
|
||||
String return_id = shopNumberSeqService.createNextSeq(type_code);
|
||||
return_order_shipping_fee_row.setReturn_id(return_id);
|
||||
|
||||
// 运费独立加一条退单记录
|
||||
if (!add(return_order_shipping_fee_row)) {
|
||||
logger.error("生成退运费订单失败!订单ID: {}", order_id);
|
||||
// 1、生成退运费售后服务单;
|
||||
throw new ApiException(I18nUtil._("生成退运费订单失败!"));
|
||||
}
|
||||
logger.info("成功生成退运费订单,退单号: {}", return_id);
|
||||
|
||||
// 重要:加上单条运费退货单
|
||||
// return_rows.add(return_order_shipping_fee_row);
|
||||
@ -1603,17 +1657,16 @@ public class ShopOrderReturnServiceImpl extends BaseServiceImpl<ShopOrderReturnM
|
||||
// // 最后一个退款订单如果有运费,加上运费
|
||||
// return_row.setReturn_refund_amount(order_refund_amount_add_fee);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
} else {
|
||||
// 退款一部分商品
|
||||
logger.debug("订单部分商品退款,订单ID: {}", order_id);
|
||||
ShopOrderData orderData = new ShopOrderData();
|
||||
orderData.setOrder_id(order_id);
|
||||
orderData.setOrder_refund_status(CommonConstant.Enable);
|
||||
if (!shopOrderDataService.edit(orderData)) {
|
||||
logger.error("部分退款失败!订单ID: {}", order_id);
|
||||
throw new ApiException(I18nUtil._("部分退款失败!"));
|
||||
}
|
||||
}
|
||||
@ -1623,6 +1676,7 @@ public class ShopOrderReturnServiceImpl extends BaseServiceImpl<ShopOrderReturnM
|
||||
orderInfo.setOrder_id(order_id);
|
||||
orderInfo.setOrder_is_sync(0); // 订单同步状态
|
||||
if (!shopOrderInfoService.edit(orderInfo)) {
|
||||
logger.error("修改订单同步状态失败!订单ID: {}", order_id);
|
||||
throw new ApiException(I18nUtil._("修改订单同步状态失败!"));
|
||||
}
|
||||
}
|
||||
@ -1634,18 +1688,37 @@ public class ShopOrderReturnServiceImpl extends BaseServiceImpl<ShopOrderReturnM
|
||||
// 执行真正退款逻辑
|
||||
// 卖家账户扣款,买家账户增加
|
||||
// 佣金问题
|
||||
|
||||
shopOrderReturn.setReturn_is_paid(1); // 0-退货未完成;1-退货完成
|
||||
shopOrderReturn.setReturn_finish_time(now);
|
||||
|
||||
List<ShopOrderReturn> returnOrder = new ArrayList<>();
|
||||
returnOrder.addAll(return_rows);
|
||||
if (return_rows != null) {
|
||||
returnOrder.addAll(return_rows);
|
||||
}
|
||||
if (return_order_shipping_fee_row != null) {
|
||||
returnOrder.add(return_order_shipping_fee_row);
|
||||
}
|
||||
|
||||
// 重要:执行退款操作
|
||||
if (!payService.doRefund(returnOrder)) {
|
||||
logger.error("执行退款操作失败!退单列表: {}", return_ids);
|
||||
throw new ApiException(ResultCode.FAILED);
|
||||
}
|
||||
logger.info("退款操作执行成功,退单列表: {}", return_ids);
|
||||
|
||||
// 更新退货单的退款完成状态和完成时间
|
||||
ShopOrderReturn updateRefundStatus = new ShopOrderReturn();
|
||||
updateRefundStatus.setReturn_is_paid(1); // 0-退货未完成;1-退货完成
|
||||
updateRefundStatus.setReturn_finish_time(now);
|
||||
|
||||
QueryWrapper<ShopOrderReturn> updateWrapper = new QueryWrapper<>();
|
||||
updateWrapper.in("return_id", return_ids);
|
||||
if (!edit(updateRefundStatus, updateWrapper)) {
|
||||
logger.error("更新退货单退款状态失败!退货单列表: {}", return_ids);
|
||||
throw new ApiException(ResultCode.FAILED);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return true;
|
||||
@ -2195,7 +2268,7 @@ public class ShopOrderReturnServiceImpl extends BaseServiceImpl<ShopOrderReturnM
|
||||
}
|
||||
|
||||
/**
|
||||
* 对已存在部分退款的订单,进行剩余商品的全部退款
|
||||
* 对已存在部分退款的订单,进行剩余商品的全部退款(前提是未发货之前)
|
||||
* 该方法用于处理订单中部分商品已经申请退款后,对剩余商品进行整单退款的场景
|
||||
*
|
||||
* @param orderId 订单ID
|
||||
@ -2204,18 +2277,31 @@ public class ShopOrderReturnServiceImpl extends BaseServiceImpl<ShopOrderReturnM
|
||||
* @return CommonResult 退款申请结果
|
||||
*/
|
||||
@Override
|
||||
@Transactional
|
||||
public CommonResult addRemainingItems(String orderId, Boolean isSystemOpt, String remark) {
|
||||
ShopOrderInfo orderInfo = shopOrderInfoService.get(orderId);
|
||||
logger.info("开始处理订单剩余商品退款申请,订单ID: {}", orderId);
|
||||
|
||||
// 参数校验
|
||||
if (StrUtil.isBlank(orderId)) {
|
||||
logger.warn("订单剩余商品退款申请失败:订单ID为空");
|
||||
throw new ApiException(I18nUtil._("订单ID不能为空!"));
|
||||
}
|
||||
|
||||
// 获取订单信息
|
||||
ShopOrderInfo orderInfo = shopOrderInfoService.get(orderId);
|
||||
if (orderInfo == null) {
|
||||
logger.warn("订单剩余商品退款申请失败:订单信息不存在,订单ID: {}", orderId);
|
||||
throw new ApiException(I18nUtil._("此订单信息为空!"));
|
||||
}
|
||||
|
||||
if (orderInfo.getOrder_is_paid().equals(StateCode.ORDER_PAID_STATE_NO)) {
|
||||
logger.debug("获取订单信息成功,订单ID: {},订单状态: {}", orderId, orderInfo.getOrder_is_paid());
|
||||
|
||||
// 检查订单支付状态
|
||||
if (orderInfo.getOrder_is_paid() != null && StateCode.ORDER_PAID_STATE_NO == orderInfo.getOrder_is_paid().intValue()) {
|
||||
logger.warn("订单剩余商品退款申请失败:订单未付款,订单ID: {}", orderId);
|
||||
throw new ApiException(I18nUtil._("该订单未付款,无法申请!"));
|
||||
}
|
||||
|
||||
// 处理系统操作标识和备注信息
|
||||
if (isSystemOpt == null) {
|
||||
isSystemOpt = false;
|
||||
}
|
||||
@ -2225,27 +2311,38 @@ public class ShopOrderReturnServiceImpl extends BaseServiceImpl<ShopOrderReturnM
|
||||
}
|
||||
|
||||
// 获取订单中所有商品
|
||||
logger.debug("开始查询订单商品列表,订单ID: {}", orderId);
|
||||
QueryWrapper<ShopOrderItem> itemQueryWrapper = new QueryWrapper<>();
|
||||
itemQueryWrapper.eq("order_id", orderId);
|
||||
List<ShopOrderItem> allOrderItems = shopOrderItemService.find(itemQueryWrapper);
|
||||
|
||||
if (CollectionUtil.isEmpty(allOrderItems)) {
|
||||
logger.warn("订单剩余商品退款申请失败:订单商品表为空,订单ID: {}", orderId);
|
||||
throw new ApiException(I18nUtil._("订单商品表为空!"));
|
||||
}
|
||||
|
||||
logger.info("获取订单商品列表成功,共 {} 个商品,订单ID: {}", allOrderItems.size(), orderId);
|
||||
|
||||
// 获取已申请退款的商品ID列表
|
||||
Set<Long> refundedItemIds = getRefundedItemIds(orderId);
|
||||
logger.debug("开始查询已退款商品ID列表,订单ID: {}", orderId);
|
||||
Set<Long> refundedItemIds = getRefundFinishedItemIds(orderId);
|
||||
logger.debug("已退款商品数量: {},订单ID: {}", refundedItemIds.size(), orderId);
|
||||
|
||||
// 筛选出尚未申请退款的商品
|
||||
logger.debug("筛选未退款商品,订单ID: {}", orderId);
|
||||
List<ShopOrderItem> remainingItems = allOrderItems.stream()
|
||||
.filter(item -> !refundedItemIds.contains(item.getOrder_item_id()))
|
||||
.collect(Collectors.toList());
|
||||
|
||||
if (CollectionUtil.isEmpty(remainingItems)) {
|
||||
logger.warn("订单剩余商品退款申请失败:订单中所有商品均已申请退款,订单ID: {}", orderId);
|
||||
throw new ApiException(I18nUtil._("订单中所有商品均已申请退款!"));
|
||||
}
|
||||
|
||||
logger.info("筛选出未退款商品 {} 个,准备创建退款申请,订单ID: {}", remainingItems.size(), orderId);
|
||||
|
||||
// 生成退款单
|
||||
logger.debug("构建退款申请参数,订单ID: {}", orderId);
|
||||
OrderReturnInputVo orderReturnInputVo = new OrderReturnInputVo();
|
||||
orderReturnInputVo.setOrder_id(orderId);
|
||||
orderReturnInputVo.setReturn_tel("");
|
||||
@ -2254,6 +2351,7 @@ public class ShopOrderReturnServiceImpl extends BaseServiceImpl<ShopOrderReturnM
|
||||
orderReturnInputVo.setSystem_opear(isSystemOpt);
|
||||
|
||||
// 为剩余商品创建退款申请
|
||||
logger.debug("为 {} 个未退款商品创建退款明细,订单ID: {}", remainingItems.size(), orderId);
|
||||
for (ShopOrderItem orderItem : remainingItems) {
|
||||
OrderReturnItemInputVo returnItemInputVo = new OrderReturnItemInputVo();
|
||||
returnItemInputVo.setOrder_item_id(orderItem.getOrder_item_id());
|
||||
@ -2261,24 +2359,32 @@ public class ShopOrderReturnServiceImpl extends BaseServiceImpl<ShopOrderReturnM
|
||||
returnItemInputVo.setReturn_refund_amount(orderItem.getOrder_item_payment_amount());
|
||||
|
||||
orderReturnInputVo.getReturn_items().add(returnItemInputVo);
|
||||
logger.debug("添加退款商品明细,商品ID: {},数量: {},金额: {}",
|
||||
orderItem.getOrder_item_id(),
|
||||
orderItem.getOrder_item_quantity(),
|
||||
orderItem.getOrder_item_payment_amount());
|
||||
}
|
||||
|
||||
return addItem(orderReturnInputVo, true);
|
||||
logger.info("退款申请参数构建完成,开始提交退款申请,订单ID: {},addItem 请求参数:{}", orderId, JSONUtil.toJsonStr(orderReturnInputVo));
|
||||
CommonResult result = addItem(orderReturnInputVo, true);
|
||||
logger.info("订单剩余商品退款申请处理完成,订单ID: {},处理结果: {}", orderId, JSONUtil.toJsonStr(result));
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取订单中已申请退款的商品ID列表
|
||||
* 获取订单中已完成退款的商品ID列表
|
||||
*
|
||||
* @param orderId 订单ID
|
||||
* @return Set<Long> 已申请退款的商品ID集合
|
||||
*/
|
||||
private Set<Long> getRefundedItemIds(String orderId) {
|
||||
private Set<Long> getRefundFinishedItemIds(String orderId) {
|
||||
Set<Long> refundedItemIds = new HashSet<>();
|
||||
|
||||
// 查询该订单所有未取消的退款单
|
||||
QueryWrapper<ShopOrderReturn> returnQueryWrapper = new QueryWrapper<>();
|
||||
returnQueryWrapper.eq("order_id", orderId)
|
||||
.ne("return_state_id", StateCode.RETURN_PROCESS_CANCEL);
|
||||
.eq("return_state_id", StateCode.RETURN_PROCESS_FINISH);
|
||||
List<ShopOrderReturn> shopOrderReturns = find(returnQueryWrapper);
|
||||
|
||||
if (CollectionUtil.isNotEmpty(shopOrderReturns)) {
|
||||
|
||||
@ -826,37 +826,37 @@ public class SFExpressApiServiceImpl implements SFExpressApiService {
|
||||
public ThirdApiRes receiveCancelOrderNotify(String jsonData, String sign) {
|
||||
// 参数校验
|
||||
if (StrUtil.isBlank(jsonData) || StrUtil.isBlank(sign)) {
|
||||
logger.warn("[顺丰订单取消回调] 缺少必要参数: jsonData或sign为空");
|
||||
logger.warn("[顺丰订单取消回调通知] 缺少必要参数: jsonData或sign为空");
|
||||
return new ThirdApiRes().fail(1003, "缺少必要参数!");
|
||||
}
|
||||
|
||||
// 签名校验
|
||||
if (!checkOpenSign(sign, jsonData)) {
|
||||
logger.warn("[顺丰订单取消回调] 请求签名sign校验失败");
|
||||
logger.warn("[顺丰订单取消回调通知] 请求签名sign校验失败");
|
||||
return new ThirdApiRes().fail(2002, "请求签名sign校验失败!");
|
||||
}
|
||||
|
||||
logger.info("[顺丰订单取消回调] 接收回调数据: {}", jsonData);
|
||||
logger.info("[顺丰订单取消回调通知] 接收回调数据: {}", jsonData);
|
||||
|
||||
try {
|
||||
// 解析并更新顺丰同城订单状态
|
||||
ShopStoreSfOrder shopStoreSfOrder = toShopStoreSfOrder(jsonData);
|
||||
if (shopStoreSfOrder == null) {
|
||||
logger.error("[顺丰订单取消回调] 解析订单数据失败: jsonData={}", jsonData);
|
||||
logger.error("[顺丰订单取消回调通知] 解析订单数据失败: jsonData={}", jsonData);
|
||||
return new ThirdApiRes().fail(-1, "订单数据解析失败!");
|
||||
}
|
||||
|
||||
String shopOrderId = shopStoreSfOrder.getShop_order_id();
|
||||
String sfOrderId = shopStoreSfOrder.getSf_order_id();
|
||||
|
||||
logger.info("[顺丰订单取消回调] 处理订单取消: shopOrderId={} sfOrderId={}", shopOrderId, sfOrderId);
|
||||
logger.info("[顺丰订单取消回调通知] 处理订单取消: shopOrderId={} sfOrderId={}", shopOrderId, sfOrderId);
|
||||
|
||||
// 判断订单的状态,是否已经取消了?已取消,不再执行
|
||||
ShopStoreSfOrder shopStoreSfOrderExist = shopStoreSfOrderService.getBySfOrderId(sfOrderId);
|
||||
if (shopStoreSfOrderExist != null && shopStoreSfOrderExist.getOrder_status() != null
|
||||
&& (ObjectUtil.equal(shopStoreSfOrderExist.getOrder_status(), StateCode.SF_ORDER_STATUS_CANCELED) ||
|
||||
ObjectUtil.equal(shopStoreSfOrderExist.getOrder_status(), StateCode.SF_ORDER_STATUS_CANCELING))) {
|
||||
logger.info("[顺丰订单取消回调] 订单已处于取消状态,无需重复处理: sfOrderId={} status={}",
|
||||
logger.info("[顺丰订单取消回调通知] 订单已处于取消状态,无需重复处理: sfOrderId={} status={}",
|
||||
sfOrderId, shopStoreSfOrderExist.getOrder_status());
|
||||
return new ThirdApiRes().success("success");
|
||||
}
|
||||
@ -864,18 +864,18 @@ public class SFExpressApiServiceImpl implements SFExpressApiService {
|
||||
// 更新顺丰订单状态
|
||||
Boolean success = shopStoreSfOrderService.updateShopStoreSfOrderStatus(shopStoreSfOrder);
|
||||
if (!success) {
|
||||
logger.error("[顺丰订单取消回调] 更新顺丰订单状态失败: sfOrderId={}", sfOrderId);
|
||||
logger.error("[顺丰订单取消回调通知] 更新顺丰订单状态失败: sfOrderId={}", sfOrderId);
|
||||
return new ThirdApiRes().fail(-1, "状态处理失败!");
|
||||
}
|
||||
logger.debug("[顺丰订单取消回调] 顺丰订单状态更新成功: sfOrderId={}", sfOrderId);
|
||||
logger.debug("[顺丰订单取消回调通知] 顺丰订单状态更新成功: sfOrderId={}", sfOrderId);
|
||||
|
||||
// 重要:更改商城订单状态为:已取消,注意事务问题
|
||||
success = shopOrderReturnService.sfExpressExpiredForceRefund(shopOrderId);
|
||||
if (!success) {
|
||||
logger.error("[顺丰订单取消回调] 取消商城订单业务处理失败: shopOrderId={}", shopOrderId);
|
||||
logger.error("[顺丰订单取消回调通知] 取消商城订单业务处理失败: shopOrderId={}", shopOrderId);
|
||||
return new ThirdApiRes().fail(-1, "取消订单业务处理失败!");
|
||||
}
|
||||
logger.debug("[顺丰订单取消回调] 商城订单取消处理成功: shopOrderId={}", shopOrderId);
|
||||
logger.debug("[顺丰订单取消回调通知] 商城订单取消处理成功: shopOrderId={}", shopOrderId);
|
||||
|
||||
// 获取顺丰同城的物流轨迹
|
||||
Map<String, Object> params = new HashMap<>();
|
||||
@ -885,7 +885,7 @@ public class SFExpressApiServiceImpl implements SFExpressApiService {
|
||||
JSONObject result = JSONUtil.parseObj(feedRes.getResult());
|
||||
if (result != null && result.get("feed") != null) {
|
||||
shopStoreSfOrder.setFeed(JSONUtil.toJsonStr(result.get("feed")));
|
||||
logger.debug("[顺丰订单取消回调] 获取物流轨迹成功: sfOrderId={}", sfOrderId);
|
||||
logger.debug("[顺丰订单取消回调通知] 获取物流轨迹成功: sfOrderId={}", sfOrderId);
|
||||
}
|
||||
}
|
||||
|
||||
@ -894,12 +894,11 @@ public class SFExpressApiServiceImpl implements SFExpressApiService {
|
||||
payload.put("category", CommonConstant.PUSH_MSG_CATE_MCH_ORDER_DETAIL);
|
||||
payload.put("orderId", shopOrderId);
|
||||
pushMessageService.noticeMerchantEmployeeOrderAction(null, shopOrderId, "您有一笔取消订单", "您有一笔取消订单[" + shopOrderId + "],请及时处理。", payload);
|
||||
logger.info("[顺丰订单取消回调] 推送消息完成: shopOrderId={}", shopOrderId);
|
||||
|
||||
logger.info("[顺丰订单取消回调] 处理完成: shopOrderId={} sfOrderId={}", shopOrderId, sfOrderId);
|
||||
|
||||
logger.info("[顺丰订单取消回调通知] 处理完成: shopOrderId={} sfOrderId={}", shopOrderId, sfOrderId);
|
||||
return new ThirdApiRes().success("success");
|
||||
} catch (Exception e) {
|
||||
logger.error("[顺丰订单取消回调] 处理过程中发生异常", e);
|
||||
logger.error("[顺丰订单取消回调通知] 处理过程中发生异常", e);
|
||||
return new ThirdApiRes().fail(-1, "系统处理异常: " + e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
@ -2375,7 +2375,7 @@ public class ShopStoreBaseServiceImpl extends BaseServiceImpl<ShopStoreBaseMappe
|
||||
// 打包费
|
||||
BigDecimal packingFee = Convert.toBigDecimal(getParameter("packing_fee"));
|
||||
if (packingFee == null || packingFee.compareTo(BigDecimal.ZERO) <= 0) {
|
||||
base.setPacking_fee(BigDecimal.ZERO);
|
||||
packingFee = BigDecimal.ZERO;
|
||||
}
|
||||
|
||||
if (packingFee.compareTo(new BigDecimal("10")) > 0) {
|
||||
@ -2385,9 +2385,11 @@ public class ShopStoreBaseServiceImpl extends BaseServiceImpl<ShopStoreBaseMappe
|
||||
|
||||
Integer ringtoneIsEnable = Convert.toInt(getParameter("ringtone_is_enable"));
|
||||
if (ringtoneIsEnable == null || ringtoneIsEnable <= 0) {
|
||||
base.setRingtone_is_enable(CommonConstant.Enable);
|
||||
ringtoneIsEnable = CommonConstant.Enable;
|
||||
}
|
||||
|
||||
base.setRingtone_is_enable(ringtoneIsEnable);
|
||||
|
||||
|
||||
// 百度坐标系BD09经纬度 转出 火星坐标系GCJ02经纬度 (因为数据库保存的经纬度统一是GCJ02经纬度,所以需要转换 )
|
||||
base = bd09ToGcj02Gps(base);
|
||||
@ -2543,12 +2545,7 @@ public class ShopStoreBaseServiceImpl extends BaseServiceImpl<ShopStoreBaseMappe
|
||||
// 打包费
|
||||
BigDecimal packingFee = Convert.toBigDecimal(getParameter("packing_fee"));
|
||||
if (packingFee == null || packingFee.compareTo(BigDecimal.ZERO) <= 0) {
|
||||
base.setPacking_fee(BigDecimal.ZERO);
|
||||
}
|
||||
|
||||
Integer ringtoneIsEnable = Convert.toInt(getParameter("ringtone_is_enable"));
|
||||
if (ringtoneIsEnable == null || ringtoneIsEnable <= 0) {
|
||||
base.setRingtone_is_enable(CommonConstant.Enable);
|
||||
packingFee = BigDecimal.ZERO;
|
||||
}
|
||||
|
||||
if (packingFee.compareTo(new BigDecimal("10")) > 0) {
|
||||
@ -2556,6 +2553,13 @@ public class ShopStoreBaseServiceImpl extends BaseServiceImpl<ShopStoreBaseMappe
|
||||
}
|
||||
base.setPacking_fee(packingFee);
|
||||
|
||||
Integer ringtoneIsEnable = Convert.toInt(getParameter("ringtone_is_enable"));
|
||||
if (ringtoneIsEnable == null || ringtoneIsEnable <= 0) {
|
||||
ringtoneIsEnable = CommonConstant.Enable;
|
||||
}
|
||||
|
||||
base.setRingtone_is_enable(ringtoneIsEnable);
|
||||
|
||||
// 百度坐标系BD09经纬度 转出 火星坐标系GCJ02经纬度 (因为数据库保存的经纬度统一是GCJ02经纬度,所以需要转换 )
|
||||
base = bd09ToGcj02Gps(base);
|
||||
|
||||
|
||||
@ -45,7 +45,6 @@ import java.io.UnsupportedEncodingException;
|
||||
import java.net.URLEncoder;
|
||||
import java.util.*;
|
||||
//import java.util.concurrent.TimeUnit;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
|
||||
@ -75,8 +74,8 @@ public class SnsUserMessageServiceImpl extends BaseServiceImpl<SnsUserMessageMap
|
||||
private SnsUserFriendService snsUserFriendService;
|
||||
@Autowired
|
||||
private ImService imService;
|
||||
@Autowired
|
||||
private RedisTemplate<String, Object> redisTemplate;
|
||||
// @Autowired
|
||||
// private RedisTemplate<String, Object> redisTemplate;
|
||||
|
||||
@Override
|
||||
public Map getMsgCount() {
|
||||
@ -88,30 +87,22 @@ public class SnsUserMessageServiceImpl extends BaseServiceImpl<SnsUserMessageMap
|
||||
}
|
||||
|
||||
Integer userId = user.getId();
|
||||
String cacheKey = "sns:user:message:unread:" + userId;
|
||||
String counterKey = "sns:user:message:unread:counter:" + userId;
|
||||
// String cacheKey = "sns:user:message:unread:" + userId;
|
||||
|
||||
// 尝试从Redis缓存中获取数据
|
||||
Map cachedResult = (Map) redisTemplate.opsForValue().get(cacheKey);
|
||||
if (cachedResult != null) {
|
||||
return cachedResult;
|
||||
}
|
||||
// // 尝试从Redis缓存中获取数据
|
||||
// Map cachedResult = (Map) redisTemplate.opsForValue().get(cacheKey);
|
||||
// if (cachedResult != null) {
|
||||
// return cachedResult;
|
||||
// }
|
||||
|
||||
// 使用计数器方式提高性能,避免每次都count数据库
|
||||
Long unreadCount = redisTemplate.opsForValue().increment(counterKey, 0);
|
||||
if (unreadCount == null) {
|
||||
// 如果计数器不存在,则从数据库查询并初始化计数器
|
||||
QueryWrapper<SnsUserMessage> queryWrapper = new QueryWrapper<>();
|
||||
queryWrapper.eq("user_id", userId).eq("message_kind", 2).eq("message_is_read", 0);
|
||||
unreadCount = count(queryWrapper);
|
||||
// 设置计数器,过期时间1小时
|
||||
redisTemplate.opsForValue().set(counterKey, unreadCount, 3600, TimeUnit.SECONDS);
|
||||
}
|
||||
QueryWrapper<SnsUserMessage> queryWrapper = new QueryWrapper<>();
|
||||
queryWrapper.eq("user_id", userId).eq("message_kind", 2).eq("message_is_read", 0);
|
||||
long num = count(queryWrapper);
|
||||
|
||||
rs.put("num", unreadCount);
|
||||
rs.put("num", num);
|
||||
|
||||
// 构造最后一个用户聊天网址
|
||||
if (unreadCount > 0) {
|
||||
if (num > 0) {
|
||||
QueryWrapper<SnsUserMessage> messageQuery = new QueryWrapper<>();
|
||||
messageQuery.orderByAsc("message_is_read").orderByDesc("message_time")
|
||||
.eq("user_id", userId).eq("message_is_read", 0).eq("message_kind", 2);
|
||||
@ -132,8 +123,8 @@ public class SnsUserMessageServiceImpl extends BaseServiceImpl<SnsUserMessageMap
|
||||
}
|
||||
}
|
||||
|
||||
// 将结果缓存到Redis,缓存5秒以提高高并发下的性能
|
||||
redisTemplate.opsForValue().set(cacheKey, rs, 5, TimeUnit.SECONDS);
|
||||
// // 将结果缓存到Redis,缓存10秒
|
||||
// redisTemplate.opsForValue().set(cacheKey, rs, 45, TimeUnit.SECONDS);
|
||||
|
||||
return rs;
|
||||
}
|
||||
@ -329,10 +320,13 @@ public class SnsUserMessageServiceImpl extends BaseServiceImpl<SnsUserMessageMap
|
||||
}
|
||||
|
||||
/**
|
||||
* 重写setRead方法,在设置消息为已读时更新未读计数器
|
||||
* 设置为已读
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public boolean setRead() {
|
||||
|
||||
// 权限判断
|
||||
UserDto user = ContextUtil.getCurrentUser();
|
||||
if (user == null) {
|
||||
@ -352,29 +346,10 @@ public class SnsUserMessageServiceImpl extends BaseServiceImpl<SnsUserMessageMap
|
||||
if (CheckUtil.isNotEmpty(user_other_id)) {
|
||||
queryWrapper.eq("user_other_id", user_other_id);
|
||||
}
|
||||
|
||||
// 查询需要更新的消息数量
|
||||
List<SnsUserMessage> messagesToUpdate = find(queryWrapper);
|
||||
long unreadToUpdate = messagesToUpdate.stream()
|
||||
.filter(m -> m.getMessage_is_read() == 0)
|
||||
.count();
|
||||
|
||||
SnsUserMessage userMessage = new SnsUserMessage();
|
||||
userMessage.setMessage_is_read(1);
|
||||
boolean result = saveOrUpdate(userMessage, queryWrapper);
|
||||
|
||||
// 更新未读计数器和缓存
|
||||
if (result && unreadToUpdate > 0) {
|
||||
String counterKey = "sns:user:message:unread:counter:" + user_id;
|
||||
String cacheKey = "sns:user:message:unread:" + user_id;
|
||||
|
||||
// 减少计数器
|
||||
redisTemplate.opsForValue().increment(counterKey, -unreadToUpdate);
|
||||
// 删除缓存,下次请求会重新生成
|
||||
redisTemplate.delete(cacheKey);
|
||||
}
|
||||
|
||||
return result;
|
||||
saveOrUpdate(userMessage, queryWrapper);
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -737,11 +712,14 @@ public class SnsUserMessageServiceImpl extends BaseServiceImpl<SnsUserMessageMap
|
||||
}
|
||||
|
||||
/**
|
||||
* 重写addMessage方法,在添加新消息时更新未读计数器
|
||||
* 添加短消息
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
@Transactional
|
||||
public Map addMessage() {
|
||||
|
||||
UserDto user = ContextUtil.getCurrentUser();
|
||||
if (user == null) {
|
||||
throw new ApiException(ResultCode.NEED_LOGIN);
|
||||
@ -840,18 +818,8 @@ public class SnsUserMessageServiceImpl extends BaseServiceImpl<SnsUserMessageMap
|
||||
if (!saveOrUpdate(other)) {
|
||||
throw new ApiException(I18nUtil._("保存收件箱失败!data=") + other);
|
||||
}
|
||||
|
||||
result.put("message_id", data.getMessage_id());
|
||||
result.put("message_other_id", other.getMessage_id());
|
||||
|
||||
// 新消息添加后,更新接收者的未读计数器和缓存
|
||||
String counterKey = "sns:user:message:unread:counter:" + user_other_row.getUser_id();
|
||||
String cacheKey = "sns:user:message:unread:" + user_other_row.getUser_id();
|
||||
|
||||
// 增加计数器
|
||||
redisTemplate.opsForValue().increment(counterKey, 1);
|
||||
// 删除缓存,下次请求会重新生成
|
||||
redisTemplate.delete(cacheKey);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
3
pom.xml
3
pom.xml
@ -560,9 +560,6 @@
|
||||
<baseImage>openjdk:8-jre</baseImage>
|
||||
|
||||
<!--定义容器启动命令,注意不能换行-->
|
||||
<!-- <entryPoint>["java", "-jar", "-Xms256m", "-Xmx512m", "-XX:MetaspaceSize=256m", "-XX:MaxMetaspaceSize=256m", "-XX:+UseContainerSupport", "-XX:MaxRAMPercentage=60.0", "-XX:+UseSerialGC", "-XX:MinHeapFreeRatio=40", "-XX:MaxHeapFreeRatio=60", "-XX:+PrintGCDetails", "-XX:+PrintGCDateStamps", "-Xloggc:./gc.log", "-XX:+UseGCLogFileRotation", "-XX:NumberOfGCLogFiles=5", "-XX:GCLogFileSize=10M", "-Dspring.profiles.active=${spring.profile}", "-Duser.timezone=Asia/Shanghai", "/${project.build.finalName}.jar"]-->
|
||||
<!-- </entryPoint>-->
|
||||
<!--定义容器启动命令,注意不能换行-->
|
||||
<entryPoint>["sh", "-c", "mkdir -p /tmp /app/temp /root/nacos/naming/public && chmod -R 777 /tmp /app/temp /root/nacos && java -Djava.io.tmpdir=/app/temp -Dnacos.naming.cache.dir=/root/nacos/naming -jar -Xms256m -Xmx512m -XX:MetaspaceSize=256m -XX:MaxMetaspaceSize=256m -XX:+UseContainerSupport -XX:MaxRAMPercentage=60.0 -XX:+UseSerialGC -XX:MinHeapFreeRatio=40 -XX:MaxHeapFreeRatio=60 -XX:+PrintGCDetails -XX:+PrintGCDateStamps -Xloggc:./gc.log -XX:+UseGCLogFileRotation -XX:NumberOfGCLogFiles=5 -XX:GCLogFileSize=10M -Dspring.profiles.active=${spring.profile} -Duser.timezone=Asia/Shanghai /${project.build.finalName}.jar"]
|
||||
</entryPoint>
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user