同一商户分账合并,增加打票机打印日志

This commit is contained in:
Jack 2025-10-18 10:12:16 +08:00
parent 4774ab8aab
commit b7701a8685
7 changed files with 93 additions and 67 deletions

View File

@ -62,7 +62,7 @@ public class LklSeparateWithTotalAmountDTO {
// 测试用例1: 所有参与方都参与分账符合比例要求
System.out.println("=== 测试用例1: 所有参与方都参与分账 ===");
LklSeparateWithTotalAmountDTO dto1 = new LklSeparateWithTotalAmountDTO();
dto1.setTotalSeparateAmount(5500); // 总金额100元(10000分)
dto1.setTotalSeparateAmount(1696); // 总金额100元(10000分)
dto1.setShippingFee(500);
// dto1.setRefCanSeparateAmount(1496);
dto1.setLklRatio(new BigDecimal("0.0025")); // 拉卡拉分账比例0.25%

View File

@ -208,9 +208,10 @@ public interface LakalaApiService {
* @param lklMerchantNo 拉卡拉商户号
* @param receiveTradeNo 收货交易号对应拉卡拉的trade_no
* @param receiveLogNo 收货流水号对应拉卡拉的log_no
* @param logDate posp日期yyyyMMdd查清结算用, 一般是值交易完成日期确认收货的日期
* @return Pair<Boolean, String> 处理结果对first为是否成功second为结果描述信息
*/
Pair<Boolean, String> innerDoOrderSeparateByMerchantAndLogNo(String lklMerchantNo, String receiveTradeNo, String receiveLogNo);
Pair<Boolean, String> innerDoOrderSeparateByMerchantAndLogNo(String lklMerchantNo, String receiveTradeNo, String receiveLogNo, String logDate);
/**
* 分账结果通知

View File

@ -11,6 +11,7 @@ package com.suisung.mall.shop.lakala.service.impl;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.convert.Convert;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONArray;
@ -823,7 +824,15 @@ public class LakalaApiServiceImpl implements LakalaApiService {
// 分账用途
String logNo = paramsJSON.getStr("log_no");
String tradeNo = paramsJSON.getStr("trade_no");
log.debug("[确认收货通知] 获取基础交易信息: logNo={} tradeNo={}", logNo, tradeNo);
String tradeTime = paramsJSON.getStr("trade_time"); // 实际交易完成时间yyyyMMddHHmmss
// 直接截取前8位获取日期部分
String logDate = tradeTime != null && tradeTime.length() >= 8 ? tradeTime.substring(0, 8) : null;
if (logDate == null) {
logDate = DateUtil.format(new Date(), "yyyyMMdd"); // 当前时间
}
log.debug("[确认收货通知] 获取基础交易信息: logNo={} tradeNo={} logDate={}", logNo, tradeNo, logDate);
// 查询用途
String originTradeNo = paramsJSON.getStr("origin_trade_no");
@ -900,7 +909,7 @@ public class LakalaApiServiceImpl implements LakalaApiService {
// 重要准备发起分账指令
log.info("[确认收货通知] 开始发起分账指令: merchantNo={}, receiveTradeNo={}, logNo={}",
merchantNo, shopOrderLkl.getLkl_receive_trade_no(), logNo);
Pair<Boolean, String> separateResult = innerDoOrderSeparateByMerchantAndLogNo(merchantNo, shopOrderLkl.getLkl_receive_trade_no(), shopOrderLkl.getLkl_receive_log_no());
Pair<Boolean, String> separateResult = innerDoOrderSeparateByMerchantAndLogNo(merchantNo, shopOrderLkl.getLkl_receive_trade_no(), shopOrderLkl.getLkl_receive_log_no(), logDate);
if (!separateResult.getFirst()) {
shopOrderLkl.setSeparate_msg(separateResult.getSecond());
@ -2451,15 +2460,16 @@ public class LakalaApiServiceImpl implements LakalaApiService {
* @param lklMerchantNo 拉卡拉商户号
* @param receiveTradeNo 收货交易号对应拉卡拉的trade_no
* @param receiveLogNo 收货流水号对应拉卡拉的log_no
* @param logDate posp日期yyyyMMdd查清结算用, 一般是值交易完成日期确认收货的日期
* @return Pair<Boolean, String> 处理结果对first为是否成功second为结果描述信息
*/
@Transactional
@Override
public Pair<Boolean, String> innerDoOrderSeparateByMerchantAndLogNo(String lklMerchantNo, String receiveTradeNo, String receiveLogNo) {
public Pair<Boolean, String> innerDoOrderSeparateByMerchantAndLogNo(String lklMerchantNo, String receiveTradeNo, String receiveLogNo, String logDate) {
// 1. 输入参数校验
if (StrUtil.hasBlank(lklMerchantNo, receiveTradeNo, receiveLogNo)) {
log.warn("[分账操作] 参数校验失败:缺少必要参数, lklMerchantNo={}, receiveTradeNo={}, receiveLogNo={}",
lklMerchantNo, receiveTradeNo, receiveLogNo);
if (StrUtil.hasBlank(lklMerchantNo, receiveTradeNo, receiveLogNo, logDate)) {
log.warn("[分账操作] 参数校验失败:缺少必要参数, lklMerchantNo={}, receiveTradeNo={}, receiveLogNo={}, logDate={}",
lklMerchantNo, receiveTradeNo, receiveLogNo, logDate);
return Pair.of(false, "缺少必要参数");
}
@ -2639,7 +2649,7 @@ public class LakalaApiServiceImpl implements LakalaApiService {
receiver.setSeparateValue(Convert.toStr(merchantAmount));
recvDatas.add(receiver);
}
// 是否有二级代理商
boolean has2ndAgent = CheckUtil.isNotEmpty(agent2ndSplitRatio) && agent2ndReceiver != null &&
StrUtil.isNotBlank(agent2ndReceiver.getReceiver_no()) &&
@ -2695,7 +2705,7 @@ public class LakalaApiServiceImpl implements LakalaApiService {
separateRequest.setMerchantNo(merchantNo);
separateRequest.setOutSeparateNo(shopOrderLkl.getOut_separate_no());
separateRequest.setLogNo(shopOrderLkl.getLkl_receive_log_no()); // 使用确认收货流水号作为分账流水号
separateRequest.setLogDate(shopOrderLkl.getLkl_log_date());
separateRequest.setLogDate(logDate); // 重要确认收货后的交易时间
separateRequest.setTotalAmt(refCanSeparateAmt.toString());
separateRequest.setLklOrgNo(orgCode);
separateRequest.setCalType("0"); // 0- 按照指定金额1- 按照指定比例默认 0

View File

@ -519,11 +519,11 @@ public class ShopOrderLklServiceImpl extends BaseServiceImpl<ShopOrderLklMapper,
*
* @param lklReceiveLogNo 拉卡拉确认收货对账单流水号
* @param separateStatus 分账状态1-已分账2-未分账3-分账已失败
* @param separateRemark 分账问题备注
* @param separateMsg 分账问题备注
* @return 更新结果 true-成功 false-失败
*/
@Override
public Boolean updateSeparateStatusByReceiveLogNo(String lklReceiveLogNo, Integer separateStatus, String separateRemark) {
public Boolean updateSeparateStatusByReceiveLogNo(String lklReceiveLogNo, Integer separateStatus, String separateMsg) {
// 检查参数是否全部为空
if (StringUtils.isBlank(lklReceiveLogNo) || separateStatus == null) {
log.warn("[更新分账状态] 参数校验失败:缺少必要参数, lklReceiveLogNo={}, separateStatus={}", lklReceiveLogNo, separateStatus);
@ -536,8 +536,8 @@ public class ShopOrderLklServiceImpl extends BaseServiceImpl<ShopOrderLklMapper,
UpdateWrapper<ShopOrderLkl> updateWrapper = new UpdateWrapper<>();
updateWrapper.eq("lkl_receive_log_no", lklReceiveLogNo);
updateWrapper.set("separate_status", separateStatus);
if (StrUtil.isNotBlank(separateRemark)) {
updateWrapper.set("separate_remark", separateRemark);
if (StrUtil.isNotBlank(separateMsg)) {
updateWrapper.set("separate_msg", separateMsg);
}
boolean result = update(updateWrapper);

View File

@ -20,6 +20,14 @@ public interface ShopStoreInfoService extends IBaseService<ShopStoreInfo> {
Map getStoreInfoById(Integer store_id);
/**
* 根据店铺id获取店铺信息
*
* @param storeId
* @return
*/
ShopStoreInfo getShopStoreInfoByStoreId(Integer storeId);
Map getInfoList(QueryWrapper<ShopStoreInfo> queryWrapper, Integer pageNum, Integer pageSize);
/**

View File

@ -80,7 +80,6 @@ import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.Serializable;
@ -176,9 +175,6 @@ public class ShopStoreBaseServiceImpl extends BaseServiceImpl<ShopStoreBaseMappe
@Autowired
private ShopPageModuleService shopPageModuleService;
@Lazy
@Resource
private ShopStoreSameCityTransportBaseService storeSameCityTransportBaseService;
@Lazy
@Autowired
private ShopMchEntryService shopMchEntryService;
@Autowired
@ -3277,54 +3273,58 @@ public class ShopStoreBaseServiceImpl extends BaseServiceImpl<ShopStoreBaseMappe
return Pair.of(0, "店铺ID获取失败");
}
// 创建店铺信息
ShopStoreInfo shopStoreInfo = new ShopStoreInfo();
shopStoreInfo.setStore_id(storeId);
shopStoreInfo.setStore_start_time(DateUtil.date());
shopStoreInfo.setStore_end_time(DateUtil.offsetDay(DateUtil.date(), 365 * 5));
shopStoreInfo.setStore_opening_hours("07:30");
shopStoreInfo.setStore_close_hours("23:00");
shopStoreInfo.setStore_discount(BigDecimal.valueOf(10));
shopStoreInfo.setStore_banner(storeFacadeImage);
// 处理联系人信息
String contact_mobile = StrUtil.isNotBlank(shopMchEntry.getLegal_person_mobile()) ?
shopMchEntry.getLegal_person_mobile() : shopMchEntry.getLogin_mobile();
shopStoreInfo.setStore_tel(contact_mobile);
shopStoreInfo.setContact_mobile(contact_mobile);
shopStoreInfo.setContact_name(shopMchEntry.getContact_name());
// 构建幻灯片
JSONArray list = new JSONArray();
if (StrUtil.isNotBlank(storeFacadeImage)) {
JSONObject slide = new JSONObject();
slide.put("img", storeFacadeImage);
slide.put("name", "店铺门面照片");
slide.put("check", true);
slide.put("url", "https://www.gpxscs.cn");
list.put(slide);
}
if (StrUtil.isNotBlank(shopMchEntry.getEnvironment_image())) {
JSONObject slide = new JSONObject();
slide.put("img", shopMchEntry.getEnvironment_image());
slide.put("name", "店铺环境照片");
slide.put("check", true);
slide.put("url", "https://www.gpxscs.cn");
list.put(slide);
}
shopStoreInfo.setStore_slide(list.toString());
// 创建店铺信息
ShopStoreInfo shopStoreInfo = shopStoreInfoService.getShopStoreInfoByStoreId(storeId); // new ShopStoreInfo();
if (shopStoreInfo == null) {
shopStoreInfo = new ShopStoreInfo();
shopStoreInfo.setStore_id(storeId);
shopStoreInfo.setStore_start_time(DateUtil.date());
shopStoreInfo.setStore_end_time(DateUtil.offsetDay(DateUtil.date(), 365 * 5));
shopStoreInfo.setStore_opening_hours("08:00");
shopStoreInfo.setStore_close_hours("21:30");
shopStoreInfo.setStore_discount(BigDecimal.valueOf(10));
shopStoreInfo.setStore_banner(storeFacadeImage);
shopStoreInfo.setStore_tel(contact_mobile);
shopStoreInfo.setContact_mobile(contact_mobile);
shopStoreInfo.setContact_name(shopMchEntry.getContact_name());
if (shopMchEntry.getStore_address() != null) {
shopStoreInfo.setStore_address(shopMchEntry.getStore_address());
}
shopStoreInfo.setStore_state_id(StateCode.STORE_STATE_YES);
if (!shopStoreInfoService.save(shopStoreInfo)) {
logger.error("生成店铺新增店铺info失败");
if (Boolean.TRUE.equals(allowThrown)) {
throw new ApiException("新增店铺信息失败");
// 构建幻灯片
JSONArray list = new JSONArray();
if (StrUtil.isNotBlank(storeFacadeImage)) {
JSONObject slide = new JSONObject();
slide.put("img", storeFacadeImage);
slide.put("name", "店铺门面照片");
slide.put("check", true);
slide.put("url", "https://www.gpxscs.cn");
list.put(slide);
}
if (StrUtil.isNotBlank(shopMchEntry.getEnvironment_image())) {
JSONObject slide = new JSONObject();
slide.put("img", shopMchEntry.getEnvironment_image());
slide.put("name", "店铺环境照片");
slide.put("check", true);
slide.put("url", "https://www.gpxscs.cn");
list.put(slide);
}
shopStoreInfo.setStore_slide(list.toString());
if (shopMchEntry.getStore_address() != null) {
shopStoreInfo.setStore_address(shopMchEntry.getStore_address());
}
shopStoreInfo.setStore_state_id(StateCode.STORE_STATE_YES);
if (!shopStoreInfoService.save(shopStoreInfo)) {
logger.error("生成店铺新增店铺info失败");
if (Boolean.TRUE.equals(allowThrown)) {
throw new ApiException("新增店铺信息失败");
}
return Pair.of(0, "新增店铺信息失败");
}
return Pair.of(0, "新增店铺信息失败");
}
// 创建店铺公司信息
@ -3887,14 +3887,14 @@ public class ShopStoreBaseServiceImpl extends BaseServiceImpl<ShopStoreBaseMappe
bizState = CommonConstant.Disable2;
}
String store_opening_hours=getParameter("store_opening_hours");
String store_close_hours=getParameter("store_close_hours");
String store_opening_hours = getParameter("store_opening_hours");
String store_close_hours = getParameter("store_close_hours");
try {
if(StringUtils.isNotEmpty(store_close_hours)){
UpdateWrapper<ShopStoreInfo> shopStoreInfoUpdateWrapper=new UpdateWrapper<>();
shopStoreInfoUpdateWrapper.eq("store_id",storeId);
shopStoreInfoUpdateWrapper.set("store_opening_hours",store_opening_hours);
shopStoreInfoUpdateWrapper.set("store_close_hours",store_close_hours);
if (StringUtils.isNotEmpty(store_close_hours)) {
UpdateWrapper<ShopStoreInfo> shopStoreInfoUpdateWrapper = new UpdateWrapper<>();
shopStoreInfoUpdateWrapper.eq("store_id", storeId);
shopStoreInfoUpdateWrapper.set("store_opening_hours", store_opening_hours);
shopStoreInfoUpdateWrapper.set("store_close_hours", store_close_hours);
shopStoreInfoService.update(shopStoreInfoUpdateWrapper);
}
// 使用 UpdateWrapper 更新店铺营业状态

View File

@ -53,6 +53,13 @@ public class ShopStoreInfoServiceImpl extends BaseServiceImpl<ShopStoreInfoMappe
return shopStoreInfoMapper.getStoreInfoById(store_id);
}
@Override
public ShopStoreInfo getShopStoreInfoByStoreId(Integer storeId) {
QueryWrapper<ShopStoreInfo> queryWrapper = new QueryWrapper<>();
queryWrapper.eq("store_id", storeId);
return findOne(queryWrapper);
}
@Override
public Map getInfoList(QueryWrapper<ShopStoreInfo> queryWrapper, Integer pageNum, Integer pageSize) {
Page<ShopStoreInfo> lists = lists(queryWrapper, pageNum, pageSize);