订单打印增加 标题后面加规格

This commit is contained in:
Jack 2025-10-09 23:31:30 +08:00
parent 4ff33b938d
commit 8b2a127ce3
5 changed files with 195 additions and 15 deletions

View File

@ -61,12 +61,12 @@ public class LklSeparateDTO {
// 测试基于可分账金额的分账算法正常情况
System.out.println("\n=== 基于可分账金额的分账算法测试(正常情况) ===");
LklSeparateDTO dto2 = new LklSeparateDTO();
dto2.setTotalSeparateAmount(900); // 分账总额 1000分
dto2.setTotalSeparateAmount(1000); // 分账总额 1000分
dto2.setShippingFee(500); // 配送费 100分
// dto2.setRefCanSeparateAmount(null);
dto2.setLklRatio(new BigDecimal("0.0025")); // 拉卡拉分账比例 0.0025
dto2.setMchRatio(new BigDecimal("0.95")); // 商家分账比例 0.857 (会产生小数)
dto2.setPlatRatio(new BigDecimal("0.01")); // 平台分账比例 0.01
dto2.setPlatRatio(new BigDecimal("0.05")); // 平台分账比例 0.01
// 不设置一级和二级代理商分账比例测试不参与分账的情况
// dto2.setAgent1stRatio(new BigDecimal("0.11")); // 一级代理商分账比例 0.023 (会产生小数)
// dto2.setAgent2ndRatio(new BigDecimal("0.04")); // 二级代理商分账比例 0.031 (会产生小数)

View File

@ -1,6 +1,7 @@
package com.suisung.mall.pay.controller.admin;
import cn.hutool.core.util.NumberUtil;
import cn.hutool.json.JSONArray;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.suisung.mall.common.api.CommonResult;
import com.suisung.mall.common.modules.order.ShopOrderReturn;
@ -17,6 +18,7 @@ import io.swagger.annotations.ApiOperation;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.util.Pair;
import org.springframework.web.bind.annotation.*;
import javax.servlet.http.HttpServletRequest;
@ -56,6 +58,8 @@ public class PayController {
private PayPlantformResourceService payPlantformResourceService;
@Autowired
private PayUserPayService payUserPayService;
@Autowired
private LakalaPayService lakalaPayService;
@ApiOperation(value = "根据user_id 删除门店顾客关系数据", notes = "根据user_id 删除门店顾客关系数据")
@RequestMapping(value = "/deleteUserChainByUid", method = RequestMethod.POST)
@ -410,8 +414,22 @@ public class PayController {
@ApiOperation(value = "批量保存", notes = "用户资源表")
@RequestMapping(value = "/saveBatchPayUserResources", method = {RequestMethod.POST})
public ThirdApiRes saveBatchPayUserResources(@RequestBody List<PayUserResource> payUserResourceList) {
return payUserPayService.saveBatchPayUserResources(payUserResourceList);
return payUserPayService.saveBatchPayUserResources(payUserResourceList);
}
/**
* 退款通知
*/
@ApiOperation(value = "【测试】平台强制到拉卡拉退款", notes = "平台强制到拉卡拉退款")
@RequestMapping(value = "/lkl/refund", method = {RequestMethod.POST})
public CommonResult refundFromLakala(HttpServletRequest request, @RequestBody JSONArray returnJsonArray) {
Pair<Boolean, String> pair = lakalaPayService.innerLklRefundForDemo(request, returnJsonArray);
if (pair.getFirst()) {
return CommonResult.success(pair.getSecond());
}
return CommonResult.failed(pair.getSecond());
}
}

View File

@ -8,9 +8,12 @@
package com.suisung.mall.pay.service;
import cn.hutool.json.JSONArray;
import cn.hutool.json.JSONObject;
import org.springframework.data.util.Pair;
import javax.servlet.http.HttpServletRequest;
public interface LakalaPayService {
Boolean initLKLSDK();
@ -70,6 +73,28 @@ public interface LakalaPayService {
*/
Pair<Boolean, String> innerLklRefund(Integer storeId, String outTradeNo, String originTradeNo, String refundAmount, String refundReason, String lklMerchantNo, String lklTermNo);
/**
* 执行内部拉卡拉交易退款(测试)
* 参考地址https://o.lakala.com/#/home/document/detail?id=113
* 参数示例
* [
* {
* "sub_trade_no": "20251009110113130266250070712668",
* "merchant_no": "822584059990FYP",
* "amount": "500",
* "settle_type": "0",
* "sub_log_no": "66250070712668",
* "out_sub_trade_no": "DF_DD_20251009_2",
* "term_no": "N5811590"
* }
* ]
*
* @param returnJsonArray 退款信息数组
* @return Pair<Boolean, String>包含退款是否成功以及消息
*/
Pair<Boolean, String> innerLklRefundForDemo(HttpServletRequest request, JSONArray returnJsonArray);
/**
* 文件上传
* 参考https://o.lakala.com/#/home/document/detail?id=90

View File

@ -22,6 +22,7 @@ import com.lkl.laop.sdk.request.V2MmsOpenApiUploadFileRequest;
import com.lkl.laop.sdk.request.V3LabsRelationRefundRequest;
import com.lkl.laop.sdk.request.model.V3LabsTradeLocationInfo;
import com.suisung.mall.common.constant.CommonConstant;
import com.suisung.mall.common.domain.UserDto;
import com.suisung.mall.common.exception.ApiException;
import com.suisung.mall.common.feignService.ShopService;
import com.suisung.mall.common.modules.store.ShopStoreBase;
@ -44,6 +45,8 @@ import org.springframework.web.context.request.ServletRequestAttributes;
import javax.servlet.http.HttpServletRequest;
import java.time.LocalDateTime;
import static com.suisung.mall.common.utils.ContextUtil.getCurrentUser;
@Slf4j
@Service
@ -634,6 +637,138 @@ public class LakalaPayServiceImpl implements LakalaPayService {
}
/**
* 执行内部拉卡拉交易退款
* 参考地址https://o.lakala.com/#/home/document/detail?id=113
* 参数示例
* [
* {
* "sub_trade_no": "20251009110113130266250070712668",
* "merchant_no": "822584059990FYP",
* "amount": "500",
* "settle_type": "0",
* "sub_log_no": "66250070712668",
* "out_sub_trade_no": "DF_DD_20251009_2",
* "term_no": "N5811590"
* }
* ]
*
* @param returnJsonArray 退款信息数组
* @return Pair<Boolean, String>包含退款是否成功以及消息
*/
@Override
public Pair<Boolean, String> innerLklRefundForDemo(HttpServletRequest request, JSONArray returnJsonArray) {
try {
log.info("[拉卡拉退款Demo] 开始执行拉卡拉内部退款,退款订单数: {}",
returnJsonArray != null ? returnJsonArray.size() : 0);
UserDto userDto = getCurrentUser();
if (userDto == null || !userDto.isAdmin()) {
log.error("[拉卡拉退款Demo] 非管理员用户尝试执行退款, userId={}",
userDto != null ? userDto.getId() : "unknown");
return Pair.of(false, I18nUtil._("非管理员用户尝试执行拉卡拉内部退款,请勿非法操作!"));
}
if (returnJsonArray == null || returnJsonArray.isEmpty()) {
log.error("[拉卡拉退款Demo] 退款信息为空");
return Pair.of(false, I18nUtil._("退款信息为空,退款失败!"));
}
ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
if (attributes == null) {
log.error("[拉卡拉退款Demo] 无法获取请求上下文");
return Pair.of(false, I18nUtil._("系统异常,无法获取请求信息!"));
}
String requestIp = IpKit.getRealIp(request);
if (StrUtil.isBlank(requestIp)) {
requestIp = request.getRemoteAddr();
}
String refundReason = "系统触发退款";
int successCount = 0;
int totalCount = returnJsonArray.size();
// 初始化拉卡拉SDK
initLKLSDK();
for (int i = 0; i < returnJsonArray.size(); i++) {
JSONObject returnJsonObject = returnJsonArray.getJSONObject(i);
// 参数提取
String outTradeNo = returnJsonObject.getStr("out_sub_trade_no");
String originTradeNo = returnJsonObject.getStr("sub_trade_no");
String refundAmount = returnJsonObject.getStr("amount");
String lklMerchantNo = returnJsonObject.getStr("merchant_no");
String lklTermNo = returnJsonObject.getStr("term_no");
// 参数校验
if (StrUtil.hasBlank(outTradeNo, originTradeNo, refundAmount, lklMerchantNo, lklTermNo)) {
log.warn("[拉卡拉退款Demo] 第{}笔退款参数不完整, 跳过处理", i + 1);
continue;
}
// 金额格式校验
if (!refundAmount.matches("\\d+") || Integer.parseInt(refundAmount) <= 0) {
log.warn("[拉卡拉退款Demo] 第{}笔退款金额格式不正确: {}, 跳过处理", i + 1, refundAmount);
continue;
}
// 构造退款请求
V3LabsRelationRefundRequest refundRequest = new V3LabsRelationRefundRequest();
refundRequest.setOutTradeNo(outTradeNo);
refundRequest.setOriginTradeNo(originTradeNo);
refundRequest.setMerchantNo(lklMerchantNo);
refundRequest.setTermNo(lklTermNo);
refundRequest.setRefundAmount(refundAmount);
refundRequest.setRefundReason(refundReason);
refundRequest.setLocationInfo(new V3LabsTradeLocationInfo(requestIp, null, ""));
// 发送请求
String responseString = LKLSDK.httpPost(refundRequest);
// 处理响应
if (StrUtil.isBlank(responseString)) {
log.error("[拉卡拉退款Demo] 第{}笔退款无响应, outTradeNo={}", i + 1, outTradeNo);
continue;
}
JSONObject lakalaResponseJson = JSONUtil.parseObj(responseString);
if (lakalaResponseJson == null) {
log.error("[拉卡拉退款Demo] 第{}笔退款响应解析失败, outTradeNo={}", i + 1, outTradeNo);
continue;
}
String responseCode = lakalaResponseJson.getStr("code");
if (StrUtil.isBlank(responseCode)) {
log.error("[拉卡拉退款Demo] 第{}笔退款响应码为空, outTradeNo={}", i + 1, outTradeNo);
continue;
}
if (!"BBS00000".equals(responseCode)) {
String errorMessage = lakalaResponseJson.getStr("msg", "未知错误");
log.error("[拉卡拉退款Demo] 第{}笔退款失败, 响应码: {}, 错误信息: {}, outTradeNo={}",
i + 1, responseCode, errorMessage, outTradeNo);
continue;
}
successCount++;
log.info("[拉卡拉退款Demo] 第{}笔退款成功, outTradeNo={}", i + 1, outTradeNo);
}
log.info("[拉卡拉退款Demo] 退款处理完成,总笔数: {}, 成功笔数: {}", totalCount, successCount);
return Pair.of(true, I18nUtil._("退款成功!") + successCount + "笔/" + totalCount + "");
} catch (SDKException e) {
log.error("[拉卡拉退款Demo] SDK异常", e);
return Pair.of(false, I18nUtil._("拉卡拉退款SDK异常退款失败") + e.getMessage());
} catch (Exception e) {
log.error("[拉卡拉退款Demo] 未知异常", e);
return Pair.of(false, I18nUtil._("拉卡拉退款发生未知异常,退款失败!") + e.getMessage());
}
}
/**
* 文件上传
* 参考https://o.lakala.com/#/home/document/detail?id=90

View File

@ -1278,6 +1278,7 @@ public class ShopOrderReturnServiceImpl extends BaseServiceImpl<ShopOrderReturnM
if (!edit(shopOrderReturn)) {
throw new ApiException(I18nUtil._("修改订单信息失败!"));
}
if (!processReviewList(return_ids, orderReturns, StateCode.RETURN_PROCESS_CHECK, StateCode.RETURN_PROCESS_FINISH)) {
throw new ApiException(I18nUtil._("审核失败!"));
}
@ -1372,6 +1373,9 @@ public class ShopOrderReturnServiceImpl extends BaseServiceImpl<ShopOrderReturnM
*/
@Override
public boolean processReviewList(List<String> return_ids, List<ShopOrderReturn> return_rows, Integer return_curr_state_id, Integer return_next_state_id) {
logger.info("退款审核 processReviewList 参数return_ids {},return_rows {},return_curr_state_id {},return_next_state_id {}",
return_ids, return_rows, return_curr_state_id, return_next_state_id);
if (CollUtil.isEmpty(return_ids)) {
throw new ApiException(I18nUtil._("请选择需要审核的退单!"));
}
@ -1415,6 +1419,7 @@ public class ShopOrderReturnServiceImpl extends BaseServiceImpl<ShopOrderReturnM
}
}
logger.info("退款审核 processReviewList 符合审核条件的退单:{}", review_ids);
if (CollUtil.isEmpty(review_ids)) {
throw new ApiException(I18nUtil._("无符合审核条件的退单!"));
}
@ -1530,7 +1535,7 @@ public class ShopOrderReturnServiceImpl extends BaseServiceImpl<ShopOrderReturnM
Integer return_is_shipping_fee = return_row.getReturn_is_shipping_fee();
// 处理非退运费单的情况
if (CheckUtil.isEmpty(return_is_shipping_fee) || return_is_shipping_fee != 1) {
if (CheckUtil.isEmpty(return_is_shipping_fee) || !CommonConstant.Enable.equals(return_is_shipping_fee)) {
// 所有单品退款额度
QueryWrapper<ShopOrderItem> orderItemQueryWrapper = new QueryWrapper<>();
orderItemQueryWrapper.eq("order_id", order_id);
@ -1589,7 +1594,7 @@ public class ShopOrderReturnServiceImpl extends BaseServiceImpl<ShopOrderReturnM
// 当前订单状态
Integer order_state_id = info_row.getOrder_state_id();
// 没有发货没有完成订单之前允许取消订单和退运费
// 没有发货没有完成订单之前允许取消订单和退运费(这个存在争议)
List<Integer> forbiddenStates = Arrays.asList(
StateCode.ORDER_STATE_SHIPPED,
StateCode.ORDER_STATE_RECEIVED,
@ -1599,7 +1604,6 @@ public class ShopOrderReturnServiceImpl extends BaseServiceImpl<ShopOrderReturnM
// shopOrderBaseService.cancel(order_id, info_row, false);
logger.info("处理运费和打包费事宜:{}", order_id);
ShopOrderData order_data_row = shopOrderDataService.get(order_id);
// 如果有打包费最后的退款订单的退款金额加上 打包费
@ -1612,10 +1616,9 @@ public class ShopOrderReturnServiceImpl extends BaseServiceImpl<ShopOrderReturnM
order_data_row.getPacking_fee());
// 最后一个退款订单如果有打包费加上打包费
return_row.setReturn_refund_amount(orderRefundAmountAddFee);
logger.debug("已添加打包费到退款金额订单ID: {}", order_id);
logger.debug("最后一个商品,已添加打包费到退款金额订单ID: {}", order_id);
}
// 有运费的重新生成一个运费退单
if (order_data_row != null &&
order_data_row.getOrder_shipping_fee_inner() != null &&
@ -1644,7 +1647,7 @@ public class ShopOrderReturnServiceImpl extends BaseServiceImpl<ShopOrderReturnM
return_order_shipping_fee_row.setBuyer_user_id(buyer_user_id);
return_order_shipping_fee_row.setReturn_is_shipping_fee(1); //退货类型(BOOL): 0-退款单;1-退运费单
return_order_shipping_fee_row.setReturn_reason_id(0);
return_order_shipping_fee_row.setReturn_buyer_message(I18nUtil._("已退配送费"));
return_order_shipping_fee_row.setReturn_buyer_message(I18nUtil._("订单(配送费)退款"));
return_order_shipping_fee_row.setStore_id(storeId);
return_order_shipping_fee_row.setReturn_refund_point(NumberUtil.min(return_refund_point, orderShippingFeeInner));
return_order_shipping_fee_row.setReturn_add_time(now); // 添加时间
@ -1658,10 +1661,10 @@ public class ShopOrderReturnServiceImpl extends BaseServiceImpl<ShopOrderReturnM
// update 2025-07-24
return_order_shipping_fee_row.setReturn_flag(0); // 退货标识(BOOL): 0-正常退货;1-退货换货
return_order_shipping_fee_row.setReturn_store_message(I18nUtil._("退运费"));
return_order_shipping_fee_row.setReturn_store_message(I18nUtil._("订单(配送费)退款"));
return_order_shipping_fee_row.setReturn_finish_time(now);
return_order_shipping_fee_row.setReturn_state_id(StateCode.RETURN_PROCESS_FINISH);
return_order_shipping_fee_row.setReturn_is_paid(0);// 退款完成
return_order_shipping_fee_row.setReturn_is_paid(1);// 退款完成
return_order_shipping_fee_row.setReturn_channel_code("lakala");
return_order_shipping_fee_row.setPayment_channel_id(1416);
@ -1676,11 +1679,11 @@ public class ShopOrderReturnServiceImpl extends BaseServiceImpl<ShopOrderReturnM
// 运费独立加一条退单记录
if (!add(return_order_shipping_fee_row)) {
logger.error("生成退运费订单失败订单ID: {}", order_id);
logger.error("配送费退款订单生成失败订单ID: {}", order_id);
// 1生成退运费售后服务单
throw new ApiException(I18nUtil._("生成退运费订单失败!"));
throw new ApiException(I18nUtil._("配送费退款订单生成失败!"));
}
logger.info("成功生成退运费订单,退单号: {}", return_id);
logger.info("配送费退款订单生成成功,退单号: {}", return_id);
}
}
@ -1751,7 +1754,6 @@ public class ShopOrderReturnServiceImpl extends BaseServiceImpl<ShopOrderReturnM
logger.error("更新退货单退款状态失败!退货单列表: {}", return_ids);
throw new ApiException(ResultCode.FAILED);
}
}
return true;