退款 配送费 流程更改,拉卡拉 合单 需分开 退款
This commit is contained in:
parent
ce85d72cee
commit
afaca094f5
@ -110,4 +110,9 @@ public class CommonConstant {
|
||||
//秒杀活动订阅消息模板id
|
||||
public static final String BIND_SUB_TMPL_SKILL = "kiDj_hSF_ASwD-Dlgxnypi6IJBQZ12a-hEpd3zZ-Uxc";
|
||||
|
||||
//分账计算方式:1-按总金额;2-按可分账金额;
|
||||
public static final int SeparateCalcMode_TotalAmt = 1;
|
||||
public static final int SeparateCalcMode_CanSeparateAmt = 2;
|
||||
|
||||
|
||||
}
|
||||
|
||||
@ -3,6 +3,7 @@ package com.suisung.mall.common.exception;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import com.suisung.mall.common.api.CommonResult;
|
||||
import com.suisung.mall.common.api.ResultCode;
|
||||
import io.seata.rm.datasource.exec.LockWaitTimeoutException;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.dao.DataAccessException;
|
||||
@ -91,13 +92,14 @@ public class GlobalExceptionHandler {
|
||||
/**
|
||||
* 处理系统级异常(数据库异常/通用异常)
|
||||
*/
|
||||
@ExceptionHandler({SQLException.class, DataAccessException.class, Exception.class})
|
||||
@ExceptionHandler({SQLException.class, DataAccessException.class, LockWaitTimeoutException.class, Exception.class})
|
||||
public CommonResult handleSystemException(HttpServletRequest req, Exception e) {
|
||||
logError(req, e.getMessage(), e);
|
||||
|
||||
if (e instanceof SQLException || e instanceof DataAccessException) {
|
||||
return CommonResult.failed("系统数据异常,请联系管理员!");
|
||||
}
|
||||
|
||||
return CommonResult.failed("系统内部异常,请联系管理员!");
|
||||
}
|
||||
|
||||
|
||||
@ -92,6 +92,9 @@ public class ShopOrderData implements Serializable {
|
||||
@ApiModelProperty(value = "实际运费金额-卖家可修改")
|
||||
private BigDecimal order_shipping_fee;
|
||||
|
||||
@ApiModelProperty(value = "平台内部运费金额")
|
||||
private BigDecimal order_shipping_fee_inner;
|
||||
|
||||
@ApiModelProperty(value = "总计分账金额(从拉卡拉上分账,分给平台和代理商费用),单位:元")
|
||||
private BigDecimal total_separate_value;
|
||||
|
||||
|
||||
@ -72,6 +72,8 @@ public class MchOrderInfoDTO implements Serializable {
|
||||
private Integer delivery_type_id;
|
||||
@ApiModelProperty(value = "订单运费")
|
||||
private BigDecimal order_shipping_fee;
|
||||
@ApiModelProperty(value = "平台内部配送费")
|
||||
private BigDecimal order_shipping_fee_inner;
|
||||
@ApiModelProperty(value = "平台费")
|
||||
private BigDecimal platform_fee;
|
||||
@ApiModelProperty(value = "店铺统一设置的打包费")
|
||||
|
||||
@ -68,8 +68,8 @@ public class LklSeparateDTO {
|
||||
dto2.setMchRatio(new BigDecimal("0.95")); // 商家分账比例 0.857 (会产生小数)
|
||||
dto2.setPlatRatio(new BigDecimal("0.06")); // 平台分账比例 0.01
|
||||
// 不设置一级和二级代理商分账比例,测试不参与分账的情况
|
||||
// dto2.setAgent1stRatio(new BigDecimal("0.01")); // 一级代理商分账比例 0.023 (会产生小数)
|
||||
// dto2.setAgent2ndRatio(new BigDecimal("0.04")); // 二级代理商分账比例 0.031 (会产生小数)
|
||||
dto2.setAgent1stRatio(new BigDecimal("0.11")); // 一级代理商分账比例 0.023 (会产生小数)
|
||||
dto2.setAgent2ndRatio(new BigDecimal("0.04")); // 二级代理商分账比例 0.031 (会产生小数)
|
||||
|
||||
SharingResult result2 = dto2.sharingOnCanSeparateAmount();
|
||||
System.out.println(result2);
|
||||
|
||||
@ -574,6 +574,10 @@ public class LakalaPayServiceImpl implements LakalaPayService {
|
||||
|
||||
// TODO 重要的逻辑,获取是否已经分账?已分账:分账退回;查商家账户余额够不够退回?够就执行退回
|
||||
|
||||
if (StrUtil.isBlank(refundReason)) {
|
||||
refundReason = "商家与买方协商退款";
|
||||
}
|
||||
|
||||
// 5. 构造退款请求并发送
|
||||
V3LabsRelationRefundRequest refundRequest = new V3LabsRelationRefundRequest();
|
||||
refundRequest.setOutTradeNo(outTradeNo);
|
||||
|
||||
@ -1609,362 +1609,6 @@ public class PayConsumeTradeServiceImpl extends BaseServiceImpl<PayConsumeTradeM
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* 执行退款操作
|
||||
* 订单退款的逻辑,处理了买家退款、卖家扣款、订单状态更新以及相关流水记录的生成。
|
||||
*
|
||||
* @param return_rows 订单信息
|
||||
*/
|
||||
// @Override
|
||||
public boolean doRefundBak(List<ShopOrderReturn> return_rows) {
|
||||
List<String> paid_return_id_row = new ArrayList<>();
|
||||
|
||||
// 原路退回标记
|
||||
boolean order_refund_flag = accountBaseConfigService.getConfig("order_refund_flag", false);
|
||||
List<String> order_id_rows = return_rows.stream().map(ShopOrderReturn::getOrder_id).distinct().collect(Collectors.toList());
|
||||
|
||||
List<ShopOrderData> order_data_rows = shopService.getsShopOrderData(order_id_rows);
|
||||
|
||||
List<Integer> store_ids = return_rows.stream().map(ShopOrderReturn::getStore_id).distinct().collect(Collectors.toList());
|
||||
List<Map> store_rows = shopService.getsShopStoreBase(store_ids);
|
||||
|
||||
List<Integer> user_ids = return_rows.stream().map(ShopOrderReturn::getBuyer_user_id).distinct().collect(Collectors.toList());
|
||||
// 不使用缓存防止缓存被保存导致回滚异常
|
||||
List<PayUserResource> payUserResources = payUserResourceService.listByIds(user_ids);
|
||||
List<ShopOrderInfo> order_info_rows = shopService.getsShopOrderInfo(order_id_rows);
|
||||
|
||||
List<String> return_ids = return_rows.stream().map(ShopOrderReturn::getReturn_id).distinct().collect(Collectors.toList());
|
||||
if (CollUtil.isEmpty(return_ids)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
Map queryParams = new HashMap();
|
||||
queryParams.put("return_id:in", return_ids);
|
||||
List<ShopOrderReturnItem> orderReturnItemList = shopService.findShopOrderReturnItem(queryParams);
|
||||
if (CollUtil.isEmpty(orderReturnItemList)) {
|
||||
throw new ApiException(I18nUtil._("没有找到相关的退货商品信息!"));
|
||||
}
|
||||
|
||||
List<Long> order_item_ids = orderReturnItemList.stream().map(ShopOrderReturnItem::getOrder_item_id).distinct().collect(Collectors.toList());
|
||||
List<ShopOrderItem> orderItemList = shopService.getsShopOrderItem(order_item_ids);
|
||||
|
||||
Date curTime = new Date();
|
||||
DateTime ymdTime = DateUtil.parse(DateUtil.format(curTime, "yyyy-MM-dd"));
|
||||
|
||||
float points_vaue_rate = accountBaseConfigService.getConfig("points_vaue_rate", 0f);
|
||||
|
||||
// 积分抵扣,暂时忽略,不涉及此处支付。
|
||||
// 按照次序,依次支付。
|
||||
for (ShopOrderReturn return_row : return_rows) {
|
||||
|
||||
Integer user_id = return_row.getBuyer_user_id();
|
||||
if (CheckUtil.isEmpty(user_id)) {
|
||||
throw new ApiException(I18nUtil._("买家信息有误!"));
|
||||
}
|
||||
|
||||
Integer buyer_store_id = return_row.getBuyer_store_id();
|
||||
|
||||
Integer store_id = return_row.getStore_id();
|
||||
Optional<Map> storeOpl = store_rows.stream().filter(s -> ObjectUtil.equal(Convert.toInt(s.get("store_id")), store_id)).findFirst();
|
||||
Map store_row = storeOpl.orElseGet(HashMap::new);
|
||||
|
||||
Integer seller_id = (Integer) store_row.get("user_id");
|
||||
if (CheckUtil.isEmpty(seller_id)) {
|
||||
throw new ApiException(I18nUtil._("卖家信息有误!"));
|
||||
}
|
||||
|
||||
// 判断当前余额
|
||||
Optional<PayUserResource> userResourceOpl = payUserResources.stream().filter(s -> ObjectUtil.equal(user_id, s.getUser_id())).findFirst();
|
||||
PayUserResource user_resource_row = userResourceOpl.orElseGet(PayUserResource::new);
|
||||
|
||||
// todo 判断是否需要退佣金 $return_row['return_commision_fee']
|
||||
BigDecimal return_commision_fee = BigDecimal.ZERO;
|
||||
|
||||
// 不是退运费
|
||||
String order_id = return_row.getOrder_id();
|
||||
Integer return_is_shipping_fee = return_row.getReturn_is_shipping_fee();
|
||||
if (CheckUtil.isEmpty(return_is_shipping_fee)) {
|
||||
float withdraw_received_day = Convert.toFloat(accountBaseConfigService.getConfig("withdraw_received_day"));
|
||||
if (withdraw_received_day == 0) {
|
||||
withdraw_received_day = 7f;
|
||||
}
|
||||
|
||||
if (withdraw_received_day >= 0) {
|
||||
Optional<ShopOrderInfo> orderInfoOpl = order_info_rows.stream().filter(s -> ObjectUtil.equal(order_id, s.getOrder_id())).findFirst();
|
||||
ShopOrderInfo order_info_row = orderInfoOpl.orElseGet(ShopOrderInfo::new);
|
||||
|
||||
Integer order_state_id = order_info_row.getOrder_state_id();
|
||||
Integer order_is_paid = order_info_row.getOrder_is_paid();
|
||||
Long order_deal_time = order_info_row.getOrder_deal_time();
|
||||
long time = DateUtil.offsetDay(curTime, -7).getTime();
|
||||
|
||||
// 未到可结算时间可退佣金
|
||||
if (ObjectUtil.equal(order_state_id, StateCode.ORDER_STATE_FINISH)
|
||||
&& ObjectUtil.equal(order_is_paid, StateCode.ORDER_PAID_STATE_YES)
|
||||
&& order_deal_time < time) {
|
||||
return_commision_fee = BigDecimal.ZERO;
|
||||
} else {
|
||||
return_commision_fee = return_row.getReturn_commision_fee();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
BigDecimal waiting_refund_amount = return_row.getReturn_refund_amount();
|
||||
if (CheckUtil.isNotEmpty(waiting_refund_amount)) {
|
||||
|
||||
Optional<ShopOrderData> OrderDataOpl = order_data_rows.stream().filter(s -> ObjectUtil.equal(s.getOrder_id(), order_id)).findFirst();
|
||||
ShopOrderData order_data_row = OrderDataOpl.orElseGet(ShopOrderData::new);
|
||||
|
||||
BigDecimal order_points_fee = order_data_row.getOrder_points_fee();
|
||||
BigDecimal order_refund_agree_points = order_data_row.getOrder_refund_agree_points();
|
||||
|
||||
BigDecimal buyer_user_money = waiting_refund_amount;
|
||||
BigDecimal buyer_user_points = BigDecimal.ZERO;
|
||||
|
||||
BigDecimal seller_user_money = waiting_refund_amount.negate();
|
||||
String return_id = return_row.getReturn_id();
|
||||
|
||||
// 写入流水
|
||||
PayConsumeRecord buyer_consume_record_row = new PayConsumeRecord();
|
||||
|
||||
buyer_consume_record_row.setOrder_id(return_id);
|
||||
buyer_consume_record_row.setUser_id(user_id);
|
||||
buyer_consume_record_row.setStore_id(buyer_store_id);
|
||||
buyer_consume_record_row.setUser_nickname(""); // todo User_nickname
|
||||
buyer_consume_record_row.setRecord_date(ymdTime);
|
||||
buyer_consume_record_row.setRecord_year(DateUtil.year(ymdTime));
|
||||
buyer_consume_record_row.setRecord_month(DateUtil.month(ymdTime) + 1);
|
||||
buyer_consume_record_row.setRecord_day(DateUtil.dayOfMonth(ymdTime));
|
||||
buyer_consume_record_row.setRecord_title(I18nUtil._("退款单:") + return_id);
|
||||
buyer_consume_record_row.setRecord_time(curTime);
|
||||
buyer_consume_record_row.setPayment_met_id(PaymentType.PAYMENT_MET_MONEY);
|
||||
|
||||
// 增加流水
|
||||
buyer_consume_record_row.setRecord_money(waiting_refund_amount); // 佣金问题?
|
||||
buyer_consume_record_row.setTrade_type_id(StateCode.TRADE_TYPE_REFUND_GATHERING);
|
||||
|
||||
// 卖家流水记录
|
||||
PayConsumeRecord seller_consume_record_row = ObjectUtil.clone(buyer_consume_record_row);
|
||||
|
||||
seller_consume_record_row.setUser_id(seller_id);
|
||||
seller_consume_record_row.setStore_id(store_id);
|
||||
seller_consume_record_row.setRecord_money(NumberUtil.add(waiting_refund_amount.negate(), return_commision_fee));
|
||||
seller_consume_record_row.setRecord_commission_fee(return_commision_fee.negate());
|
||||
seller_consume_record_row.setTrade_type_id(StateCode.TRADE_TYPE_REFUND_PAY);
|
||||
|
||||
order_data_row.setOrder_refund_agree_amount(NumberUtil.add(waiting_refund_amount, order_refund_agree_points));
|
||||
|
||||
// todo 不能在这里统计,并发情况下seata操作同一张表数据会导致无法回滚的问题 原因:A线程修改完数据记录到undo_log表中,回滚的时候发现B线程也修改了这个数据
|
||||
// 平台佣金总额
|
||||
/*if (CheckUtil.isNotEmpty(return_commision_fee)) {
|
||||
PayPlantformResource plantform_resource_row = payPlantformResourceService.get(DATA_ID);
|
||||
if (plantform_resource_row == null) {
|
||||
plantform_resource_row = new PayPlantformResource();
|
||||
plantform_resource_row.setPlantform_resource_id(DATA_ID);
|
||||
}
|
||||
plantform_resource_row.setPlantform_commission_fee(NumberUtil.add(return_commision_fee.negate(), plantform_resource_row.getPlantform_commission_fee()));
|
||||
if (!payPlantformResourceService.saveOrUpdate(plantform_resource_row)) {
|
||||
throw new ApiException(ResultCode.FAILED);
|
||||
}
|
||||
|
||||
BigDecimal order_commission_fee_refund = order_data_row.getOrder_commission_fee_refund();
|
||||
order_data_row.setOrder_commission_fee_refund(NumberUtil.add(order_commission_fee_refund, return_commision_fee));
|
||||
}*/
|
||||
|
||||
// 读取退款单项目
|
||||
List<ShopOrderReturnItem> order_return_item_rows = orderReturnItemList.stream().filter(s -> ObjectUtil.equal(s.getReturn_id(), return_id)).collect(Collectors.toList());
|
||||
if (CollUtil.isNotEmpty(orderItemList)) {
|
||||
|
||||
List<ShopOrderItem> order_item_rows = new ArrayList<>();
|
||||
for (ShopOrderReturnItem order_return_item_row : order_return_item_rows) {
|
||||
|
||||
Long order_item_id = order_return_item_row.getOrder_item_id();
|
||||
Optional<ShopOrderItem> orderItemOpl = orderItemList.stream().filter(s -> ObjectUtil.equal(order_item_id, s.getOrder_item_id())).findFirst();
|
||||
if (orderItemOpl.isPresent()) {
|
||||
ShopOrderItem order_item_row = orderItemOpl.get();
|
||||
|
||||
BigDecimal return_item_subtotal = order_return_item_row.getReturn_item_subtotal();
|
||||
Integer return_item_num = order_return_item_row.getReturn_item_num();
|
||||
BigDecimal order_item_return_agree_amount = order_item_row.getOrder_item_return_agree_amount();
|
||||
Integer order_item_return_agree_num = ObjectUtil.defaultIfNull(order_item_row.getOrder_item_return_agree_num(), 0);
|
||||
|
||||
order_item_row.setOrder_item_return_agree_amount(NumberUtil.add(order_item_return_agree_amount, return_item_subtotal));
|
||||
order_item_row.setOrder_item_return_agree_num(order_item_return_agree_num + return_item_num);
|
||||
|
||||
// 订单未结算才发放佣金
|
||||
if (CheckUtil.isNotEmpty(return_commision_fee)) {
|
||||
BigDecimal return_item_commision_fee = order_return_item_row.getReturn_item_commision_fee();
|
||||
BigDecimal order_item_commission_fee_refund = ObjectUtil.defaultIfNull(order_item_row.getOrder_item_commission_fee_refund(), BigDecimal.ZERO);
|
||||
order_item_row.setOrder_item_commission_fee_refund(NumberUtil.add(return_item_commision_fee, order_item_commission_fee_refund));
|
||||
}
|
||||
order_item_rows.add(order_item_row);
|
||||
}
|
||||
}
|
||||
|
||||
if (CollUtil.isNotEmpty(order_item_rows)) {
|
||||
if (!shopService.editsShopOrderItem(order_item_rows)) {
|
||||
throw new ApiException(I18nUtil._("修改订单商品数据失败!"));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 买家数据
|
||||
if (!payConsumeRecordService.saveOrUpdate(buyer_consume_record_row)) {
|
||||
throw new ApiException(I18nUtil._("添加买家流水数据失败!"));
|
||||
}
|
||||
|
||||
// 如果混合了积分,优先退积分
|
||||
if (order_points_fee.compareTo(BigDecimal.ZERO) > 0
|
||||
&& order_points_fee.compareTo(order_refund_agree_points) > 0) {
|
||||
BigDecimal refund_points = NumberUtil.round(NumberUtil.min(NumberUtil.sub(order_points_fee, order_refund_agree_points)), 2);
|
||||
buyer_user_money = NumberUtil.round(NumberUtil.sub(buyer_user_money, refund_points), 2);
|
||||
|
||||
if (points_vaue_rate > 0) {
|
||||
buyer_user_points = NumberUtil.div(refund_points, points_vaue_rate);
|
||||
}
|
||||
order_data_row.setOrder_refund_agree_points(NumberUtil.add(order_refund_agree_points, refund_points));
|
||||
}
|
||||
|
||||
// todo 优化代码
|
||||
if (order_refund_flag) {
|
||||
// 读取在线支付信息,如果无在线支付信息,则余额支付 否则在线支付【联合支付】判断
|
||||
QueryWrapper<PayConsumeDeposit> depositQueryWrapper = new QueryWrapper<>();
|
||||
depositQueryWrapper.apply(order_id != null, "FIND_IN_SET ('" + order_id + "', order_id )");
|
||||
PayConsumeDeposit consume_row = payConsumeDepositService.findOne(depositQueryWrapper);
|
||||
|
||||
if (consume_row != null) {
|
||||
Integer payment_channel_id = consume_row.getPayment_channel_id();
|
||||
PayPaymentChannel payment_channel_row = payPaymentChannelService.get(payment_channel_id);
|
||||
String payment_channel_code = payment_channel_row.getPayment_channel_code();
|
||||
BigDecimal deposit_total_fee = consume_row.getDeposit_total_fee();
|
||||
|
||||
if (Arrays.asList("alipay", "wx_native").contains(payment_channel_code)) {
|
||||
BigDecimal d_money = NumberUtil.round(NumberUtil.sub(buyer_user_money, deposit_total_fee), 2);
|
||||
if (d_money.compareTo(BigDecimal.ZERO) > 0) {
|
||||
PayUserResource payUserResource = payUserResourceService.getById(user_id);
|
||||
payUserResource.setUser_money(NumberUtil.add(payUserResource.getUser_money(), d_money));
|
||||
if (!payUserResourceService.edit(payUserResource)) {
|
||||
throw new ApiException(I18nUtil._("用户退款失败!"));
|
||||
}
|
||||
}
|
||||
|
||||
if (buyer_user_points.compareTo(BigDecimal.ZERO) > 0) {
|
||||
if (!payUserResourceService.points(user_id, buyer_user_points, PointsType.POINTS_TYPE_CONSUME_RETRUN, return_id, store_id, null, return_id)) {
|
||||
throw new ApiException(I18nUtil._("用户退积分失败!"));
|
||||
}
|
||||
}
|
||||
|
||||
String deposit_trade_no = consume_row.getDeposit_trade_no();
|
||||
|
||||
ShopOrderReturn orderReturn = new ShopOrderReturn();
|
||||
orderReturn.setReturn_id(return_id);
|
||||
orderReturn.setReturn_channel_code(payment_channel_code);
|
||||
orderReturn.setDeposit_trade_no(deposit_trade_no);
|
||||
orderReturn.setPayment_channel_id(payment_channel_id);
|
||||
orderReturn.setTrade_payment_amount(deposit_total_fee);
|
||||
if (!shopService.editShopOrderReturn(orderReturn)) {
|
||||
throw new ApiException(I18nUtil._("修改退单信息失败!"));
|
||||
}
|
||||
} else {
|
||||
if (buyer_user_money.compareTo(BigDecimal.ZERO) > 0) {
|
||||
PayUserResource payUserResource = payUserResourceService.getById(user_id);
|
||||
payUserResource.setUser_money(NumberUtil.add(payUserResource.getUser_money(), buyer_user_money));
|
||||
if (!payUserResourceService.edit(payUserResource)) {
|
||||
throw new ApiException(I18nUtil._("用户退款失败!"));
|
||||
}
|
||||
}
|
||||
|
||||
if (buyer_user_points.compareTo(BigDecimal.ZERO) > 0) {
|
||||
if (!payUserResourceService.points(user_id, buyer_user_points, PointsType.POINTS_TYPE_CONSUME_RETRUN, return_id, store_id, null, return_id)) {
|
||||
throw new ApiException(I18nUtil._("用户退积分失败!"));
|
||||
}
|
||||
}
|
||||
|
||||
ShopOrderReturn orderReturn = new ShopOrderReturn();
|
||||
orderReturn.setReturn_id(return_id);
|
||||
orderReturn.setReturn_channel_flag(1);
|
||||
if (!shopService.editShopOrderReturn(orderReturn)) {
|
||||
throw new ApiException(I18nUtil._("修改退单信息失败!"));
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (buyer_user_money.compareTo(BigDecimal.ZERO) > 0) {
|
||||
PayUserResource payUserResource = payUserResourceService.getById(user_id);
|
||||
payUserResource.setUser_money(NumberUtil.add(payUserResource.getUser_money(), buyer_user_money));
|
||||
if (!payUserResourceService.edit(payUserResource)) {
|
||||
throw new ApiException(I18nUtil._("用户退款失败!"));
|
||||
}
|
||||
}
|
||||
|
||||
if (buyer_user_points.compareTo(BigDecimal.ZERO) > 0) {
|
||||
if (!payUserResourceService.points(user_id, buyer_user_points, PointsType.POINTS_TYPE_CONSUME_RETRUN, return_id, store_id, null, return_id)) {
|
||||
throw new ApiException(I18nUtil._("用户退积分失败!"));
|
||||
}
|
||||
}
|
||||
|
||||
ShopOrderReturn orderReturn = new ShopOrderReturn();
|
||||
orderReturn.setReturn_id(return_id);
|
||||
orderReturn.setReturn_channel_flag(1);
|
||||
if (!shopService.editShopOrderReturn(orderReturn)) {
|
||||
throw new ApiException(I18nUtil._("修改退单信息失败!"));
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (buyer_user_money.compareTo(BigDecimal.ZERO) > 0) {
|
||||
PayUserResource payUserResource = payUserResourceService.getById(user_id);
|
||||
payUserResource.setUser_money(NumberUtil.add(payUserResource.getUser_money(), buyer_user_money));
|
||||
if (!payUserResourceService.edit(payUserResource)) {
|
||||
throw new ApiException(I18nUtil._("用户退款失败!"));
|
||||
}
|
||||
}
|
||||
|
||||
if (buyer_user_points.compareTo(BigDecimal.ZERO) > 0) {
|
||||
if (!payUserResourceService.points(user_id, buyer_user_points, PointsType.POINTS_TYPE_CONSUME_RETRUN, return_id, store_id, null, return_id)) {
|
||||
throw new ApiException(I18nUtil._("用户退积分失败!"));
|
||||
}
|
||||
}
|
||||
|
||||
ShopOrderReturn orderReturn = new ShopOrderReturn();
|
||||
orderReturn.setReturn_id(return_id);
|
||||
orderReturn.setReturn_channel_flag(1);
|
||||
if (!shopService.editShopOrderReturn(orderReturn)) {
|
||||
throw new ApiException(I18nUtil._("修改退单信息失败!"));
|
||||
}
|
||||
}
|
||||
|
||||
if (!shopService.editShopOrderData(order_data_row)) {
|
||||
throw new ApiException(I18nUtil._("修改详细信息失败!"));
|
||||
}
|
||||
|
||||
// todo 修改订单状态?
|
||||
if (buyer_user_money != null) {
|
||||
// 流水记录
|
||||
if (!payConsumeRecordService.saveOrUpdate(seller_consume_record_row)) {
|
||||
throw new ApiException(I18nUtil._("写入卖家信息失败!"));
|
||||
}
|
||||
|
||||
seller_user_money = NumberUtil.add(buyer_user_money.negate(), return_commision_fee);
|
||||
PayUserResource payUserResource = payUserResourceService.getById(seller_id);
|
||||
payUserResource.setUser_money(NumberUtil.add(payUserResource.getUser_money(), seller_user_money));
|
||||
if (!payUserResourceService.edit(payUserResource)) {
|
||||
throw new ApiException(I18nUtil._("卖家用户退款失败!"));
|
||||
}
|
||||
}
|
||||
|
||||
paid_return_id_row.add(return_id);
|
||||
}
|
||||
}
|
||||
|
||||
if (CollUtil.isNotEmpty(paid_return_id_row)) {
|
||||
// 远程服务器订单更改放入
|
||||
// 本地服务器订单更改
|
||||
if (!shopService.setReturnPaidYes(paid_return_id_row)) {
|
||||
throw new ApiException(ResultCode.FAILED);
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* 更改交易订单的订单状态和付款状态
|
||||
|
||||
@ -11,9 +11,11 @@ package com.suisung.mall.shop.lakala.service;
|
||||
import cn.hutool.json.JSONObject;
|
||||
import com.suisung.mall.common.api.CommonResult;
|
||||
import com.suisung.mall.common.modules.store.ShopMchEntry;
|
||||
import com.suisung.mall.common.pojo.dto.LklSeparateDTO;
|
||||
import org.springframework.data.util.Pair;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import java.math.BigDecimal;
|
||||
|
||||
/**
|
||||
* 拉卡拉业务接口
|
||||
@ -350,4 +352,26 @@ public interface LakalaApiService {
|
||||
*/
|
||||
JSONObject ewalletWithDrawNotify(HttpServletRequest request);
|
||||
|
||||
/**
|
||||
* 商户分账参数计算及评估
|
||||
*
|
||||
* @param splitMode 分账模式:1-总金额为基准分账,2-可分账金额基准分账,必填参数
|
||||
* @param orderPayAmount 订单支付总金额(单位:分)必填参数
|
||||
* @param shippingFeeInner 平台内部配送费(单位:分)必填参数
|
||||
* @param mchSplitRatioRaw 商户分账比例值(分子值,如10表示10%)必填参数
|
||||
* @param platSplitRatio 平台分账比例(百分比值,如0.01表示1%)可选参数
|
||||
* @param agent1stRatio 一级分账比例(百分比值,如0.01表示1%)可选参数
|
||||
* @param agent2ndRatio 二级分账比例(百分比值,如0.01表示1%)可选参数
|
||||
* @param refCanSeparateAmt 参考可分金额(单位:分) 可选参数
|
||||
* @return Pair<Boolean, LklSeparateDTO> 分账参数评估结果,第一个元素表示是否成功,第二个元素为分账参数对象
|
||||
*/
|
||||
Pair<Boolean, LklSeparateDTO> calculateAndEvaluateSharingParams(int splitMode,
|
||||
Integer orderPayAmount,
|
||||
Integer shippingFeeInner,
|
||||
BigDecimal mchSplitRatioRaw,
|
||||
BigDecimal platSplitRatio,
|
||||
BigDecimal agent1stRatio,
|
||||
BigDecimal agent2ndRatio,
|
||||
Integer refCanSeparateAmt);
|
||||
|
||||
}
|
||||
|
||||
@ -3612,4 +3612,111 @@ public class LakalaApiServiceImpl implements LakalaApiService {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 商户分账参数计算及评估
|
||||
*
|
||||
* @param splitMode 分账模式:1-总金额为基准分账,2-可分账金额基准分账,必填参数
|
||||
* @param orderPayAmount 订单支付总金额(单位:分)必填参数
|
||||
* @param shippingFeeInner 平台内部配送费(单位:分)必填参数
|
||||
* @param mchSplitRatioRaw 商户分账比例值(分子值,如10表示10%)必填参数
|
||||
* @param platSplitRatio 平台分账比例(百分比值,如0.01表示1%)可选参数
|
||||
* @param agent1stRatio 一级分账比例(百分比值,如0.01表示1%)可选参数
|
||||
* @param agent2ndRatio 二级分账比例(百分比值,如0.01表示1%)可选参数
|
||||
* @param refCanSeparateAmt 参考可分金额(单位:分) 可选参数
|
||||
* @return Pair<Boolean, LklSeparateDTO> 分账参数评估结果,第一个元素表示是否成功,第二个元素为分账参数对象
|
||||
*/
|
||||
@Override
|
||||
public Pair<Boolean, LklSeparateDTO> calculateAndEvaluateSharingParams(int splitMode,
|
||||
Integer orderPayAmount,
|
||||
Integer shippingFeeInner,
|
||||
BigDecimal mchSplitRatioRaw,
|
||||
BigDecimal platSplitRatio,
|
||||
BigDecimal agent1stRatio,
|
||||
BigDecimal agent2ndRatio,
|
||||
Integer refCanSeparateAmt) {
|
||||
log.debug("[分账参数计算] 开始计算分账参数: splitMode={}, orderPayAmount={}, shippingFeeInner={}, " +
|
||||
"mchSplitRatioRaw={}, platSplitRatio={}, agent1stRatio={}, agent2ndRatio={}, refCanSeparateAmt={}",
|
||||
splitMode, orderPayAmount, shippingFeeInner, mchSplitRatioRaw, platSplitRatio,
|
||||
agent1stRatio, agent2ndRatio, refCanSeparateAmt);
|
||||
|
||||
// 参数校验
|
||||
if (orderPayAmount == null || orderPayAmount <= 0) {
|
||||
log.warn("[分账参数计算] 订单支付金额参数无效: orderPayAmount={}", orderPayAmount);
|
||||
return Pair.of(false, null);
|
||||
}
|
||||
|
||||
if (mchSplitRatioRaw == null || mchSplitRatioRaw.compareTo(BigDecimal.ZERO) <= 0 || mchSplitRatioRaw.compareTo(BigDecimal.valueOf(100)) > 0) {
|
||||
log.warn("[分账参数计算] 商户分账比例参数无效: mchSplitRatioRaw={}", mchSplitRatioRaw);
|
||||
return Pair.of(false, null);
|
||||
}
|
||||
|
||||
if (splitMode != 1 && splitMode != 2) {
|
||||
log.warn("[分账参数计算] 分账模式参数错误: splitMode={}", splitMode);
|
||||
return Pair.of(false, null);
|
||||
}
|
||||
|
||||
// 计算商家分账比例(转换为小数)
|
||||
BigDecimal mchSplitRatio = mchSplitRatioRaw.divide(new BigDecimal(100));
|
||||
log.debug("[分账参数计算] 商家分账比例转换: {} -> {}", mchSplitRatioRaw, mchSplitRatio);
|
||||
|
||||
// 平台分账比例处理
|
||||
BigDecimal platformSplitRatio = platSplitRatio;
|
||||
if (platformSplitRatio == null || platformSplitRatio.compareTo(BigDecimal.ZERO) <= 0) {
|
||||
platformSplitRatio = BigDecimal.valueOf(0.01); // 默认平台分账1%
|
||||
log.debug("[分账参数计算] 使用默认平台分账比例: {}", platformSplitRatio);
|
||||
}
|
||||
|
||||
// 内部配送费处理
|
||||
Integer actualShippingFeeInner = CheckUtil.isEmpty(shippingFeeInner) ? 0 : shippingFeeInner;
|
||||
BigDecimal wxFeeRatio = StrUtil.isEmpty(wxFee) ? BigDecimal.valueOf(0.0025) : new BigDecimal(wxFee).divide(BigDecimal.valueOf(100));
|
||||
log.debug("[分账参数计算] 配送费: {}, 拉卡拉费率: {}", actualShippingFeeInner, wxFeeRatio);
|
||||
|
||||
// 构建分账参数对象
|
||||
LklSeparateDTO lklSeparateDTO = new LklSeparateDTO();
|
||||
lklSeparateDTO.setTotalSeparateAmount(orderPayAmount);
|
||||
lklSeparateDTO.setShippingFee(actualShippingFeeInner);
|
||||
lklSeparateDTO.setLklRatio(wxFeeRatio); // 拉卡拉给的微信分账比例 0.0025 千分之2.5
|
||||
lklSeparateDTO.setMchRatio(mchSplitRatio);
|
||||
lklSeparateDTO.setPlatRatio(platformSplitRatio);
|
||||
|
||||
// 设置代理商分账比例
|
||||
if (agent1stRatio != null && agent1stRatio.compareTo(BigDecimal.ZERO) > 0) {
|
||||
lklSeparateDTO.setAgent1stRatio(agent1stRatio);
|
||||
log.debug("[分账参数计算] 设置一级代理商分账比例: {}", agent1stRatio);
|
||||
}
|
||||
|
||||
if (agent2ndRatio != null && agent2ndRatio.compareTo(BigDecimal.ZERO) > 0) {
|
||||
lklSeparateDTO.setAgent2ndRatio(agent2ndRatio);
|
||||
log.debug("[分账参数计算] 设置二级代理商分账比例: {}", agent2ndRatio);
|
||||
}
|
||||
|
||||
// 设置参考可分账金额
|
||||
if (refCanSeparateAmt != null && refCanSeparateAmt > 0) {
|
||||
lklSeparateDTO.setRefCanSeparateAmount(refCanSeparateAmt);
|
||||
log.debug("[分账参数计算] 设置参考可分账金额: {}", refCanSeparateAmt);
|
||||
}
|
||||
|
||||
// 根据分账模式执行不同的分账计算
|
||||
LklSeparateDTO.SharingResult canSeparateAmtResult;
|
||||
if (splitMode == 1) {
|
||||
// 总金额为基准分账
|
||||
log.debug("[分账参数计算] 使用总金额为基准分账模式");
|
||||
canSeparateAmtResult = lklSeparateDTO.sharingOnTotalAmount();
|
||||
} else {
|
||||
// 可分金额基准分账
|
||||
log.debug("[分账参数计算] 使用可分账金额基准分账模式");
|
||||
canSeparateAmtResult = lklSeparateDTO.sharingOnCanSeparateAmount();
|
||||
}
|
||||
|
||||
if (!canSeparateAmtResult.isSuccess()) {
|
||||
log.warn("[分账参数计算] 分账参数评估失败: {}", canSeparateAmtResult.getErrorMessage());
|
||||
return Pair.of(false, lklSeparateDTO);
|
||||
}
|
||||
|
||||
log.info("[分账参数计算] 分账参数计算评估成功, result={}", lklSeparateDTO);
|
||||
return Pair.of(true, lklSeparateDTO);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@ -80,6 +80,8 @@ import static com.suisung.mall.common.utils.I18nUtil._;
|
||||
@Slf4j
|
||||
public class ShopMessageTemplateServiceImpl extends BaseServiceImpl<ShopMessageTemplateMapper, ShopMessageTemplate> implements ShopMessageTemplateService {
|
||||
|
||||
// 批处理阈值
|
||||
private static final int BATCH_SIZE = 30;
|
||||
@Autowired
|
||||
ShopStoreBaseService shopStoreBaseService;
|
||||
@Autowired
|
||||
@ -90,19 +92,13 @@ public class ShopMessageTemplateServiceImpl extends BaseServiceImpl<ShopMessageT
|
||||
private SnsService snsService;
|
||||
@Autowired
|
||||
private GeTuiUtil geTuiUtil;
|
||||
|
||||
@Autowired
|
||||
private CloundService cloundService;
|
||||
|
||||
@Autowired
|
||||
private ShopWechatTplmsgService shopWechatTplmsgService;
|
||||
|
||||
@Autowired
|
||||
private Environment environment;
|
||||
|
||||
// 批处理阈值
|
||||
private static final int BATCH_SIZE = 30;
|
||||
|
||||
public String dealMessageTemplate(String message_content, Map args) {
|
||||
StringSubstitutor sub = new StringSubstitutor(args);
|
||||
|
||||
@ -658,16 +654,22 @@ public class ShopMessageTemplateServiceImpl extends BaseServiceImpl<ShopMessageT
|
||||
/**
|
||||
* 异步批量发送阿里云短信
|
||||
*
|
||||
* @param mobiles
|
||||
* @param tmplCode
|
||||
* @param tmplParams
|
||||
* @return
|
||||
* @param mobiles 手机号列表
|
||||
* @param tmplCode 模板代码
|
||||
* @param tmplParams 模板参数
|
||||
* @return 成功发送的数量
|
||||
*/
|
||||
@Async
|
||||
@Override
|
||||
public Integer aliyunSmsSend(List<String> mobiles, String tmplCode, Map<String, Object> tmplParams) {
|
||||
// 过滤重复手机号,避免重复发送短信
|
||||
List<String> uniqueMobiles = mobiles.stream()
|
||||
.filter(StrUtil::isNotBlank)
|
||||
.distinct()
|
||||
.collect(Collectors.toList());
|
||||
|
||||
int successCnt = 0;
|
||||
for (String mobile : mobiles) {
|
||||
for (String mobile : uniqueMobiles) {
|
||||
if (aliyunSmsSend(mobile, tmplCode, tmplParams)) {
|
||||
successCnt++;
|
||||
}
|
||||
@ -676,22 +678,23 @@ public class ShopMessageTemplateServiceImpl extends BaseServiceImpl<ShopMessageT
|
||||
return successCnt;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public CommonResult sendToXcxUserMessage(Integer user_id) {
|
||||
Map bind_row = accountService.getBind(user_id, BindCode.MOBILE);
|
||||
if(bind_row == null){
|
||||
if (bind_row == null) {
|
||||
return CommonResult.failed("账号不存在");
|
||||
}
|
||||
if(bind_row.get("bind_openid")==null){
|
||||
if (bind_row.get("bind_openid") == null) {
|
||||
log.info("微信id不存在");
|
||||
return CommonResult.failed("微信id不存在");
|
||||
}
|
||||
String open_id = (String) bind_row.get("bind_openid");
|
||||
Map args=new HashMap();
|
||||
Map args = new HashMap();
|
||||
String[] activeProfiles = environment.getActiveProfiles();
|
||||
String activeProfile = activeProfiles[0];
|
||||
//微信小程序订阅消息
|
||||
args.put("evn",activeProfile);
|
||||
args.put("evn", activeProfile);
|
||||
//String open_id = Convert.toStr(user_setting.get("bind_openid"));
|
||||
//从bind表中读取用户公众号openid
|
||||
if (StrUtil.isNotEmpty(open_id)) {
|
||||
@ -700,10 +703,10 @@ public class ShopMessageTemplateServiceImpl extends BaseServiceImpl<ShopMessageT
|
||||
QueryWrapper<ShopWechatTplmsg> queryWrapper = new QueryWrapper<>();
|
||||
queryWrapper.eq("tplmsg_id", 1022);//todo 后期改为动态
|
||||
ShopWechatTplmsg wechatTplmsg = shopWechatTplmsgService.getOne(queryWrapper);
|
||||
ShopStoreBase shopStoreBase= shopStoreBaseService.get(wechatTplmsg.getStore_id());
|
||||
ShopStoreBase shopStoreBase = shopStoreBaseService.get(wechatTplmsg.getStore_id());
|
||||
args.put("storeName", shopStoreBase.getStore_name());
|
||||
if (wechatTplmsg != null) {
|
||||
Map timeArgs=getActiveTime();
|
||||
Map timeArgs = getActiveTime();
|
||||
args.putAll(timeArgs);
|
||||
String wechatTplData = getXcxWechatTplData(open_id, wechatTplmsg, args);
|
||||
log.info(wechatTplData);
|
||||
@ -720,10 +723,10 @@ public class ShopMessageTemplateServiceImpl extends BaseServiceImpl<ShopMessageT
|
||||
return CommonResult.success();
|
||||
}
|
||||
|
||||
private Map getActiveTime(){
|
||||
private Map getActiveTime() {
|
||||
Map args = new HashMap();
|
||||
// 获取当前时间
|
||||
LocalDateTime now = LocalDateTime.of(LocalDate.now(), LocalTime.of(9,0,0));
|
||||
LocalDateTime now = LocalDateTime.of(LocalDate.now(), LocalTime.of(9, 0, 0));
|
||||
// 加上13小时30分钟
|
||||
LocalDateTime futureTime = now.plusHours(13).minusMinutes(30);
|
||||
// 格式化输出
|
||||
@ -738,7 +741,7 @@ public class ShopMessageTemplateServiceImpl extends BaseServiceImpl<ShopMessageT
|
||||
@Override
|
||||
public void sendToXcxAllUserMessage() {
|
||||
long allBindCount = accountService.getAllBindCount(CommonConstant.BIND_SUB_TMPL_SKILL);
|
||||
if(allBindCount==0){
|
||||
if (allBindCount == 0) {
|
||||
return;
|
||||
}
|
||||
String accessToken = accountService.getXcxAccessToken(true);
|
||||
@ -746,25 +749,25 @@ public class ShopMessageTemplateServiceImpl extends BaseServiceImpl<ShopMessageT
|
||||
QueryWrapper<ShopWechatTplmsg> queryWrapper = new QueryWrapper<>();
|
||||
queryWrapper.eq("tplmsg_id", 1022);//todo 后期改为动态
|
||||
ShopWechatTplmsg wechatTplmsg = shopWechatTplmsgService.getOne(queryWrapper);
|
||||
ShopStoreBase shopStoreBase= shopStoreBaseService.get(wechatTplmsg.getStore_id());
|
||||
Map args=new HashMap();
|
||||
ShopStoreBase shopStoreBase = shopStoreBaseService.get(wechatTplmsg.getStore_id());
|
||||
Map args = new HashMap();
|
||||
String[] activeProfiles = environment.getActiveProfiles();
|
||||
String activeProfile = activeProfiles[0];
|
||||
args.put("storeName", shopStoreBase.getStore_name());
|
||||
args.put("evn",activeProfile);
|
||||
Map timeArgs=getActiveTime();
|
||||
args.put("evn", activeProfile);
|
||||
Map timeArgs = getActiveTime();
|
||||
args.putAll(timeArgs);
|
||||
int total= (int) allBindCount;
|
||||
Integer pages= CommonUtil.getPagesCount(total,BATCH_SIZE);
|
||||
int total = (int) allBindCount;
|
||||
Integer pages = CommonUtil.getPagesCount(total, BATCH_SIZE);
|
||||
ExecutorService executor = Executors.newFixedThreadPool(6);
|
||||
List<Future<?>> futures = new ArrayList<>();
|
||||
for (int i=1;i<=pages;i++){
|
||||
List<AccountUserBindConnect> finalList=accountService.getAllBindPage(CommonConstant.BIND_SUB_TMPL_SKILL,i,BATCH_SIZE);
|
||||
for (int i = 1; i <= pages; i++) {
|
||||
List<AccountUserBindConnect> finalList = accountService.getAllBindPage(CommonConstant.BIND_SUB_TMPL_SKILL, i, BATCH_SIZE);
|
||||
int finalI = i;
|
||||
futures.add(executor.submit(() -> {
|
||||
finalList.forEach(accountUserBindConnect -> {
|
||||
String open_id=accountUserBindConnect.getBind_openid();
|
||||
if(StrUtil.isNotEmpty(open_id)){
|
||||
String open_id = accountUserBindConnect.getBind_openid();
|
||||
if (StrUtil.isNotEmpty(open_id)) {
|
||||
String wechatTplData = getXcxWechatTplData(open_id, wechatTplmsg, args);
|
||||
String result = WxHttpUtil.request(WxHttpUtil.MethodType.POST, WxHttpUtil.WxType.XCX, accessToken, url, null, wechatTplData);
|
||||
JSONObject resultJson = JSONUtil.parseObj(result);
|
||||
@ -775,7 +778,7 @@ public class ShopMessageTemplateServiceImpl extends BaseServiceImpl<ShopMessageT
|
||||
}
|
||||
}
|
||||
});
|
||||
return "完成推送批次:"+ finalI;
|
||||
return "完成推送批次:" + finalI;
|
||||
}));
|
||||
}
|
||||
// 等待所有任务完成
|
||||
@ -804,11 +807,11 @@ public class ShopMessageTemplateServiceImpl extends BaseServiceImpl<ShopMessageT
|
||||
wxXcxMsgPushVo.setTemplate_id(wechatTplmsg.getTplmsg_tpl_id());
|
||||
wxXcxMsgPushVo.setPage(wechatTplmsg.getLink_url());
|
||||
|
||||
String evn=Convert.toStr(args.get("evn"));
|
||||
String storeName=Convert.toStr(args.get("storeName"));
|
||||
String miniprogram_state="trial";//默认为体验版
|
||||
if(evn.equals("prod")){
|
||||
miniprogram_state="formal";
|
||||
String evn = Convert.toStr(args.get("evn"));
|
||||
String storeName = Convert.toStr(args.get("storeName"));
|
||||
String miniprogram_state = "trial";//默认为体验版
|
||||
if (evn.equals("prod")) {
|
||||
miniprogram_state = "formal";
|
||||
}
|
||||
wxXcxMsgPushVo.setMiniprogram_state(miniprogram_state);
|
||||
wxXcxMsgPushVo.setLang("zh_CN");
|
||||
@ -829,8 +832,8 @@ public class ShopMessageTemplateServiceImpl extends BaseServiceImpl<ShopMessageT
|
||||
|
||||
amount4.setValue("0.01");
|
||||
BaseValue.setAmount4(amount4);
|
||||
String formattedNow=Convert.toStr(args.get("formattedNow"));
|
||||
String formattedFuture=Convert.toStr(args.get("formattedFuture"));
|
||||
String formattedNow = Convert.toStr(args.get("formattedNow"));
|
||||
String formattedFuture = Convert.toStr(args.get("formattedFuture"));
|
||||
|
||||
time6.setValue(formattedNow);
|
||||
BaseValue.setTime6(time6);
|
||||
|
||||
@ -86,6 +86,9 @@ public class ShopOrderReturnController extends BaseControllerImpl {
|
||||
ShopOrderReturn shopOrderReturn = new ShopOrderReturn();
|
||||
shopOrderReturn.setReturn_id(return_id);
|
||||
shopOrderReturn.setReturn_flag(return_flag);
|
||||
if (StrUtil.isBlank(return_store_message)) {
|
||||
return_store_message = I18nUtil._("同意");
|
||||
}
|
||||
shopOrderReturn.setReturn_store_message(return_store_message);
|
||||
return CommonResult.success(shopOrderReturnService.processReviewList(shopOrderReturn, receiving_address));
|
||||
}
|
||||
|
||||
@ -12,6 +12,7 @@ import cn.hutool.json.JSONObject;
|
||||
import com.suisung.mall.common.modules.order.ShopOrderLkl;
|
||||
import com.suisung.mall.core.web.service.IBaseService;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.util.List;
|
||||
|
||||
public interface ShopOrderLklService extends IBaseService<ShopOrderLkl> {
|
||||
@ -113,4 +114,22 @@ public interface ShopOrderLklService extends IBaseService<ShopOrderLkl> {
|
||||
* @return
|
||||
*/
|
||||
Boolean safeUpdate(ShopOrderLkl record);
|
||||
|
||||
/**
|
||||
* 获取平台内部订单配送费
|
||||
*
|
||||
* @param storeId 店铺Id
|
||||
* @param orderId 订单编号
|
||||
* @return
|
||||
*/
|
||||
Integer getOrderShippingFeeInner(Integer storeId, String orderId);
|
||||
|
||||
/**
|
||||
* 获取平台内部订单配送费
|
||||
*
|
||||
* @param storeId 店铺Id
|
||||
* @param orderId 订单编号
|
||||
* @return
|
||||
*/
|
||||
BigDecimal getOrderShippingFeeInnerToDecimal(Integer storeId, String orderId);
|
||||
}
|
||||
|
||||
@ -56,6 +56,7 @@ import com.suisung.mall.common.modules.product.ShopProductItem;
|
||||
import com.suisung.mall.common.modules.product.ShopProductValidPeriod;
|
||||
import com.suisung.mall.common.modules.store.*;
|
||||
import com.suisung.mall.common.modules.user.*;
|
||||
import com.suisung.mall.common.pojo.dto.LklSeparateDTO;
|
||||
import com.suisung.mall.common.pojo.dto.StandardAddressDTO;
|
||||
import com.suisung.mall.common.pojo.dto.WxOrderBaseInfoDTO;
|
||||
import com.suisung.mall.common.pojo.req.*;
|
||||
@ -3228,6 +3229,8 @@ public class ShopOrderBaseServiceImpl extends BaseServiceImpl<ShopOrderBaseMappe
|
||||
|
||||
// 获取所有店铺管理员的手机号
|
||||
shopKeeperMobiles.add(mobile);
|
||||
// 增加谢总的手机号
|
||||
shopKeeperMobiles.add("17777525395");
|
||||
|
||||
// 老流程(之前获取用户id不正确,现在更正) 2024-12-10 update 获取所有店铺管理员的 user_id
|
||||
MsgTO sellerMsgTo = new MsgTO(userId, store_id, message_id, args);
|
||||
@ -3236,11 +3239,11 @@ public class ShopOrderBaseServiceImpl extends BaseServiceImpl<ShopOrderBaseMappe
|
||||
}
|
||||
|
||||
// 2024-12-10 add
|
||||
// Map<String, Object> tmplArgs = new HashMap<>(2);
|
||||
// tmplArgs.put("order_id", order_id);
|
||||
// tmplArgs.put("order_payment_amount", order_payment_amount);
|
||||
// 所有店铺管理员的发送邮件, 提醒商家:您有一笔新的订单 ${order_id},请及时处理。
|
||||
// shopMessageTemplateService.aliyunSmsSend(shopKeeperMobiles, "SMS_476810378", tmplArgs);
|
||||
Map<String, Object> tmplArgs = new HashMap<>(2);
|
||||
tmplArgs.put("order_id", order_id);
|
||||
tmplArgs.put("order_payment_amount", order_payment_amount);
|
||||
// 所有店铺管理员的发送邮件, 提醒商家:您有一笔新的订单 ${order_id},请及时处理。
|
||||
shopMessageTemplateService.aliyunSmsSend(shopKeeperMobiles, "SMS_476810378", tmplArgs);
|
||||
}
|
||||
|
||||
// 付款成功,对通知推广员进行提醒
|
||||
@ -6554,6 +6557,8 @@ public class ShopOrderBaseServiceImpl extends BaseServiceImpl<ShopOrderBaseMappe
|
||||
}
|
||||
info_row.setStore_id((Integer) base_row.get("store_id")); // 卖家店铺编号
|
||||
info_row.setSubsite_id(subsite_id); // 所属分站
|
||||
|
||||
|
||||
info_row.setBuyer_user_id((Integer) base_row.get("buyer_user_id")); // 买家编号
|
||||
info_row.setKind_id(kind_id); // 订单种类(ENUM): 1201-实物 ; 1202-虚拟
|
||||
info_row.setOrder_lock_status(0); // 锁定状态(BOOL):0-是正常;1-锁定
|
||||
@ -6575,7 +6580,7 @@ public class ShopOrderBaseServiceImpl extends BaseServiceImpl<ShopOrderBaseMappe
|
||||
info_row.setOrder_is_paid(StateCode.ORDER_PAID_STATE_NO); // 付款状态(BOOL):0-未付款;6-付款待审核;7-部分付款;1-已付款
|
||||
info_row.setOrder_is_out(StateCode.ORDER_PICKING_STATE_NO);
|
||||
info_row.setOrder_is_shipped(StateCode.ORDER_SHIPPED_STATE_NO);
|
||||
info_row.setOrder_is_received(0); // 收货状态(BOOL):0-未收货;1-已收货
|
||||
info_row.setOrder_is_received(CommonConstant.Disable); // 收货状态(BOOL):0-未收货;1-已收货
|
||||
info_row.setChain_id(ObjectUtil.equal(base_store_id, chain_store_id) ? chain_id : 0);
|
||||
info_row.setDelivery_type_id(delivery_type_id); // 配送方式
|
||||
info_row.setOrder_is_offline(order_is_offline); // 线下订单
|
||||
@ -7660,14 +7665,51 @@ public class ShopOrderBaseServiceImpl extends BaseServiceImpl<ShopOrderBaseMappe
|
||||
// 店铺统一设置的打包费
|
||||
data_row.setPacking_fee(packingFee);
|
||||
|
||||
// 平台最低配送费,单位(分)
|
||||
Integer innerMinDeliverFee = accountBaseConfigService.getInnerMinDeliveryFee();
|
||||
|
||||
// 平台最低配送费,单位(元)
|
||||
BigDecimal shoppingFeeInner = Convert.toBigDecimal(innerMinDeliverFee).divide(BigDecimal.valueOf(100));
|
||||
data_row.setOrder_shipping_fee_inner(shoppingFeeInner);
|
||||
|
||||
// 从 base_row 中获取应付款 order_payment_amount,计算平台和代理商的总计分账金额
|
||||
BigDecimal split_amount_from = NumberUtil.sub(order_payment_amount, _freight, packingFee);
|
||||
// BigDecimal split_amount_from = NumberUtil.sub(order_payment_amount, _freight, packingFee);
|
||||
// BigDecimal platform_fee = calculatePlatformAndAgentShareAmount(Convert.toInt(base_row.get("store_id")), split_amount_from);
|
||||
|
||||
BigDecimal storeSplitRatio = shopStoreBaseService.getStoreSplitRatio(store_id, false);
|
||||
|
||||
// 计算平台和代理商的分账金额
|
||||
Pair<Boolean, LklSeparateDTO> calcResult = lakalaApiService.calculateAndEvaluateSharingParams(
|
||||
CommonConstant.SeparateCalcMode_CanSeparateAmt,
|
||||
Convert.toInt(order_payment_amount.multiply(BigDecimal.valueOf(100))),
|
||||
innerMinDeliverFee,
|
||||
storeSplitRatio,
|
||||
BigDecimal.valueOf(0.01),
|
||||
null, null, null);
|
||||
|
||||
// 计算平台费
|
||||
BigDecimal platform_fee = calculatePlatformAndAgentShareAmount(Convert.toInt(base_row.get("store_id")), split_amount_from);
|
||||
data_row.setTotal_separate_value(platform_fee); // 从拉卡拉分账,给平台和代理商的总计分账金额
|
||||
data_row.setPlatform_fee(platform_fee);
|
||||
if (calcResult != null && calcResult.getFirst() && calcResult.getSecond() != null) {
|
||||
try {
|
||||
LklSeparateDTO lklSeparateDTO = calcResult.getSecond();
|
||||
// 确保分账金额不为负数
|
||||
BigDecimal totalSeparateAmount = BigDecimal.valueOf(lklSeparateDTO.getCanSeparateAmount())
|
||||
.divide(BigDecimal.valueOf(100), 2, RoundingMode.HALF_UP);
|
||||
BigDecimal platformFee = BigDecimal.valueOf(lklSeparateDTO.getPlatAmount() + lklSeparateDTO.getAgent1stAmount() + lklSeparateDTO.getAgent2ndAmount())
|
||||
.divide(BigDecimal.valueOf(100), 2, RoundingMode.HALF_UP);
|
||||
|
||||
// 防止负值
|
||||
data_row.setTotal_separate_value(totalSeparateAmount.max(BigDecimal.ZERO));
|
||||
data_row.setPlatform_fee(platformFee.max(BigDecimal.ZERO));
|
||||
} catch (Exception e) {
|
||||
log.warn("分账金额计算异常,使用默认值: {}", e.getMessage());
|
||||
data_row.setTotal_separate_value(BigDecimal.ZERO);
|
||||
data_row.setPlatform_fee(BigDecimal.ZERO);
|
||||
}
|
||||
} else {
|
||||
log.warn("拉卡拉分账参数计算失败,使用默认值");
|
||||
data_row.setTotal_separate_value(BigDecimal.ZERO);
|
||||
data_row.setPlatform_fee(BigDecimal.ZERO);
|
||||
}
|
||||
|
||||
Integer voucher_id = (Integer) order_voucher_row.get("voucher_id");
|
||||
String voucher_code = (String) order_voucher_row.get("voucher_code");
|
||||
|
||||
@ -33,8 +33,10 @@ import org.springframework.stereotype.Service;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.math.BigDecimal;
|
||||
import java.math.RoundingMode;
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
|
||||
@Slf4j
|
||||
@Service
|
||||
@ -596,4 +598,64 @@ public class ShopOrderLklServiceImpl extends BaseServiceImpl<ShopOrderLklMapper,
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取平台内部订单运费
|
||||
*
|
||||
* @param storeId 店铺Id
|
||||
* @param orderId 订单编号
|
||||
* @return 平台内部订单运费,单位:分
|
||||
*/
|
||||
@Override
|
||||
public Integer getOrderShippingFeeInner(Integer storeId, String orderId) {
|
||||
// 参数校验
|
||||
if (storeId == null || StringUtils.isBlank(orderId)) {
|
||||
log.warn("[获取平台内部订单运费] 参数校验失败:storeId或orderId为空, storeId={}, orderId={}", storeId, orderId);
|
||||
return 0;
|
||||
}
|
||||
|
||||
try {
|
||||
QueryWrapper<ShopOrderLkl> queryWrapper = new QueryWrapper<>();
|
||||
queryWrapper.select("shopping_fee_inner");
|
||||
queryWrapper.eq("store_id", storeId);
|
||||
queryWrapper.eq("order_id", orderId);
|
||||
|
||||
ShopOrderLkl shopOrderLkl = findOne(queryWrapper);
|
||||
Integer fee = Optional.ofNullable(shopOrderLkl)
|
||||
.map(ShopOrderLkl::getShopping_fee_inner)
|
||||
.orElse(0);
|
||||
|
||||
log.debug("[获取平台内部订单运费] 查询成功, storeId={}, orderId={}, fee={}", storeId, orderId, fee);
|
||||
return fee;
|
||||
} catch (Exception e) {
|
||||
log.error("[获取平台内部订单运费] 系统异常, storeId={}, orderId={}", storeId, orderId, e);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public BigDecimal getOrderShippingFeeInnerToDecimal(Integer storeId, String orderId) {
|
||||
// 参数校验
|
||||
if (storeId == null || StringUtils.isBlank(orderId)) {
|
||||
log.warn("[获取平台内部订单运费(Decimal)] 参数校验失败:storeId或orderId为空, storeId={}, orderId={}", storeId, orderId);
|
||||
return BigDecimal.ZERO;
|
||||
}
|
||||
|
||||
try {
|
||||
// 调用已有的方法获取运费(单位:分)
|
||||
Integer feeInCents = getOrderShippingFeeInner(storeId, orderId);
|
||||
|
||||
// 转换为元为单位的BigDecimal
|
||||
BigDecimal feeInYuan = new BigDecimal(feeInCents).divide(BigDecimal.valueOf(100), 2, RoundingMode.HALF_UP);
|
||||
|
||||
log.debug("[获取平台内部订单运费(Decimal)] 查询成功, storeId={}, orderId={}, feeInCents={}, feeInYuan={}",
|
||||
storeId, orderId, feeInCents, feeInYuan);
|
||||
return feeInYuan;
|
||||
} catch (Exception e) {
|
||||
log.error("[获取平台内部订单运费(Decimal)] 系统异常, storeId={}, orderId={}", storeId, orderId, e);
|
||||
return BigDecimal.ZERO;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@ -196,6 +196,10 @@ public class ShopOrderReturnServiceImpl extends BaseServiceImpl<ShopOrderReturnM
|
||||
@Autowired
|
||||
private LklOrderSeparateService lklOrderSeparateService;
|
||||
|
||||
@Lazy
|
||||
@Autowired
|
||||
private ShopOrderLklService shopOrderLklService;
|
||||
|
||||
@Lazy
|
||||
@Autowired
|
||||
private SFExpressApiService sfExpressApiService;
|
||||
@ -1603,7 +1607,7 @@ 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);
|
||||
|
||||
// 如果有打包费,最后的退款订单的退款金额加上 打包费
|
||||
@ -1611,18 +1615,19 @@ public class ShopOrderReturnServiceImpl extends BaseServiceImpl<ShopOrderReturnM
|
||||
order_data_row.getPacking_fee() != null &&
|
||||
order_data_row.getPacking_fee().compareTo(BigDecimal.ZERO) > 0) {
|
||||
// 退款金额+打包费
|
||||
BigDecimal order_refund_amount_add_fee = NumberUtil.add(
|
||||
BigDecimal orderRefundAmountAddFee = NumberUtil.add(
|
||||
order_data_row.getOrder_refund_amount(),
|
||||
order_data_row.getPacking_fee());
|
||||
// 最后一个退款订单如果有打包费,加上打包费
|
||||
return_row.setReturn_refund_amount(order_refund_amount_add_fee);
|
||||
return_row.setReturn_refund_amount(orderRefundAmountAddFee);
|
||||
logger.debug("已添加打包费到退款金额,订单ID: {}", order_id);
|
||||
}
|
||||
|
||||
// 有运费的订单
|
||||
|
||||
// 有运费的,重新生成一个运费退单
|
||||
if (order_data_row != null &&
|
||||
order_data_row.getOrder_shipping_fee() != null &&
|
||||
order_data_row.getOrder_shipping_fee().compareTo(BigDecimal.ZERO) > 0) {
|
||||
order_data_row.getOrder_shipping_fee_inner() != null &&
|
||||
order_data_row.getOrder_shipping_fee_inner().compareTo(BigDecimal.ZERO) > 0) {
|
||||
// 运费大于0的, 执行退运费操作, 有两种方案,1、生成退运费售后服务单; 2、直接执行退款
|
||||
// 1、生成独立退运费售后服务单,需注意运费是退给运费代理商的,需要获取代理商的交易单号
|
||||
|
||||
@ -1630,8 +1635,15 @@ public class ShopOrderReturnServiceImpl extends BaseServiceImpl<ShopOrderReturnM
|
||||
|
||||
Integer buyer_user_id = info_row.getBuyer_user_id();
|
||||
Integer storeId = info_row.getStore_id();
|
||||
// 订单运费
|
||||
BigDecimal order_shipping_fee = order_data_row.getOrder_shipping_fee();
|
||||
|
||||
// 平台内部订单运费
|
||||
BigDecimal orderShippingFeeInner = order_data_row.getOrder_shipping_fee_inner();
|
||||
if (orderShippingFeeInner == null || orderShippingFeeInner.compareTo(BigDecimal.ZERO) <= 0) {
|
||||
orderShippingFeeInner = shopOrderLklService.getOrderShippingFeeInnerToDecimal(storeId, order_id);
|
||||
}
|
||||
|
||||
return_order_shipping_fee_row.setReturn_refund_amount(orderShippingFeeInner); // 平台内部配送费退款金额
|
||||
|
||||
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);
|
||||
@ -1640,12 +1652,12 @@ 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_amount(order_shipping_fee);
|
||||
return_order_shipping_fee_row.setReturn_refund_point(NumberUtil.min(return_refund_point, order_shipping_fee));
|
||||
return_order_shipping_fee_row.setReturn_refund_point(NumberUtil.min(return_refund_point, orderShippingFeeInner));
|
||||
return_order_shipping_fee_row.setReturn_add_time(now); // 添加时间
|
||||
return_order_shipping_fee_row.setReturn_tel("");
|
||||
|
||||
// 店铺审核操作员
|
||||
Integer storeUserId = user != null ? user.getId() : 0;
|
||||
return_order_shipping_fee_row.setReturn_store_user_id(storeUserId);
|
||||
@ -1678,21 +1690,6 @@ public class ShopOrderReturnServiceImpl extends BaseServiceImpl<ShopOrderReturnM
|
||||
}
|
||||
logger.info("成功生成退运费订单,退单号: {}", return_id);
|
||||
|
||||
// 重要:加上单条运费退货单
|
||||
// return_rows.add(return_order_shipping_fee_row);
|
||||
|
||||
// // 修正退款总额 为 加上运费
|
||||
// ShopOrderData orderData = shopOrderDataService.get(order_id);
|
||||
// BigDecimal order_refund_amount = orderData.getOrder_refund_amount();
|
||||
// // 退款金额+运费
|
||||
// BigDecimal order_refund_amount_add_fee = NumberUtil.add(order_refund_amount, order_shipping_fee);
|
||||
// orderData.setOrder_refund_amount(order_refund_amount_add_fee);
|
||||
// if (!shopOrderDataService.edit(orderData)) {
|
||||
// throw new ApiException(I18nUtil._("修改订单退款总额(加运费)失败!"));
|
||||
// }
|
||||
//
|
||||
// // 最后一个退款订单如果有运费,加上运费
|
||||
// return_row.setReturn_refund_amount(order_refund_amount_add_fee);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1738,10 +1735,17 @@ public class ShopOrderReturnServiceImpl extends BaseServiceImpl<ShopOrderReturnM
|
||||
}
|
||||
|
||||
// 重要:执行退款操作
|
||||
try {
|
||||
if (!payService.doRefund(returnOrder)) {
|
||||
logger.error("执行退款操作失败!退单列表: {}", return_ids);
|
||||
throw new ApiException(ResultCode.FAILED);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
logger.error("执行退款操作异常!退单列表: {}", return_ids, e);
|
||||
// 根据业务需要决定是抛出异常触发回滚,还是其他处理方式
|
||||
throw new ApiException("退款服务调用异常: " + e.getMessage());
|
||||
}
|
||||
|
||||
logger.info("退款操作执行成功,退单列表: {}", return_ids);
|
||||
|
||||
// 更新退货单的退款完成状态和完成时间
|
||||
@ -2616,7 +2620,6 @@ public class ShopOrderReturnServiceImpl extends BaseServiceImpl<ShopOrderReturnM
|
||||
// 订单商品总金额
|
||||
BigDecimal orderGoodsAmount = orderItems.stream().map(ShopOrderItem::getOrder_item_amount).reduce(BigDecimal.ZERO, BigDecimal::add);
|
||||
|
||||
|
||||
if (StrUtil.isNotBlank(requestParams.getStr("order_return_vo"))) {
|
||||
orderReturnInputVo = JSONUtil.toBean(requestParams.getStr("order_return_vo"), OrderReturnInputVo.class);
|
||||
// 如果orderReturnInputVo中的order_id为空或与上层参数不一致,则使用上层参数中的order_id
|
||||
|
||||
@ -575,6 +575,7 @@
|
||||
<result property="order_product_amount" column="order_product_amount"/>
|
||||
<result property="order_payment_amount" column="order_payment_amount"/>
|
||||
<result property="order_shipping_fee" column="order_shipping_fee"/>
|
||||
<result property="order_shipping_fee_inner" column="order_shipping_fee_inner"/>
|
||||
<result property="packing_fee" column="packing_fee"/>
|
||||
<!--总计优惠金额 order_discount_amount + order_voucher_price + order_points_fee + order_adjust_fee-->
|
||||
<result property="total_discount_amount" column="total_discount_amount"/>
|
||||
@ -780,11 +781,12 @@
|
||||
AS is_new_buyer,
|
||||
oi.payment_time,
|
||||
od.order_shipping_fee,
|
||||
IFNULL(od.order_shipping_fee_inner, 0) as order_shipping_fee_inner,
|
||||
<!--总计优惠金额 order_discount_amount + order_voucher_price + order_points_fee + order_adjust_fee-->
|
||||
(od.order_discount_amount + od.voucher_price + od.order_points_fee + od.order_adjust_fee) as
|
||||
total_discount_amount,
|
||||
<!--预计收入:订单原价金额-总计优惠金额-配送费-平台费 + 打包费-->
|
||||
(ob.order_product_amount-od.order_discount_amount-od.voucher_price-od.order_points_fee-od.order_adjust_fee-od.platform_fee-od.order_shipping_fee+od.packing_fee)
|
||||
(ob.order_product_amount-od.order_discount_amount-od.voucher_price-od.order_points_fee-od.order_adjust_fee-od.platform_fee-order_shipping_fee_inner+od.packing_fee)
|
||||
as order_income_amount,
|
||||
od.platform_fee,
|
||||
od.packing_fee,
|
||||
|
||||
@ -7,7 +7,7 @@
|
||||
, order_desc, order_delay_time, delivery_type_id, delivery_time_id, delivery_time, delivery_time_rang,
|
||||
delivery_time_h, delivery_time_i, delivery_istimer, invoice_type_id, invoice_company_code, order_invoice_title,
|
||||
order_message, order_item_amount, order_discount_amount, order_adjust_fee, order_points_fee,
|
||||
order_shipping_fee_amount, order_shipping_fee, platform_fee, packing_fee, voucher_id, voucher_number, voucher_price, redpacket_id,
|
||||
order_shipping_fee_amount, order_shipping_fee,order_shipping_fee_inner, platform_fee, packing_fee, voucher_id, voucher_number, voucher_price, redpacket_id,
|
||||
redpacket_number, redpacket_price, order_redpacket_price, order_resource_ext1, order_resource_ext2,
|
||||
order_resource_ext3, trade_payment_money, trade_payment_recharge_card, trade_payment_credit,
|
||||
order_refund_status, order_refund_amount, order_refund_agree_amount, order_return_status, order_return_num,
|
||||
|
||||
Loading…
Reference in New Issue
Block a user