diff --git a/ShopOrderBaseServiceImpl.java b/ShopOrderBaseServiceImpl.java
deleted file mode 100644
index 7de57f26..00000000
--- a/ShopOrderBaseServiceImpl.java
+++ /dev/null
@@ -1,119 +0,0 @@
-/**
- * 确认收货处理
- * @param order_ids 订单ID列表
- * @param order_rows 订单数据列表
- * @return 是否处理成功
- */
-public boolean receive(List order_ids, List order_rows) {
- // 检测数据是否合法,过滤允许修改的数据
- if (CollUtil.isEmpty(order_ids)) {
- throw new ApiException(I18nUtil._("请选择需要确认收货的订单!"));
- }
-
- if (CollUtil.isEmpty(order_rows)) {
- order_rows = gets(order_ids);
- }
-
- List receive_id_row = new ArrayList<>();
-
- for (ShopOrderBase order_row : order_rows) {
- // 判断订单是否可以确认收货
- if (ifReceive(order_row.getOrder_state_id())) {
- receive_id_row.add(order_row.getOrder_id());
-
- // 增加积分和经验
- // todo 目前付款支付积分,此处为收货后发放
- Integer user_id = order_row.getBuyer_user_id();
- String order_id = order_row.getOrder_id();
- Integer store_id = order_row.getStore_id();
-
- ShopOrderData order_data_row = shopOrderDataService.get(order_id);
- BigDecimal order_points_add = order_data_row.getOrder_points_add();
-
- BigDecimal order_points_add_all = order_points_add.add(order_data_row.getOrder_double_points_add());
-
- // 发放购物积分
- if (CheckUtil.isNotEmpty(order_points_add_all)) {
- String desc = String.format(I18nUtil._("购物获取积分 %s,订单号 %s"), order_points_add_all, order_id);
- if (!payService.points(user_id, order_points_add_all, PointsType.POINTS_TYPE_CONSUME, desc, store_id, null, order_id)) {
- throw new ApiException(I18nUtil._("积分操作失败!"));
- }
- }
-
- // todo 根据送花郎插件是否开启显示是否需要分钱给不同商户
- /*
- boolean hall_enable = accountBaseConfigService.getConfig("hall_enable", false);
- if (hall_enable) {
- BigDecimal order_commission_fee = order_data_row.getOrder_commission_fee();
- sendMoneyForTransfer(order_row, order_commission_fee);
- }
- */
-
- // 分销功能处理
- String fx_settle_type = accountBaseConfigService.getConfig("fx_settle_type", "receive");
- if (StrUtil.equals(fx_settle_type, "receive")) {
- // todo settleDistributionUserOrder
- shopDistributionUserOrderService.settleDistributionUserOrder(order_id);
- }
-
- // 重要:拉卡拉给平台和代理商分账
- Pair retOrderSeparateRet = lakalaApiService.innerDoOrderSeparate(order_row.getOrder_id(), Convert.toStr(order_row.getStore_id()));
- if (!retOrderSeparateRet.getFirst()) {
- throw new ApiException(I18nUtil._("平台或代理商分账失败: " + retOrderSeparateRet.getSecond()));
- }
-
- // 统计总营业额
- ShopStoreAnalytics analytics_row = shopStoreAnalyticsService.get(store_id);
- BigDecimal order_payment_amount = order_row.getOrder_payment_amount();
- analytics_row.setStore_trade_amount(NumberUtil.add(analytics_row.getStore_trade_amount(), order_payment_amount));
- if (!shopStoreAnalyticsService.edit(analytics_row)) {
- throw new ApiException(ResultCode.FAILED);
- }
- }
- }
-
- // 检查是否有符合条件的订单
- if (CollUtil.isEmpty(receive_id_row)) {
- throw new ApiException(I18nUtil._("无符合确认收货条件的订单!"));
- }
-
- // 修改订单状态, 随机去一个订单获取店铺编号
- ShopOrderBase shopOrderBase = order_rows.get(0);
- Integer store_id = shopOrderBase.getStore_id();
- editNextState(receive_id_row, store_id, StateCode.ORDER_STATE_SHIPPED, order_rows, 0);
-
- // 如果是商家,且启用供应商,则商家看到供应商店铺商品 store_type = 2
- boolean ifSupplierMarket = accountBaseConfigService.ifSupplierMarket();
- UserDto user = getCurrentUser();
- store_id = user != null ? Convert.toInt(user.getStore_id(), 0) : 0;
-
- // 处理供应商市场的库存增加逻辑
- if (ifSupplierMarket && CheckUtil.isNotEmpty(store_id)) {
- // 供应商商品,增加商家库存
- QueryWrapper itemQueryWrapper = new QueryWrapper<>();
- itemQueryWrapper.in("order_id", receive_id_row);
- List order_item_rows = shopOrderItemService.find(itemQueryWrapper);
-
- List item_src_ids = order_item_rows.stream().map(ShopOrderItem::getItem_id).distinct().collect(Collectors.toList());
- if (CollUtil.isNotEmpty(item_src_ids)) {
- QueryWrapper productItemQueryWrapper = new QueryWrapper<>();
- productItemQueryWrapper.in("item_src_id", item_src_ids).eq("store_id", store_id);
- List product_item_rows = shopProductItemService.find(productItemQueryWrapper);
-
- // 更新供应商商品库存
- for (ShopProductItem product_item_row : product_item_rows) {
- String item_src_id = product_item_row.getItem_src_id();
- Optional orderItemOpl = order_item_rows.stream().filter(s -> ObjectUtil.equal(s.getItem_id(), item_src_id)).findFirst();
- if (orderItemOpl.isPresent()) {
- ShopOrderItem shopOrderItem = orderItemOpl.get();
- Integer order_item_quantity = shopOrderItem.getOrder_item_quantity();
- product_item_row.setItem_quantity(product_item_row.getItem_quantity() + order_item_quantity);
- if (!shopProductItemService.edit(product_item_row)) {
- throw new ApiException(ResultCode.FAILED);
- }
- }
- }
- }
- }
- return true;
-}
\ No newline at end of file
diff --git a/mall-common/src/main/java/com/suisung/mall/common/modules/lakala/LklLedgerMember.java b/mall-common/src/main/java/com/suisung/mall/common/modules/lakala/LklLedgerMember.java
index adbaf357..d957bbd3 100644
--- a/mall-common/src/main/java/com/suisung/mall/common/modules/lakala/LklLedgerMember.java
+++ b/mall-common/src/main/java/com/suisung/mall/common/modules/lakala/LklLedgerMember.java
@@ -44,6 +44,7 @@ public class LklLedgerMember implements Serializable {
private String ele_contract_no;
private String split_launch_mode;
private String settle_type;
+ private String settle_type_draw;
private String split_rule_source;
private String ret_url;
private String apply_id;
diff --git a/mall-common/src/main/java/com/suisung/mall/common/modules/lakala/LklOrderDraw.java b/mall-common/src/main/java/com/suisung/mall/common/modules/lakala/LklOrderDraw.java
new file mode 100644
index 00000000..d41b1abf
--- /dev/null
+++ b/mall-common/src/main/java/com/suisung/mall/common/modules/lakala/LklOrderDraw.java
@@ -0,0 +1,185 @@
+/*
+ * Copyright (c) 2025. Lorem ipsum dolor sit amet, consectetur adipiscing elit.
+ * Morbi non lorem porttitor neque feugiat blandit. Ut vitae ipsum eget quam lacinia accumsan.
+ * Etiam sed turpis ac ipsum condimentum fringilla. Maecenas magna.
+ * Proin dapibus sapien vel ante. Aliquam erat volutpat. Pellentesque sagittis ligula eget metus.
+ * Vestibulum commodo. Ut rhoncus gravida arcu.
+ */
+
+package com.suisung.mall.common.modules.lakala;
+
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.experimental.Accessors;
+
+import java.util.Date;
+
+@Data
+@EqualsAndHashCode(callSuper = false)
+@Accessors(chain = true)
+@TableName("lkl_order_draw")
+@ApiModel(value = "拉卡拉订单分账金额提现表实体", description = "拉卡拉订单分账金额提现表实体")
+public class LklOrderDraw {
+
+ @TableId(value = "id", type = IdType.INPUT)
+ @ApiModelProperty(value = "自增Id", example = "1")
+ private Long id;
+
+ /**
+ * 钱包ID
+ */
+ @ApiModelProperty(value = "钱包ID", example = "W123456789")
+ private String ewallet_id;
+
+ /**
+ * 请求日期
+ */
+ @ApiModelProperty(value = "请求日期", example = "20231001")
+ private String req_date;
+
+ /**
+ * 提款流水号
+ */
+ @ApiModelProperty(value = "提款流水号", example = "DRAW2023100100001")
+ private String draw_jnl;
+
+ /**
+ * 提款金额(单位:元)含手续费
+ */
+ @ApiModelProperty(value = "提款金额(单位:元)含手续费", example = "1000.00")
+ private String draw_amt;
+
+ /**
+ * 手续费
+ */
+ @ApiModelProperty(value = "手续费", example = "10.00")
+ private String draw_fee;
+
+ /**
+ * 提款模式
+ */
+ @ApiModelProperty(value = "提款模式", example = "ONLINE")
+ private String draw_mode;
+
+ /**
+ * 结算模式(01主动提款 02余额自动结算 03 交易自动结算)
+ */
+ @ApiModelProperty(value = "结算模式(01主动提款 02余额自动结算 03 交易自动结算)", example = "01")
+ private String batch_auto_settle;
+
+ /**
+ * 自动结算批次号
+ */
+ @ApiModelProperty(value = "自动结算批次号", example = "BATCH20231001001")
+ private String batch_no;
+
+ /**
+ * 结算账户号
+ */
+ @ApiModelProperty(value = "结算账户号", example = "6222021234567890123")
+ private String acc_no;
+
+ /**
+ * 结算账户名
+ */
+ @ApiModelProperty(value = "结算账户名", example = "张三")
+ private String acct_name;
+
+ /**
+ * 提款状态:DRAW.ACCEPTED 提款已受理;DRAW.FREEZE 提款冻结;
+ * DRAW.PROCESSING 提款处理中;DRAW.SUCCESS 提款成功;DRAW.FAILED 提款失败
+ */
+ @ApiModelProperty(value = "提款状态:DRAW.ACCEPTED(提款已受理)、DRAW.FREEZE(提款冻结)、DRAW.PROCESSING(提款处理中)、DRAW.SUCCESS(提款成功)、DRAW.FAILED(提款失败)",
+ example = "DRAW.SUCCESS")
+ private String draw_state;
+
+ /**
+ * 结果信息
+ */
+ @ApiModelProperty(value = "结果信息", example = "提款成功")
+ private String meno;
+
+ /**
+ * 商户订单号
+ */
+ @ApiModelProperty(value = "商户订单号", example = "MER2023100100001")
+ private String mer_order_no;
+
+ /**
+ * 结算流水号
+ */
+ @ApiModelProperty(value = "结算流水号", example = "SETTLE2023100100001")
+ private String settle_no;
+
+ /**
+ * 银行行号
+ */
+ @ApiModelProperty(value = "银行行号", example = "102100099999")
+ private String bank_no;
+
+ /**
+ * 银行名称
+ */
+ @ApiModelProperty(value = "银行名称", example = "中国工商银行")
+ private String nbk_name;
+
+ /**
+ * 商户号
+ */
+ @ApiModelProperty(value = "商户号", example = "M1234567890")
+ private String merc_id;
+
+ /**
+ * 完成时间
+ */
+ @ApiModelProperty(value = "完成时间", example = "2023-10-01 12:00:00")
+ private String complete_time;
+
+ /**
+ * 创建时间
+ */
+ @ApiModelProperty(value = "创建时间", example = "2023-10-01 11:30:00")
+ private String created_time;
+
+ /**
+ * 异步通知地址
+ */
+ @ApiModelProperty(value = "异步通知地址", example = "https://api.example.com/notify")
+ private String notify_url;
+
+ /**
+ * 异步通知返回的JSON数据
+ */
+ @ApiModelProperty(value = "异步通知返回的JSON数据", example = "{\"code\":\"0000\",\"msg\":\"success\"}")
+ private String notify_resp;
+
+ @ApiModelProperty(value = "备注信息")
+ private String remark;
+
+ @ApiModelProperty(value = "摘要")
+ private String summary;
+
+ /**
+ * 记录状态:1-有效;2-无效;
+ */
+ @ApiModelProperty(value = "记录状态:1-有效;2-无效", example = "1")
+ private Integer status;
+
+ /**
+ * 新建时间
+ */
+ @ApiModelProperty(value = "新建时间", example = "2023-10-01 11:30:00")
+ private Date created_at;
+
+ /**
+ * 更新时间
+ */
+ @ApiModelProperty(value = "更新时间", example = "2023-10-01 12:00:00")
+ private Date updated_at;
+}
+
diff --git a/mall-common/src/main/resources/application-dev.yml b/mall-common/src/main/resources/application-dev.yml
index e9b9540a..e23eb9cf 100644
--- a/mall-common/src/main/resources/application-dev.yml
+++ b/mall-common/src/main/resources/application-dev.yml
@@ -30,8 +30,8 @@ redis:
baidu:
map:
- app_id: 116444176
- ak: qWKt2xbrqXsp2yK35YYXVBNZgrbiCG5v
+ app_id: 120196890
+ ak: YzRPLAOTYyCFVjvlh2vxnaUnH4jPjufM
url: https://api.map.baidu.com/geoconv/v2/?
getui: # 个推配置
diff --git a/mall-common/src/main/resources/application-local.yml b/mall-common/src/main/resources/application-local.yml
index 753e7f0d..6c7ca24d 100644
--- a/mall-common/src/main/resources/application-local.yml
+++ b/mall-common/src/main/resources/application-local.yml
@@ -30,8 +30,8 @@ redis:
baidu:
map:
- app_id: 116444176
- ak: qWKt2xbrqXsp2yK35YYXVBNZgrbiCG5v
+ app_id: 120196890
+ ak: YzRPLAOTYyCFVjvlh2vxnaUnH4jPjufM
url: https://api.map.baidu.com/geoconv/v2/?
getui: # 个推配置
push:
diff --git a/mall-common/src/main/resources/application-prod.yml b/mall-common/src/main/resources/application-prod.yml
index 736778a7..f3d810c5 100644
--- a/mall-common/src/main/resources/application-prod.yml
+++ b/mall-common/src/main/resources/application-prod.yml
@@ -30,8 +30,8 @@ redis:
baidu:
map:
- app_id: 116444176
- ak: qWKt2xbrqXsp2yK35YYXVBNZgrbiCG5v
+ app_id: 120196890
+ ak: YzRPLAOTYyCFVjvlh2vxnaUnH4jPjufM
url: https://api.map.baidu.com/geoconv/v2/?
getui: # 个推配置
push:
diff --git a/mall-common/src/main/resources/application-test.yml b/mall-common/src/main/resources/application-test.yml
index 82bb8d56..322ead6c 100644
--- a/mall-common/src/main/resources/application-test.yml
+++ b/mall-common/src/main/resources/application-test.yml
@@ -30,8 +30,8 @@ redis:
baidu:
map:
- app_id: 116444176
- ak: qWKt2xbrqXsp2yK35YYXVBNZgrbiCG5v
+ app_id: 120196890
+ ak: YzRPLAOTYyCFVjvlh2vxnaUnH4jPjufM
url: https://api.map.baidu.com/geoconv/v2/?
getui: # 个推配置
push:
diff --git a/mall-common/src/main/resources/application-uat.yml b/mall-common/src/main/resources/application-uat.yml
index 38e9680d..df4afea2 100644
--- a/mall-common/src/main/resources/application-uat.yml
+++ b/mall-common/src/main/resources/application-uat.yml
@@ -30,8 +30,8 @@ redis:
baidu:
map:
- app_id: 116444176
- ak: qWKt2xbrqXsp2yK35YYXVBNZgrbiCG5v
+ app_id: 120196890
+ ak: YzRPLAOTYyCFVjvlh2vxnaUnH4jPjufM
url: https://api.map.baidu.com/geoconv/v2/?
getui: # 个推配置
diff --git a/mall-shop/src/main/java/com/suisung/mall/shop/base/service/AccountBaseConfigService.java b/mall-shop/src/main/java/com/suisung/mall/shop/base/service/AccountBaseConfigService.java
index d3997e94..9256981d 100644
--- a/mall-shop/src/main/java/com/suisung/mall/shop/base/service/AccountBaseConfigService.java
+++ b/mall-shop/src/main/java/com/suisung/mall/shop/base/service/AccountBaseConfigService.java
@@ -50,4 +50,19 @@ public interface AccountBaseConfigService extends IBaseService configs);
boolean saveOrUpdate(AccountBaseConfig config);
+
+ /**
+ * 获取系统配置
+ *
+ * @param configKey
+ * @return
+ */
+ String getSystemConfig(String configKey);
+
+ /**
+ * 获取平台内部最低配送费,单位(分)
+ *
+ * @return
+ */
+ Integer getInnerMinDeliveryFee();
}
diff --git a/mall-shop/src/main/java/com/suisung/mall/shop/base/service/ShopBaseDistrictService.java b/mall-shop/src/main/java/com/suisung/mall/shop/base/service/ShopBaseDistrictService.java
index ce71b5fc..970c54d7 100644
--- a/mall-shop/src/main/java/com/suisung/mall/shop/base/service/ShopBaseDistrictService.java
+++ b/mall-shop/src/main/java/com/suisung/mall/shop/base/service/ShopBaseDistrictService.java
@@ -56,4 +56,33 @@ public interface ShopBaseDistrictService extends IBaseService
*/
String joinDistrict(List list, Integer joinKey, Boolean hasSeparator, String separator);
+
+ /**
+ * 省市区ID路径和名称路径相互转换
+ * 支持根据ID路径获取名称路径,或根据名称路径获取ID路径
+ *
+ * @param areaIds 省市区ID路径,格式如:"450000/450800/450881"
+ * @param areaNames 省市区名称路径,格式如:"广西壮族自治区/贵港市/桂平市"
+ * @return String数组,第一个元素为处理后的ID路径,第二个元素为处理后的名称路径
+ */
+ String[] convertDistrictPath(String areaIds, String areaNames);
+
+ /**
+ * 根据省市区ID路径获取对应的名称路径
+ * 例如:450000/450800/450881 -> 广西壮族自治区/贵港市/桂平市
+ *
+ * @param districtIdPath 省市区ID路径,格式如:"450000/450800/450881"
+ * @return 省市区名称路径,格式如:"广西壮族自治区/贵港市/桂平市"
+ */
+ String getDistrictNamePathByIdPath(String districtIdPath);
+
+ /**
+ * 根据省市区名称路径获取对应的ID路径
+ * 例如:广西壮族自治区/贵港市/桂平市 -> 450000/450800/450881
+ *
+ * @param districtNamePath 省市区名称路径,格式如:"省/市/区"
+ * @return 省市区ID路径,格式如:"450000/450800/450881"
+ */
+ String getDistrictIdPathByNamePath(String districtNamePath);
+
}
diff --git a/mall-shop/src/main/java/com/suisung/mall/shop/base/service/impl/AccountBaseConfigServiceImpl.java b/mall-shop/src/main/java/com/suisung/mall/shop/base/service/impl/AccountBaseConfigServiceImpl.java
index d97b023d..f6c98682 100644
--- a/mall-shop/src/main/java/com/suisung/mall/shop/base/service/impl/AccountBaseConfigServiceImpl.java
+++ b/mall-shop/src/main/java/com/suisung/mall/shop/base/service/impl/AccountBaseConfigServiceImpl.java
@@ -7,6 +7,7 @@ import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.suisung.mall.common.constant.CommonConstant;
import com.suisung.mall.common.constant.ConfigConstant;
import com.suisung.mall.common.constant.RedisConstant;
import com.suisung.mall.common.exception.ApiException;
@@ -341,6 +342,44 @@ public class AccountBaseConfigServiceImpl extends BaseServiceImpl
+ * 根据配置键获取对应的配置值,如果配置值为空则返回空字符串。
+ *
+ *
+ * @param configKey 配置键
+ * @return 配置值,如果找不到或为空则返回空字符串
+ */
+ @Override
+ public String getSystemConfig(String configKey) {
+ // 参数校验
+ if (StrUtil.isBlank(configKey)) {
+ log.warn("[系统配置] 参数校验失败:配置键不能为空");
+ return "";
+ }
+
+ try {
+ String configValue = accountService.getAccountBaseConfigValue(configKey);
+ return StrUtil.blankToDefault(configValue, "0");
+ } catch (Exception e) {
+ log.error("[系统配置] 获取配置值异常,configKey={}", configKey, e);
+ return "";
+ }
+ }
+
+ /**
+ * 获取平台内部最低配送费,单位(分)
+ *
+ * @return
+ */
+ @Override
+ public Integer getInnerMinDeliveryFee() {
+ String v = getSystemConfig(CommonConstant.Inner_Min_DeliveryFee_Key);
+ return NumberUtil.isNumber(v) ? Convert.toInt(v) : 0;
+ }
+
+
@Override
@Async
public void run(String... args) throws Exception {
diff --git a/mall-shop/src/main/java/com/suisung/mall/shop/base/service/impl/ShopBaseCrontabServiceImpl.java b/mall-shop/src/main/java/com/suisung/mall/shop/base/service/impl/ShopBaseCrontabServiceImpl.java
index 96ad6597..e84d23a4 100644
--- a/mall-shop/src/main/java/com/suisung/mall/shop/base/service/impl/ShopBaseCrontabServiceImpl.java
+++ b/mall-shop/src/main/java/com/suisung/mall/shop/base/service/impl/ShopBaseCrontabServiceImpl.java
@@ -125,7 +125,7 @@ public class ShopBaseCrontabServiceImpl extends BaseServiceImpl implements ShopBaseDistrictService {
@@ -339,4 +341,129 @@ public class ShopBaseDistrictServiceImpl extends BaseServiceImpl 广西壮族自治区/贵港市/桂平市
+ *
+ * @param districtIdPath 省市区ID路径,格式如:"450000/450800/450881"
+ * @return 省市区名称路径,格式如:"广西壮族自治区/贵港市/桂平市"
+ */
+ @Override
+ public String getDistrictNamePathByIdPath(String districtIdPath) {
+ if (StrUtil.isBlank(districtIdPath)) {
+ return "";
+ }
+
+ String[] idStrs = districtIdPath.split("/");
+ List names = new ArrayList<>(idStrs.length);
+
+ // 先获取所有地区对象的名称
+ for (String idStr : idStrs) {
+ Integer districtId = Convert.toInt(idStr);
+ if (districtId == null) {
+ log.warn("[地区转换] ID格式不正确: {}", idStr);
+ names.add(""); // 添加空字符串而不是直接返回
+ continue; // 继续处理下一个
+ }
+
+ ShopBaseDistrict district = get(districtId);
+ if (district == null) {
+ log.warn("[地区转换] 未找到对应地区信息, districtId: {}", districtId);
+ names.add(""); // 添加空字符串而不是直接返回
+ continue; // 继续处理下一个
+ }
+
+ names.add(district.getDistrict_name());
+ }
+
+ return String.join("/", names);
+ }
+
+
+ /**
+ * 根据省市区名称路径获取对应的ID路径
+ * 例如:广西壮族自治区/贵港市/桂平市 -> 450000/450800/450881
+ *
+ * @param districtNamePath 省市区名称路径,格式如:"省/市/区"
+ * @return 省市区ID路径,格式如:"450000/450800/450881"
+ */
+ @Override
+ public String getDistrictIdPathByNamePath(String districtNamePath) {
+ if (StrUtil.isBlank(districtNamePath)) {
+ return "";
+ }
+
+ String[] names = districtNamePath.split("/");
+ List ids = new ArrayList<>(names.length);
+
+ // 先根据名称获取所有地区对象的ID
+ for (String name : names) {
+ if (StrUtil.isBlank(name)) {
+ log.warn("[地区转换] 名称不能为空");
+ ids.add(""); // 添加空字符串而不是直接返回
+ continue; // 继续处理下一个
+ }
+
+ QueryWrapper queryWrapper = new QueryWrapper<>();
+ queryWrapper.eq("district_name", name.trim());
+
+ ShopBaseDistrict district = findOne(queryWrapper);
+ if (district == null) {
+ log.warn("[地区转换] 未找到对应地区信息, name: {}", name);
+ ids.add(""); // 添加空字符串而不是直接返回
+ continue; // 继续处理下一个
+ }
+
+ ids.add(district.getDistrict_id().toString());
+ }
+
+ return String.join("/", ids);
+ }
+
+
}
diff --git a/mall-shop/src/main/java/com/suisung/mall/shop/components/quartz/job/UpdateOrderStatusJob.java b/mall-shop/src/main/java/com/suisung/mall/shop/components/quartz/job/UpdateOrderStatusJob.java
index 4a2e92a0..33fc9268 100644
--- a/mall-shop/src/main/java/com/suisung/mall/shop/components/quartz/job/UpdateOrderStatusJob.java
+++ b/mall-shop/src/main/java/com/suisung/mall/shop/components/quartz/job/UpdateOrderStatusJob.java
@@ -21,7 +21,7 @@ import java.util.List;
*/
public class UpdateOrderStatusJob extends QuartzJobBean {
- private static Logger logger = LoggerFactory.getLogger(UpdateOrderStatusJob.class);
+ private static final Logger logger = LoggerFactory.getLogger(UpdateOrderStatusJob.class);
@Override
protected void executeInternal(JobExecutionContext jobExecutionContext) throws JobExecutionException {
@@ -29,6 +29,8 @@ public class UpdateOrderStatusJob extends QuartzJobBean {
ShopOrderInfoService shopOrderInfoService = SpringUtil.getBean(ShopOrderInfoService.class);
ShopDistributionUserOrderService shopDistributionUserOrderService = SpringUtil.getBean(ShopDistributionUserOrderService.class);
+ // 在UpdateOrderStatusJob.execute方法开始添加日志
+ logger.info("UpdateOrderStatusJob 方法开始执行");
// 自动取消未支付订单
//shopOrderBaseService.autoCancelOrder();
diff --git a/mall-shop/src/main/java/com/suisung/mall/shop/components/quartz/service/impl/QuartzServiceImpl.java b/mall-shop/src/main/java/com/suisung/mall/shop/components/quartz/service/impl/QuartzServiceImpl.java
index afd72519..29feab17 100644
--- a/mall-shop/src/main/java/com/suisung/mall/shop/components/quartz/service/impl/QuartzServiceImpl.java
+++ b/mall-shop/src/main/java/com/suisung/mall/shop/components/quartz/service/impl/QuartzServiceImpl.java
@@ -29,32 +29,31 @@ public class QuartzServiceImpl implements QuartzService {
*/
@Override
public void addJob(String jName, String jGroup, String tName, String tGroup, String cron, String cName) {
- logger.info("[Quartz] 开始添加定时任务: 任务名称={}, 任务组={}, 触发器名称={}, 触发器组={}, cron表达式={}, 类名={}",
- jName, jGroup, tName, tGroup, cron, cName);
+ logger.info("[Quartz] 添加定时任务: 任务名称={}, cron表达式={}", jName, cron);
// 1. 参数校验
if (jName == null || jName.trim().isEmpty()) {
- logger.warn("[Quartz] 任务名称不能为空: {}", jName);
+ logger.warn("[Quartz] 任务名称不能为空");
throw new ApiException(I18nUtil._("任务名称不能为空!"));
}
if (jGroup == null || jGroup.trim().isEmpty()) {
- logger.warn("[Quartz] 任务组不能为空: {}", jGroup);
+ logger.warn("[Quartz] 任务组不能为空");
throw new ApiException(I18nUtil._("任务组不能为空!"));
}
if (tName == null || tName.trim().isEmpty()) {
- logger.warn("[Quartz] 触发器名称不能为空: {}", tName);
+ logger.warn("[Quartz] 触发器名称不能为空");
throw new ApiException(I18nUtil._("触发器名称不能为空!"));
}
if (tGroup == null || tGroup.trim().isEmpty()) {
- logger.warn("[Quartz] 触发器组不能为空: {}", tGroup);
+ logger.warn("[Quartz] 触发器组不能为空");
throw new ApiException(I18nUtil._("触发器组不能为空!"));
}
if (cron == null || cron.trim().isEmpty()) {
- logger.warn("[Quartz] cron表达式不能为空: {}", cron);
+ logger.warn("[Quartz] cron表达式不能为空");
throw new ApiException(I18nUtil._("cron表达式不能为空!"));
}
if (cName == null || cName.trim().isEmpty()) {
- logger.warn("[Quartz] 任务实现类名称不能为空: {}", cName);
+ logger.warn("[Quartz] 任务实现类名称不能为空");
throw new ApiException(I18nUtil._("任务实现类名称不能为空!"));
}
@@ -63,9 +62,7 @@ public class QuartzServiceImpl implements QuartzService {
Class clazz;
String fullClassName = PATH_PREFIX + cName;
- logger.debug("[Quartz] 尝试加载任务类: {}", fullClassName);
clazz = (Class) Class.forName(fullClassName);
- logger.debug("[Quartz] 成功加载任务类: {}", fullClassName);
// 3. 构建任务详情和触发器
JobKey jobKey = new JobKey(jName, jGroup);
@@ -77,44 +74,38 @@ public class QuartzServiceImpl implements QuartzService {
CronTrigger trigger = TriggerBuilder.newTrigger()
.withIdentity(triggerKey)
.startNow()
- .withSchedule(CronScheduleBuilder.cronSchedule(cron))
+ .withSchedule(CronScheduleBuilder.cronSchedule(cron).withMisfireHandlingInstructionDoNothing())
.build();
- logger.debug("[Quartz] 构建任务详情和触发器完成: jobKey={}, triggerKey={}", jobKey, triggerKey);
-
- // 打印最终执行的 cron 表达式
- logger.info("[Quartz] 定时任务最终执行表达式: {}", trigger.getCronExpression());
-
// 4. 检查任务是否已存在
if (scheduler.checkExists(jobKey)) {
- logger.info("[Quartz] 任务已存在,先删除旧任务: jobKey={}", jobKey);
+ logger.info("[Quartz] 任务已存在,先删除旧任务: {}", jName);
scheduler.deleteJob(jobKey);
}
// 5. 调度任务
- logger.info("[Quartz] 开始调度任务: jobKey={}, triggerKey={}", jobKey, triggerKey);
scheduler.scheduleJob(jobDetail, trigger);
- logger.info("[Quartz] 任务调度成功: jobKey={}, triggerKey={}", jobKey, triggerKey);
+ logger.info("[Quartz] 任务调度成功: {}", jName);
// 6. 启动调度器(如果尚未启动)
if (!scheduler.isStarted()) {
- logger.info("[Quartz] 调度器尚未启动,正在启动...");
scheduler.start();
logger.info("[Quartz] 调度器启动成功");
}
+
+ // 只在异常状态时记录详细信息
if (scheduler.getTriggerState(triggerKey) != Trigger.TriggerState.NORMAL) {
- logger.error("Trigger注册异常,当前状态: {}", scheduler.getTriggerState(triggerKey));
+ logger.error("[Quartz] Trigger注册异常,当前状态: {}", scheduler.getTriggerState(triggerKey));
}
+
} catch (SchedulerException e) {
- logger.error("[Quartz] 添加定时任务失败!任务名称={}, 任务组={}, 触发器名称={}, 触发器组={}",
- jName, jGroup, tName, tGroup, e);
+ logger.error("[Quartz] 添加定时任务失败!任务名称={}", jName, e);
throw new ApiException(I18nUtil._("添加定时任务失败!"), e);
} catch (ClassNotFoundException e) {
logger.error("[Quartz] 定时任务脚本不存在!类名: {}{}", PATH_PREFIX, cName, e);
throw new ApiException(I18nUtil._("定时任务脚本不存在!类名: " + PATH_PREFIX + cName), e);
} catch (Exception e) {
- logger.error("[Quartz] 添加定时任务时发生未知异常!任务名称={}, 任务组={}, 触发器名称={}, 触发器组={}",
- jName, jGroup, tName, tGroup, e);
+ logger.error("[Quartz] 添加定时任务时发生未知异常!任务名称={}", jName, e);
throw new ApiException(I18nUtil._("添加定时任务失败!"), e);
}
}
@@ -132,23 +123,22 @@ public class QuartzServiceImpl implements QuartzService {
*/
public boolean addOrUpdateJobFromDatabase(String jobName, String jobGroup, String triggerName,
String triggerGroup, String dbCron, String dbJobClass) {
- logger.info("[Quartz] 尝试从数据库信息添加或更新任务: 任务名称={}, 任务组={}", jobName, jobGroup);
+
+ logger.info("[Quartz] 添加或更新任务: {}", jobName);
try {
JobKey jobKey = new JobKey(jobName, jobGroup);
// 检查任务是否已存在
if (scheduler.checkExists(jobKey)) {
- logger.debug("[Quartz] 任务已存在于调度器中: jobKey={}", jobKey);
return true; // 任务已存在,无需添加
}
// 任务不存在,从数据库信息创建新任务
- logger.info("[Quartz] 调度器中不存在任务,从数据库信息创建: jobKey={}", jobKey);
addJob(jobName, jobGroup, triggerName, triggerGroup, dbCron, dbJobClass);
return true;
} catch (Exception e) {
- logger.error("[Quartz] 从数据库信息添加或更新任务失败: 任务名称={}, 任务组={}", jobName, jobGroup, e);
+ logger.error("[Quartz] 添加或更新任务失败: {}", jobName, e);
return false;
}
}
@@ -162,24 +152,22 @@ public class QuartzServiceImpl implements QuartzService {
*/
@Override
public void pauseJob(String jName, String jGroup) {
- logger.info("[Quartz] 开始暂停定时任务: 任务名称={}, 任务组={}", jName, jGroup);
+
+ logger.info("[Quartz] 暂停定时任务: {}", jName);
try {
JobKey jobKey = JobKey.jobKey(jName, jGroup);
// 检查任务是否存在,不存在则记录日志并返回,不抛出异常
if (!scheduler.checkExists(jobKey)) {
- logger.info("[Quartz] 任务不存在,无需暂停: jobKey={},可能任务已手动删除或尚未创建", jobKey);
return;
}
scheduler.pauseJob(jobKey);
- logger.info("[Quartz] 定时任务暂停成功: jobKey={}", jobKey);
+ logger.info("[Quartz] 定时任务暂停成功: {}", jName);
} catch (SchedulerException e) {
- logger.error("[Quartz] 暂停定时任务时发生调度异常!任务名称={}, 任务组={}", jName, jGroup, e);
- // 即使暂停失败也继续执行,避免阻塞业务流程
+ logger.error("[Quartz] 暂停定时任务时发生调度异常!任务名称={}", jName, e);
} catch (Exception e) {
- logger.error("[Quartz] 暂停定时任务时发生未知异常!任务名称={}, 任务组={}", jName, jGroup, e);
- // 即使暂停失败也继续执行,避免阻塞业务流程
+ logger.error("[Quartz] 暂停定时任务时发生未知异常!任务名称={}", jName, e);
}
}
@@ -191,24 +179,22 @@ public class QuartzServiceImpl implements QuartzService {
*/
@Override
public void resumeJob(String jName, String jGroup) {
- logger.info("[Quartz] 开始继续定时任务: 任务名称={}, 任务组={}", jName, jGroup);
+
+ logger.info("[Quartz] 继续定时任务: {}", jName);
try {
JobKey jobKey = JobKey.jobKey(jName, jGroup);
// 检查任务是否存在,不存在则记录日志并返回,不抛出异常
if (!scheduler.checkExists(jobKey)) {
- logger.info("[Quartz] 任务不存在,无需继续: jobKey={},可能任务已手动删除或尚未创建", jobKey);
return;
}
scheduler.resumeJob(jobKey);
- logger.info("[Quartz] 定时任务继续成功: jobKey={}", jobKey);
+ logger.info("[Quartz] 定时任务继续成功: {}", jName);
} catch (SchedulerException e) {
- logger.error("[Quartz] 继续定时任务时发生调度异常!任务名称={}, 任务组={}", jName, jGroup, e);
- // 即使继续失败也继续执行,避免阻塞业务流程
+ logger.error("[Quartz] 继续定时任务时发生调度异常!任务名称={}", jName, e);
} catch (Exception e) {
- logger.error("[Quartz] 继续定时任务时发生未知异常!任务名称={}, 任务组={}", jName, jGroup, e);
- // 即使继续失败也继续执行,避免阻塞业务流程
+ logger.error("[Quartz] 继续定时任务时发生未知异常!任务名称={}", jName, e);
}
}
@@ -220,30 +206,25 @@ public class QuartzServiceImpl implements QuartzService {
*/
@Override
public void deleteJob(String jName, String jGroup) {
- logger.info("[Quartz] 开始删除定时任务: 任务名称={}, 任务组={}", jName, jGroup);
+ logger.info("[Quartz] 删除定时任务: {}", jName);
try {
JobKey jobKey = JobKey.jobKey(jName, jGroup);
// 检查任务是否存在,不存在则记录日志并返回,不抛出异常
if (!scheduler.checkExists(jobKey)) {
- logger.info("[Quartz] 任务不存在,无需删除: jobKey={},可能任务已手动删除或尚未创建", jobKey);
return;
}
boolean deleted = scheduler.deleteJob(jobKey);
if (deleted) {
- logger.info("[Quartz] 定时任务删除成功: jobKey={}", jobKey);
+ logger.info("[Quartz] 定时任务删除成功: {}", jName);
} else {
- logger.warn("[Quartz] 定时任务删除失败: jobKey={}", jobKey);
+ logger.warn("[Quartz] 定时任务删除失败: {}", jName);
}
} catch (SchedulerException e) {
- logger.error("[Quartz] 删除定时任务时发生调度异常!任务名称={}, 任务组={}", jName, jGroup, e);
- // 即使删除失败也继续执行,避免阻塞业务流程
+ logger.error("[Quartz] 删除定时任务时发生调度异常!任务名称={}", jName, e);
} catch (Exception e) {
- logger.error("[Quartz] 删除定时任务时发生未知异常!任务名称={}, 任务组={}", jName, jGroup, e);
- // 即使删除失败也继续执行,避免阻塞业务流程
+ logger.error("[Quartz] 删除定时任务时发生未知异常!任务名称={}", jName, e);
}
}
-
-
}
diff --git a/mall-shop/src/main/java/com/suisung/mall/shop/lakala/controller/admin/LakalaAdminController.java b/mall-shop/src/main/java/com/suisung/mall/shop/lakala/controller/admin/LakalaAdminController.java
index 238aa1cc..1eb0afe7 100644
--- a/mall-shop/src/main/java/com/suisung/mall/shop/lakala/controller/admin/LakalaAdminController.java
+++ b/mall-shop/src/main/java/com/suisung/mall/shop/lakala/controller/admin/LakalaAdminController.java
@@ -28,7 +28,7 @@ public class LakalaAdminController extends BaseControllerImpl {
@Resource
private LakalaApiService lakalaPayService;
-
+
@ApiOperation(value = "查询拉卡拉商户可分账的金额", notes = "查询拉卡拉商户可分账的金额")
@RequestMapping(value = "/sacs/queryMchSplitAmt", method = RequestMethod.POST)
public CommonResult queryMchCanSplitAmt(@RequestBody JSONObject paramsJSON) {
@@ -39,4 +39,47 @@ public class LakalaAdminController extends BaseControllerImpl {
return CommonResult.failed();
}
+ @ApiOperation(value = "拉卡拉账户D1提现", notes = "拉卡拉账户D1提现")
+ @RequestMapping(value = "/ewallet/drawD1", method = RequestMethod.POST)
+ public CommonResult ewalletWithDrawD1(@RequestBody JSONObject paramsJSON) {
+ try {
+ // 参数校验
+ if (paramsJSON == null) {
+ return CommonResult.failed("请求参数不能为空");
+ }
+
+ // 执行业务逻辑
+ Boolean success = lakalaPayService.ewalletWithDrawD1(paramsJSON.getStr("mercId"), paramsJSON.getStr("merOrderNo"), paramsJSON.getStr("drawAmt"), paramsJSON.getStr("remark"), paramsJSON.getStr("summary"));
+ if (success) {
+ return CommonResult.success("账户D1提现提交成功");
+ }
+
+ return CommonResult.failed("账户D1提现提交失败");
+ } catch (Exception e) {
+ return CommonResult.failed("系统异常:" + e.getMessage());
+ }
+ }
+
+ @ApiOperation(value = "提款模式设置", notes = "提款模式设置")
+ @RequestMapping(value = "/ewallet/settleProfile", method = RequestMethod.POST)
+ public CommonResult ewalletSettleProfile(@RequestBody JSONObject paramsJSON) {
+ try {
+ // 参数校验
+ if (paramsJSON == null) {
+ return CommonResult.failed("请求参数不能为空");
+ }
+
+ // 执行业务逻辑
+ Boolean success = lakalaPayService.ewalletSettleProfile(paramsJSON.getStr("mercId"), paramsJSON.getStr("settleType"), paramsJSON.getStr("settleTime"));
+
+ if (success) {
+ return CommonResult.success("提款模式设置成功");
+ }
+
+ return CommonResult.failed("提款模式设置失败");
+ } catch (Exception e) {
+ return CommonResult.failed("系统异常:" + e.getMessage());
+ }
+ }
+
}
diff --git a/mall-shop/src/main/java/com/suisung/mall/shop/lakala/controller/mobile/LakalaController.java b/mall-shop/src/main/java/com/suisung/mall/shop/lakala/controller/mobile/LakalaController.java
index ac07da3b..5a100b20 100644
--- a/mall-shop/src/main/java/com/suisung/mall/shop/lakala/controller/mobile/LakalaController.java
+++ b/mall-shop/src/main/java/com/suisung/mall/shop/lakala/controller/mobile/LakalaController.java
@@ -12,6 +12,7 @@ import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.suisung.mall.common.api.CommonResult;
import com.suisung.mall.common.service.impl.BaseControllerImpl;
+import com.suisung.mall.shop.base.service.ShopBaseDistrictService;
import com.suisung.mall.shop.lakala.service.LakalaApiService;
import com.suisung.mall.shop.lakala.service.LklLedgerEcService;
import com.suisung.mall.shop.library.service.LibraryProductService;
@@ -23,6 +24,7 @@ import com.suisung.mall.shop.sfexpress.service.SFExpressApiService;
import com.suisung.mall.shop.store.service.ShopStoreSameCityTransportBaseService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
+import lombok.extern.slf4j.Slf4j;
import org.springframework.context.annotation.Lazy;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
@@ -36,6 +38,7 @@ import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
import java.util.List;
+@Slf4j
@Api(tags = "拉卡拉相关接口 - 前端控制器")
@RestController
@RequestMapping("/mobile/shop/lakala")
@@ -80,6 +83,9 @@ public class LakalaController extends BaseControllerImpl {
@Resource
private LklLedgerEcService lklLedgerEcService;
+ @Resource
+ private ShopBaseDistrictService shopBaseDistrictService;
+
@ApiOperation(value = "测试案例", notes = "测试案例")
@RequestMapping(value = "/testcase", method = RequestMethod.POST)
public Object testcase(@RequestBody JSONObject paramsJSON) {
@@ -118,7 +124,10 @@ public class LakalaController extends BaseControllerImpl {
// return lakalaApiService.sacsQuery("8226330541100GU", "20250918770188017227140800").toString();
- return lakalaApiService.queryLedgerMer("8226330541100HA");
+ String[] result = shopBaseDistrictService.convertDistrictPath(paramsJSON.getStr("id"), paramsJSON.getStr("name"));
+ log.info("result: " + result[0] + " " + result[1]);
+
+ return ""; //lakalaApiService.queryLedgerMer("8226330541100HA");
}
@ApiOperation(value = "批量发送推送消息 - 测试案例", notes = "批量发送推送消息 - 测试案例")
@@ -239,4 +248,42 @@ public class LakalaController extends BaseControllerImpl {
return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(resp);
}
+
+ /**
+ * 分账结果通知
+ * 参考:https://o.lakala.com/#/home/document/detail?id=367
+ *
+ * @param request
+ * @return
+ */
+ @ApiOperation(value = "拉卡拉提现结果通知", notes = "拉卡拉提现结果通知")
+ @RequestMapping(value = "/ewallet/drawNotify", method = RequestMethod.POST)
+ public ResponseEntity ewalletWithDrawNotify(HttpServletRequest request) {
+ JSONObject resp = lakalaPayService.ewalletWithDrawNotify(request);
+ if (resp != null && "SUCCESS".equals(resp.get("code"))) {
+ return ResponseEntity.ok(resp);
+ }
+
+ return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(resp);
+ }
+
+ /**
+ * 分账结果通知
+ * 参考:https://o.lakala.com/#/home/document/detail?id=393
+ *
+ * @param request
+ * @return
+ */
+ @ApiOperation(value = "提款模式设置结果通知", notes = "提款模式设置结果通知")
+ @RequestMapping(value = "/ewallet/settleProfileNotify", method = RequestMethod.POST)
+ public ResponseEntity ewalletSettleProfileNotify(HttpServletRequest request) {
+ JSONObject resp = lakalaPayService.ewalletSettleProfileNotify(request);
+ if (resp != null && "SUCCESS".equals(resp.get("code"))) {
+ return ResponseEntity.ok(resp);
+ }
+
+ return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(resp);
+ }
+
+
}
diff --git a/mall-shop/src/main/java/com/suisung/mall/shop/lakala/mapper/LklOrderDrawMapper.java b/mall-shop/src/main/java/com/suisung/mall/shop/lakala/mapper/LklOrderDrawMapper.java
new file mode 100644
index 00000000..c83d91d9
--- /dev/null
+++ b/mall-shop/src/main/java/com/suisung/mall/shop/lakala/mapper/LklOrderDrawMapper.java
@@ -0,0 +1,19 @@
+/*
+ * Copyright (c) 2025. Lorem ipsum dolor sit amet, consectetur adipiscing elit.
+ * Morbi non lorem porttitor neque feugiat blandit. Ut vitae ipsum eget quam lacinia accumsan.
+ * Etiam sed turpis ac ipsum condimentum fringilla. Maecenas magna.
+ * Proin dapibus sapien vel ante. Aliquam erat volutpat. Pellentesque sagittis ligula eget metus.
+ * Vestibulum commodo. Ut rhoncus gravida arcu.
+ */
+
+package com.suisung.mall.shop.lakala.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.suisung.mall.common.modules.lakala.LklOrderDraw;
+import org.springframework.stereotype.Repository;
+
+
+@Repository
+public interface LklOrderDrawMapper extends BaseMapper {
+
+}
diff --git a/mall-shop/src/main/java/com/suisung/mall/shop/lakala/service/LakalaApiService.java b/mall-shop/src/main/java/com/suisung/mall/shop/lakala/service/LakalaApiService.java
index 1b28f065..49366084 100644
--- a/mall-shop/src/main/java/com/suisung/mall/shop/lakala/service/LakalaApiService.java
+++ b/mall-shop/src/main/java/com/suisung/mall/shop/lakala/service/LakalaApiService.java
@@ -309,5 +309,46 @@ public interface LakalaApiService {
*/
Boolean checkAndFixLedgerMerApplyAndBindRelations(ShopMchEntry shopMchEntry);
+ /**
+ * 提款模式设置
+ * 参考:https://o.lakala.com/#/home/document/detail?id=372
+ *
+ * @param mercId 822商户号或receiveNo
+ * @param settleType 提款模式(01主动提款 02余额自动结算 03交易自动结算)
+ * @param settleTime 余额自动结算时间(小时)- 默认值:06。如08:00-09:00到账,则传入08。
+ * @return 设置是否成功
+ */
+ Boolean ewalletSettleProfile(String mercId, String settleType, String settleTime);
+
+
+ /**
+ * 提款模式设置结果通知
+ * 参考:https://o.lakala.com/#/home/document/detail?id=372
+ *
+ * @param request
+ * @return
+ */
+ JSONObject ewalletSettleProfileNotify(HttpServletRequest request);
+
+ /**
+ * 拉卡拉账户D1提现
+ * 参考:https://o.lakala.com/#/home/document/detail?id=430
+ *
+ * @param mercId 822商户号或receiveNo
+ * @param merOrderNo 商户订单号
+ * @param drawAmt 提现金额(分)
+ * @param remark
+ * @param summary
+ */
+ Boolean ewalletWithDrawD1(String mercId, String merOrderNo, String drawAmt, String remark, String summary);
+
+ /**
+ * 拉卡拉账户D1提现结果通知
+ * 参考:https://o.lakala.com/#/home/document/detail?id=367
+ *
+ * @param request
+ * @return
+ */
+ JSONObject ewalletWithDrawNotify(HttpServletRequest request);
}
diff --git a/mall-shop/src/main/java/com/suisung/mall/shop/lakala/service/LklLedgerMemberService.java b/mall-shop/src/main/java/com/suisung/mall/shop/lakala/service/LklLedgerMemberService.java
index 6f407c5a..5d607f7b 100644
--- a/mall-shop/src/main/java/com/suisung/mall/shop/lakala/service/LklLedgerMemberService.java
+++ b/mall-shop/src/main/java/com/suisung/mall/shop/lakala/service/LklLedgerMemberService.java
@@ -55,4 +55,13 @@ public interface LklLedgerMemberService extends IBaseService {
*/
Boolean updateAuditResult(String applyId, String merInnerNo, String merCupNo, String entrustFileName, String entrustFilePath, String auditStatus, String auditStatusText, String remark, String notifyResp);
+
+ /**
+ * 更新商户的提现模式
+ *
+ * @param merCupNo 银联商户号
+ * @param settleType 提款模式(01主动提款 02余额自动结算 03交易自动结算)
+ * @return 更新是否成功
+ */
+ Boolean updateSettleTypeDraw(String merCupNo, String settleType);
}
diff --git a/mall-shop/src/main/java/com/suisung/mall/shop/lakala/service/LklOrderDrawService.java b/mall-shop/src/main/java/com/suisung/mall/shop/lakala/service/LklOrderDrawService.java
new file mode 100644
index 00000000..8d074ae6
--- /dev/null
+++ b/mall-shop/src/main/java/com/suisung/mall/shop/lakala/service/LklOrderDrawService.java
@@ -0,0 +1,32 @@
+/*
+ * Copyright (c) 2025. Lorem ipsum dolor sit amet, consectetur adipiscing elit.
+ * Morbi non lorem porttitor neque feugiat blandit. Ut vitae ipsum eget quam lacinia accumsan.
+ * Etiam sed turpis ac ipsum condimentum fringilla. Maecenas magna.
+ * Proin dapibus sapien vel ante. Aliquam erat volutpat. Pellentesque sagittis ligula eget metus.
+ * Vestibulum commodo. Ut rhoncus gravida arcu.
+ */
+
+package com.suisung.mall.shop.lakala.service;
+
+import com.suisung.mall.common.modules.lakala.LklOrderDraw;
+import com.suisung.mall.core.web.service.IBaseService;
+
+public interface LklOrderDrawService extends IBaseService {
+
+ /**
+ * 新增或更新记录
+ *
+ * @param record
+ * @return
+ */
+ Boolean addOrUpdateByMercIdAndMerOrderNo(LklOrderDraw record);
+
+ /**
+ * 根据拉卡拉对账单流水号和平台订单号查询记录
+ *
+ * @param mercId 商户号
+ * @param merOrderNo 商户订单号
+ * @return
+ */
+ LklOrderDraw getByByMercIdAndMerOrderNo(String mercId, String merOrderNo);
+}
diff --git a/mall-shop/src/main/java/com/suisung/mall/shop/lakala/service/impl/LakalaApiServiceImpl.java b/mall-shop/src/main/java/com/suisung/mall/shop/lakala/service/impl/LakalaApiServiceImpl.java
index c04d3518..70dea245 100644
--- a/mall-shop/src/main/java/com/suisung/mall/shop/lakala/service/impl/LakalaApiServiceImpl.java
+++ b/mall-shop/src/main/java/com/suisung/mall/shop/lakala/service/impl/LakalaApiServiceImpl.java
@@ -57,6 +57,7 @@ import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.io.File;
import java.math.BigDecimal;
+import java.math.RoundingMode;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.ArrayList;
@@ -145,6 +146,9 @@ public class LakalaApiServiceImpl implements LakalaApiService {
@Resource
private LklOrderSeparateService lklOrderSeparateService;
+ @Resource
+ private LklOrderDrawService lklOrderDrawService;
+
@Lazy
@Resource
private ShopOrderBaseService shopOrderBaseService;
@@ -682,7 +686,7 @@ public class LakalaApiServiceImpl implements LakalaApiService {
reqData.put("splitLowestRatio", splitLowestRatio); // 商家最低分账比例不低于 20%
reqData.put("splitRange", "ALL");
- reqData.put("settleType", "01"); //01:主动提款 03:交易自动结算 不填默认01
+ reqData.put("settleType", "03"); //01:主动提款 03:交易自动结算 不填默认01
String postUrl = "";
String operationType = ""; // 操作类型,用于日志记录和提示信息
@@ -1800,6 +1804,7 @@ public class LakalaApiServiceImpl implements LakalaApiService {
// 10. 检查商户绑定状态是否完成, 更改总的审核状态
shopMchEntryService.checkMerchEntryFinished(mchId);
+
// 11. 日志记录并返回成功响应
log.info("商家绑定分账接收方异步通知处理完成,mchId:{} merCupNo:{}", mchId, merCupNo);
return JSONUtil.createObj().set("code", "SUCCESS").set("message", "分账接收方绑定成功");
@@ -3256,5 +3261,330 @@ public class LakalaApiServiceImpl implements LakalaApiService {
return true;
}
+ /**
+ * 提款模式设置
+ * 参考:https://o.lakala.com/#/home/document/detail?id=372
+ *
+ * @param mercId 822商户号或receiveNo
+ * @param settleType 提款模式(01主动提款 02余额自动结算 03交易自动结算)
+ * @param settleTime 余额自动结算时间(小时)- 默认值:06。如08:00-09:00到账,则传入08。
+ * @return 设置是否成功
+ */
+ @Override
+ public Boolean ewalletSettleProfile(String mercId, String settleType, String settleTime) {
+ // 1. 参数校验
+ if (StrUtil.isBlank(mercId)) {
+ log.warn("[提款模式设置] 参数校验失败:缺少必要参数, mercId={}", mercId);
+ return false;
+ }
+
+ // 设置默认值
+ if (StrUtil.isBlank(settleType)) {
+ settleType = "02"; // 默认余额自动结算
+ }
+
+ if (StrUtil.isBlank(settleTime)) {
+ settleTime = "06"; // 默认06点结算
+ }
+
+ try {
+ // 2. 配置初始化
+ initLKLSDK();
+
+ // 3. 装配数据
+ V2LaepIndustryEwalletSettleProfileRequest request = new V2LaepIndustryEwalletSettleProfileRequest();
+ request.setBmcpNo(orgCode);
+ request.setMercId(mercId);
+ request.setSettleType(settleType);
+ request.setSettleTime(settleTime);
+ request.setNotifyUrl(projectDomain + "/api/mobile/shop/lakala/ewallet/settleProfileNotify");
+
+ log.info("[提款模式设置] 开始设置提款模式, mercId={}, settleType={}, settleTime={}",
+ mercId, settleType, settleTime);
+
+ // 4. 发送请求
+ String responseStr = LKLSDK.httpPost(request);
+ if (StrUtil.isBlank(responseStr)) {
+ log.error("[提款模式设置] 服务器无响应, mercId={}", mercId);
+ return false;
+ }
+
+ JSONObject lakalaRespJSON = JSONUtil.parseObj(responseStr);
+ if (lakalaRespJSON == null) {
+ log.error("[提款模式设置] 响应数据解析失败, mercId={}, response={}", mercId, responseStr);
+ return false;
+ }
+
+ String retCode = lakalaRespJSON.getStr("retCode");
+ boolean success = "000000".equals(retCode);
+
+ if (success) {
+ log.info("[提款模式设置] 设置成功, mercId={}", mercId);
+
+ // 更新商户的提现模式
+ lklLedgerMemberService.updateSettleTypeDraw(mercId, settleType);
+ } else {
+ log.warn("[提款模式设置] 设置失败, mercId={}, retCode={}, retMsg={}",
+ mercId, retCode, lakalaRespJSON.getStr("retMsg"));
+ }
+
+ return success;
+ } catch (SDKException e) {
+ log.error("[提款模式设置] SDK调用异常, mercId={}", mercId, e);
+ return false;
+ } catch (Exception e) {
+ log.error("[提款模式设置] 设置过程中发生未知异常, mercId={}", mercId, e);
+ return false;
+ }
+ }
+
+
+ /**
+ * 提款模式设置结果通知
+ * 参考:https://o.lakala.com/#/home/document/detail?id=372
+ *
+ * @param request HTTP请求对象,包含拉卡拉回调通知的参数
+ * @return JSONObject 响应结果对象
+ */
+ @Override
+ public JSONObject ewalletSettleProfileNotify(HttpServletRequest request) {
+ log.info("[提款模式设置通知] 开始处理拉卡拉提款模式设置结果异步回调");
+
+ // 1. 验签处理 - 验证通知来源的合法性
+ Pair signCheckResult = LakalaUtil.chkLklApiNotifySign(request, lklNotifyCerPath, false);
+ if (!signCheckResult.getFirst()) {
+ String errorMsg = "提款模式设置通知验签失败: " + signCheckResult.getSecond();
+ log.warn("[提款模式设置通知] {}", errorMsg);
+ return JSONUtil.createObj()
+ .set("code", "FAIL")
+ .set("message", signCheckResult.getSecond());
+ }
+
+ // 2. 解析回调参数
+ JSONObject paramsJSON = JSONUtil.parseObj(signCheckResult.getSecond());
+ if (paramsJSON == null) {
+ log.warn("[提款模式设置通知] 回调参数解析失败");
+ return JSONUtil.createObj()
+ .set("code", "FAIL")
+ .set("message", "回调参数解析失败");
+ }
+
+ log.info("[提款模式设置通知] 验签成功,回调参数: {}", paramsJSON);
+
+ // 3. 返回成功响应
+ return JSONUtil.createObj()
+ .set("code", "SUCCESS")
+ .set("message", "处理成功");
+ }
+
+ /**
+ * 拉卡拉账户D1提现
+ * 参考:https://o.lakala.com/#/home/document/detail?id=430
+ *
+ * @param mercId 822商户号或receiveNo
+ * @param merOrderNo 商户订单号
+ * @param drawAmt 提现金额(分)
+ * @param remark 备注信息
+ * @param summary 摘要信息
+ * @return 操作结果,成功返回true,失败返回false
+ */
+ @Override
+ public Boolean ewalletWithDrawD1(String mercId, String merOrderNo, String drawAmt, String remark, String summary) {
+ // 1. 参数校验
+ if (StrUtil.hasBlank(mercId, merOrderNo, drawAmt)) {
+ log.warn("[D1提现申请] D1提现参数校验失败,关键参数为空: mercId={}, merOrderNo={}, drawAmt={}",
+ mercId, merOrderNo, drawAmt);
+ return false;
+ }
+
+ // 账号类型(01:收款账户,04:分账接收方账户)
+ String payType = "04";
+ if (StrUtil.startWith(mercId, "822")) {
+ payType = "01";
+ }
+
+ try {
+ // 验证提现金额是否为有效数字
+ BigDecimal drawAmtDecimal = Convert.toBigDecimal(drawAmt);
+ if (drawAmtDecimal == null || drawAmtDecimal.compareTo(BigDecimal.ZERO) <= 0) {
+ log.warn("[D1提现申请] D1提现金额无效,商户号={},订单号={},提现金额={}", mercId, merOrderNo, drawAmt);
+ return false;
+ }
+
+ // 设置默认值
+ if (StrUtil.isBlank(remark)) {
+ remark = String.format("商户订单:%s 账号类型:%s 分账后立即提现", merOrderNo, payType);
+ }
+
+ log.info("[D1提现申请] 开始处理D1提现,商户号={},订单号={},提现金额={}分", mercId, merOrderNo, drawAmt);
+
+ // 2. 配置初始化
+ initLKLSDK();
+
+ // 3. 装配数据
+ V2LaepIndustryEwalletWithdrawD1Request request = new V2LaepIndustryEwalletWithdrawD1Request();
+ request.setOrgNo(orgCode);
+ request.setMerchantNo(mercId);
+ request.setMerOrderNo(merOrderNo);
+ request.setPayType(payType);
+
+ // 分转元,保留两位小数点,不要四舍五入
+ String drawAmtYuan = drawAmtDecimal.divide(BigDecimal.valueOf(100), 2, RoundingMode.DOWN).toString();
+ request.setDrawAmt(drawAmtYuan); // 单位:元
+ request.setRemark(remark);
+ if (StrUtil.isNotBlank(summary)) {
+ request.setSummary(summary);
+ }
+ request.setNotifyUrl(projectDomain + "/api/mobile/shop/lakala/ewallet/ewallet/drawNotify");
+
+ // 4. 发送请求
+ String responseStr = LKLSDK.httpPost(request);
+ if (StrUtil.isBlank(responseStr)) {
+ log.error("[D1提现申请] D1提现请求无响应,商户号={},订单号={}", mercId, merOrderNo);
+ return false;
+ }
+
+ JSONObject lakalaRespJSON = JSONUtil.parseObj(responseStr);
+ if (lakalaRespJSON == null) {
+ log.error("[D1提现申请] D1提现响应数据解析失败,商户号={},订单号={}", mercId, merOrderNo);
+ return false;
+ }
+
+ String retCode = lakalaRespJSON.getStr("retCode");
+ Object drawJnl = lakalaRespJSON.getByPath("respData.drawJnl");
+ boolean success = "000000".equals(retCode);
+
+ if (success && drawJnl != null) {
+ log.info("[D1提现申请] D1提现请求成功,商户号={},订单号={},流水号={}", mercId, merOrderNo, drawJnl);
+
+ // 5. 保存提现记录
+ LklOrderDraw lklOrderDraw = new LklOrderDraw();
+ lklOrderDraw.setMerc_id(mercId);
+ lklOrderDraw.setMer_order_no(merOrderNo);
+ lklOrderDraw.setDraw_jnl(Convert.toStr(drawJnl));
+ lklOrderDraw.setDraw_amt(drawAmtYuan);
+ lklOrderDraw.setBatch_auto_settle(payType);
+ lklOrderDraw.setNotify_url(request.getNotifyUrl());
+ lklOrderDraw.setNotify_resp(responseStr);
+ lklOrderDraw.setRemark(remark);
+ if (StrUtil.isNotBlank(summary)) {
+ lklOrderDraw.setSummary(summary);
+ }
+
+ boolean saveResult = lklOrderDrawService.addOrUpdateByMercIdAndMerOrderNo(lklOrderDraw);
+ if (saveResult) {
+ log.info("[D1提现申请] D1提现记录保存成功,商户号={},订单号={},流水号={}", mercId, merOrderNo, drawJnl);
+ } else {
+ log.error("[D1提现申请] D1提现记录保存失败,商户号={},订单号={},流水号={}", mercId, merOrderNo, drawJnl);
+ }
+
+ return saveResult;
+ } else {
+ String retMsg = lakalaRespJSON.getStr("retMsg");
+ log.error("[D1提现申请] D1提现失败,商户号={},订单号={},错误码={},错误信息={}",
+ mercId, merOrderNo, retCode, retMsg);
+ return false;
+ }
+
+ } catch (SDKException e) {
+ log.error("[D1提现申请] D1提现SDK调用异常,商户号={},订单号={}", mercId, merOrderNo, e);
+ return false;
+ } catch (Exception e) {
+ log.error("[D1提现申请] D1提现处理异常,商户号={},订单号={}", mercId, merOrderNo, e);
+ return false;
+ }
+ }
+
+
+ /**
+ * 拉卡拉账户D1提现结果通知处理
+ * 参考:https://o.lakala.com/#/home/document/detail?id=367
+ *
+ * @param request HTTP请求对象,包含拉卡拉提现结果通知的参数
+ * @return JSONObject 响应结果对象
+ */
+ @Override
+ public JSONObject ewalletWithDrawNotify(HttpServletRequest request) {
+ log.debug("[拉卡拉提现结果通知] 开始处理拉卡拉提现结果通知");
+
+ try {
+ // 1. 验签处理 - 验证通知来源的合法性
+ Pair signCheckResult = LakalaUtil.chkLklApiNotifySign(request, lklNotifyCerPath, false);
+ if (!signCheckResult.getFirst()) {
+ log.warn("[LklOrderDraw] 验签失败: {}", signCheckResult.getSecond());
+ return JSONUtil.createObj()
+ .set("code", "FAIL")
+ .set("message", signCheckResult.getSecond());
+ }
+
+ // 2. 解析回调参数
+ JSONObject paramsJSON = JSONUtil.parseObj(signCheckResult.getSecond());
+ if (paramsJSON == null) {
+ log.warn("[拉卡拉提现结果通知] 回调参数解析失败");
+ return JSONUtil.createObj()
+ .set("code", "FAIL")
+ .set("message", "回调参数解析失败");
+ }
+
+ String drawState = paramsJSON.getStr("drawState");
+ String mercId = paramsJSON.getStr("mercId");
+ String merOrderNo = paramsJSON.getStr("merOrderNo");
+
+ log.info("[拉卡拉提现结果通知] 提现通知参数: drawState={}, mercId={}, merOrderNo={}", drawState, mercId, merOrderNo);
+
+ if (StrUtil.isBlank(mercId) || StrUtil.isBlank(merOrderNo) || StrUtil.isBlank(drawState)) {
+ log.warn("[拉卡拉提现结果通知] 回调参数缺失: drawState={}, mercId={}, merOrderNo={}", drawState, mercId, merOrderNo);
+ return JSONUtil.createObj()
+ .set("code", "FAIL")
+ .set("message", "回调参数错误");
+ }
+
+ // 只处理成功的提现状态
+ if (!"DRAW.SUCCESS".equals(drawState)) {
+ log.debug("[拉卡拉提现结果通知] 提现状态未成功,忽略处理: drawState={}", drawState);
+ return JSONUtil.createObj()
+ .set("code", "SUCCESS") // 返回成功,避免重复通知
+ .set("message", "状态未成功,忽略处理");
+ }
+
+ // 3. 转换参数并更新数据
+ String snakeCaseJson = StringUtils.convertCamelToSnake(signCheckResult.getSecond());
+ if (StringUtils.isBlank(snakeCaseJson)) {
+ log.error("[拉卡拉提现结果通知] 回调参数转换失败,mercId={} merOrderNo={}", mercId, merOrderNo);
+ return JSONUtil.createObj()
+ .set("code", "FAIL")
+ .set("message", "回调参数转换失败");
+ }
+
+ LklOrderDraw lklOrderDraw = JSONUtil.toBean(snakeCaseJson, LklOrderDraw.class);
+ if (lklOrderDraw == null) {
+ log.error("[拉卡拉提现结果通知] 回调参数转换为对象失败,mercId={} merOrderNo={}", mercId, merOrderNo);
+ return JSONUtil.createObj()
+ .set("code", "FAIL")
+ .set("message", "回调参数转换失败");
+ }
+
+ boolean isSuccess = lklOrderDrawService.addOrUpdateByMercIdAndMerOrderNo(lklOrderDraw);
+ if (!isSuccess) {
+ log.error("[拉卡拉提现结果通知] 数据更新失败,mercId={} merOrderNo={}", mercId, merOrderNo);
+ return JSONUtil.createObj()
+ .set("code", "FAIL")
+ .set("message", "数据更新失败");
+ }
+
+ log.info("[拉卡拉提现结果通知] 拉卡拉提现结果通知处理成功,mercId={} merOrderNo={}", mercId, merOrderNo);
+
+ // 4. 返回成功响应
+ return JSONUtil.createObj()
+ .set("code", "SUCCESS")
+ .set("message", "处理成功");
+
+ } catch (Exception e) {
+ log.error("[拉卡拉提现结果通知] 处理拉卡拉提现结果通知异常", e);
+ return JSONUtil.createObj()
+ .set("code", "FAIL")
+ .set("message", "系统处理异常");
+ }
+ }
}
diff --git a/mall-shop/src/main/java/com/suisung/mall/shop/lakala/service/impl/LklLedgerMemberServiceImpl.java b/mall-shop/src/main/java/com/suisung/mall/shop/lakala/service/impl/LklLedgerMemberServiceImpl.java
index be33de34..98dd3a74 100644
--- a/mall-shop/src/main/java/com/suisung/mall/shop/lakala/service/impl/LklLedgerMemberServiceImpl.java
+++ b/mall-shop/src/main/java/com/suisung/mall/shop/lakala/service/impl/LklLedgerMemberServiceImpl.java
@@ -125,4 +125,40 @@ public class LklLedgerMemberServiceImpl extends BaseServiceImpl updateWrapper = new UpdateWrapper<>();
+ updateWrapper.eq("mer_cup_no", merCupNo).ne("settle_type_draw", settleType);
+ updateWrapper.set("settle_type_draw", settleType);
+
+ boolean result = update(updateWrapper);
+
+ if (result) {
+ log.info("[更新提现模式] 更新成功, merCupNo={}, settleType={}", merCupNo, settleType);
+ } else {
+ log.warn("[更新提现模式] 未找到匹配记录或更新失败, merCupNo={}, settleType={}", merCupNo, settleType);
+ }
+
+ return result;
+ } catch (Exception e) {
+ log.error("[更新提现模式] 更新过程中发生异常, merCupNo={}, settleType={}", merCupNo, settleType, e);
+ return false;
+ }
+ }
+
+
}
diff --git a/mall-shop/src/main/java/com/suisung/mall/shop/lakala/service/impl/LklOrderDrawServiceImpl.java b/mall-shop/src/main/java/com/suisung/mall/shop/lakala/service/impl/LklOrderDrawServiceImpl.java
new file mode 100644
index 00000000..22e7043c
--- /dev/null
+++ b/mall-shop/src/main/java/com/suisung/mall/shop/lakala/service/impl/LklOrderDrawServiceImpl.java
@@ -0,0 +1,105 @@
+package com.suisung.mall.shop.lakala.service.impl;
+
+import cn.hutool.core.util.StrUtil;
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.suisung.mall.common.modules.lakala.LklOrderDraw;
+import com.suisung.mall.core.web.service.impl.BaseServiceImpl;
+import com.suisung.mall.shop.lakala.mapper.LklOrderDrawMapper;
+import com.suisung.mall.shop.lakala.service.LklOrderDrawService;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.stereotype.Service;
+
+@Slf4j
+@Service
+public class LklOrderDrawServiceImpl extends BaseServiceImpl implements LklOrderDrawService {
+ /**
+ * 新增或更新拉卡拉订单提现记录
+ *
+ * @param record 拉卡拉订单提现记录
+ * @return 操作结果,成功返回true,失败返回false
+ */
+ @Override
+ public Boolean addOrUpdateByMercIdAndMerOrderNo(LklOrderDraw record) {
+ // 参数校验
+ if (record == null || (StrUtil.isBlank(record.getMer_order_no()) && StrUtil.isBlank(record.getMerc_id()))) {
+ log.warn("[LklOrderDraw] 新增或更新记录参数校验失败,record为空或关键参数缺失");
+ return false;
+ }
+
+ try {
+ log.debug("[LklOrderDraw] 开始处理订单提现记录,商户订单号={},商户号={}",
+ record.getMer_order_no(), record.getMerc_id());
+
+ QueryWrapper queryWrapper = new QueryWrapper<>();
+ queryWrapper.eq("mer_order_no", record.getMer_order_no())
+ .eq("merc_id", record.getMerc_id());
+
+ if (StrUtil.isNotBlank(record.getDraw_jnl())) {
+ queryWrapper.eq("draw_jnl", record.getDraw_jnl());
+ }
+
+ LklOrderDraw existsRecord = getOne(queryWrapper);
+ if (existsRecord != null && existsRecord.getId() != null && existsRecord.getId() > 0) {
+ // 更新记录
+ log.info("[LklOrderDraw] 记录已存在,执行更新操作,ID={}", existsRecord.getId());
+ record.setId(existsRecord.getId());
+ boolean updateResult = updateById(record);
+ if (updateResult) {
+ log.debug("[LklOrderDraw] 记录更新成功,ID={}", record.getId());
+ } else {
+ log.error("[LklOrderDraw] 记录更新失败,ID={}", record.getId());
+ }
+ return updateResult;
+ }
+
+ log.info("[LklOrderDraw] 记录不存在,执行新增操作");
+ boolean addResult = add(record);
+ if (addResult) {
+ log.debug("[LklOrderDraw] 记录新增成功,ID={}", record.getId());
+ } else {
+ log.error("[LklOrderDraw] 记录新增失败");
+ }
+ return addResult;
+
+ } catch (Exception e) {
+ log.error("[LklOrderDraw] 处理订单提现记录异常,商户订单号={},商户号={}",
+ record.getMer_order_no(), record.getMerc_id(), e);
+ return false;
+ }
+ }
+
+ /**
+ * 根据商户号和商户订单号查询拉卡拉订单提现记录
+ *
+ * @param mercId 商户号
+ * @param merOrderNo 商户订单号
+ * @return 拉卡拉订单分账记录,未找到返回null
+ */
+ @Override
+ public LklOrderDraw getByByMercIdAndMerOrderNo(String mercId, String merOrderNo) {
+ // 参数校验
+ if (StrUtil.isBlank(mercId) && StrUtil.isBlank(merOrderNo)) {
+ log.warn("[LklOrderDraw] 查询记录参数校验失败,商户号和商户订单号均为空");
+ return null;
+ }
+
+ try {
+ log.debug("[LklOrderDraw] 开始查询订单提现记录,商户订单号={},商户号={}", merOrderNo, mercId);
+
+ QueryWrapper queryWrapper = new QueryWrapper<>();
+ queryWrapper.eq("mer_order_no", merOrderNo).eq("merc_id", mercId);
+
+ LklOrderDraw result = getOne(queryWrapper);
+ if (result != null) {
+ log.debug("[LklOrderDraw] 查询到订单提现记录,ID={}", result.getId());
+ } else {
+ log.debug("[LklOrderDraw] 未查询到订单提现记录");
+ }
+
+ return result;
+ } catch (Exception e) {
+ log.error("[LklOrderDraw] 查询订单提现记录异常,商户订单号={},商户号={}", merOrderNo, mercId, e);
+ return null;
+ }
+ }
+}
diff --git a/mall-shop/src/main/java/com/suisung/mall/shop/sfexpress/service/impl/SFExpressApiServiceImpl.java b/mall-shop/src/main/java/com/suisung/mall/shop/sfexpress/service/impl/SFExpressApiServiceImpl.java
index 76bb25a3..2e3021f1 100644
--- a/mall-shop/src/main/java/com/suisung/mall/shop/sfexpress/service/impl/SFExpressApiServiceImpl.java
+++ b/mall-shop/src/main/java/com/suisung/mall/shop/sfexpress/service/impl/SFExpressApiServiceImpl.java
@@ -106,21 +106,26 @@ public class SFExpressApiServiceImpl implements SFExpressApiService {
*
* @param mchId 入驻记录Id, 必填项(mchId 和 storeId 其一必填) 优先
* @param storeId 商家门店ID 必填项(mchId 和 storeId 其一必填)
- * @return
+ * @return Pair 第一个元素表示是否成功,第二个元素表示结果信息或错误信息
*/
@Override
public Pair createSfExpressShop(Long mchId, Integer storeId) {
+ logger.info("[顺丰] 开始创建连锁店铺: mchId={}, storeId={}", mchId, storeId);
+
// 参数校验
- if (ObjectUtil.isEmpty(mchId) && ObjectUtil.isEmpty(storeId)) {
+ if (CheckUtil.isEmpty(mchId) && CheckUtil.isEmpty(storeId)) {
logger.error("创建顺丰同店铺:mchId 和 storeId 其一必填");
return Pair.of(false, "缺少必填参数");
}
+ // 获取商家入驻信息
ShopMchEntry shopMchEntry;
- if (ObjectUtil.isEmpty(mchId)) {
- shopMchEntry = shopMchEntryService.getShopMerchEntryByStoreId(storeId);
- } else {
+ if (ObjectUtil.isNotEmpty(mchId)) {
shopMchEntry = shopMchEntryService.shopMerchEntryById(mchId);
+ logger.debug("[顺丰] 通过mchId获取入驻信息: mchId={}", mchId);
+ } else {
+ shopMchEntry = shopMchEntryService.getShopMerchEntryByStoreId(storeId);
+ logger.debug("[顺丰] 通过storeId获取入驻信息: storeId={}", storeId);
}
if (shopMchEntry == null) {
@@ -149,39 +154,53 @@ public class SFExpressApiServiceImpl implements SFExpressApiService {
return Pair.of(false, "联系人姓名不能为空");
}
- String contact_mobile = StrUtil.isBlank(shopMchEntry.getLegal_person_mobile()) ?
- shopMchEntry.getLogin_mobile() : shopMchEntry.getLegal_person_mobile();
+ String contactMobile = StrUtil.isNotBlank(shopMchEntry.getLegal_person_mobile()) ?
+ shopMchEntry.getLegal_person_mobile() : shopMchEntry.getLogin_mobile();
- if (StrUtil.isBlank(contact_mobile)) {
+ if (StrUtil.isBlank(contactMobile)) {
logger.error("创建顺丰同店铺:联系人手机号不能为空");
return Pair.of(false, "联系人手机号不能为空");
}
- // shopMchEntry.getStore_area() == 广西壮族自治区/贵港市/桂平市 or 广西壮族自治区/贵港市
- String[] areaNames = StrUtil.isNotBlank(shopMchEntry.getStore_area()) ?
- shopMchEntry.getStore_area().split("/") : new String[0];
- String cityName = areaNames.length > 0 ?
- areaNames[areaNames.length - 1] :
- shopMchEntry.getStore_area() != null ? shopMchEntry.getStore_area().replace("/", "") : "";
-
- // 如果城市名为空,使用默认值
- if (StrUtil.isBlank(cityName)) {
- cityName = "桂平市"; // 默认城市
- logger.warn("城市名为空,使用默认城市: {}", cityName);
+ // 解析城市名称
+ String cityName = "桂平市"; // 默认城市
+ if (StrUtil.isNotBlank(shopMchEntry.getStore_area())) {
+ String[] areaNames = shopMchEntry.getStore_area().split("/");
+ if (areaNames.length > 0) {
+ cityName = areaNames[areaNames.length - 1];
+ } else {
+ cityName = shopMchEntry.getStore_area().replace("/", "");
+ }
}
- return createSfExpressShop(
+ // 如果解析后城市名为空,使用默认值
+ if (StrUtil.isBlank(cityName)) {
+ cityName = "桂平市";
+ logger.warn("[顺丰] 城市名为空,使用默认城市: {}", cityName);
+ } else {
+ logger.debug("[顺丰] 解析得到城市名: {}", cityName);
+ }
+
+ // 为了其他顺丰店同名,店铺名称加上[门店ID]; 如:xxxx[xxxx] 聚万家生鲜超市[69]
+ String shopStoreName = String.format("%s[%s]", shopMchEntry.getStore_name(), shopMchEntry.getStore_id());
+
+ // 调用创建店铺方法
+ Pair result = createSfExpressShop(
Convert.toInt(shopMchEntry.getStore_id()),
- shopMchEntry.getStore_name(),
+ shopStoreName,
cityName,
shopMchEntry.getStore_address(),
shopMchEntry.getContact_name(),
- contact_mobile,
+ contactMobile,
shopMchEntry.getStore_longitude(),
shopMchEntry.getStore_latitude()
);
+
+ logger.info("[顺丰] 连锁店铺创建结果: success={}, message={}", result.getFirst(), result.getSecond());
+ return result;
}
+
/**
* 创建顺丰同城(普通型)店铺
*
diff --git a/mall-shop/src/main/java/com/suisung/mall/shop/store/service/ShopMchEntryService.java b/mall-shop/src/main/java/com/suisung/mall/shop/store/service/ShopMchEntryService.java
index 7ceeabc9..f1859fa4 100644
--- a/mall-shop/src/main/java/com/suisung/mall/shop/store/service/ShopMchEntryService.java
+++ b/mall-shop/src/main/java/com/suisung/mall/shop/store/service/ShopMchEntryService.java
@@ -357,4 +357,14 @@ public interface ShopMchEntryService {
* @return 分账比例
*/
BigDecimal getMchEntryRatioOrDefault(Integer mch1stBizCategory, Integer mch2ndBizCategory, BigDecimal srcRatio, BigDecimal defaultRatio);
+
+ /**
+ * 处理店铺省市区信息
+ *
+ * @param storeDistrict 店铺省市区ID路径
+ * @param storeArea 店铺省市区名称路径
+ * @param refStoreAddress 参考店铺地址(用于解析省市区信息)
+ * @return 包含ID路径和名称路径的字符串数组,格式为 [ID路径, 名称路径]
+ */
+ String[] handleStoreDistrictInfo(String storeDistrict, String storeArea, String refStoreAddress);
}
\ No newline at end of file
diff --git a/mall-shop/src/main/java/com/suisung/mall/shop/store/service/impl/ShopMchEntryServiceImpl.java b/mall-shop/src/main/java/com/suisung/mall/shop/store/service/impl/ShopMchEntryServiceImpl.java
index f47f5463..cc73839d 100644
--- a/mall-shop/src/main/java/com/suisung/mall/shop/store/service/impl/ShopMchEntryServiceImpl.java
+++ b/mall-shop/src/main/java/com/suisung/mall/shop/store/service/impl/ShopMchEntryServiceImpl.java
@@ -29,10 +29,12 @@ import com.suisung.mall.common.modules.account.AccountUserBase;
import com.suisung.mall.common.modules.lakala.LklLedgerEc;
import com.suisung.mall.common.modules.store.ShopMchEntry;
import com.suisung.mall.common.modules.store.ShopStoreEmployee;
+import com.suisung.mall.common.pojo.to.AddressParseResultTO;
import com.suisung.mall.common.utils.*;
import com.suisung.mall.common.utils.phone.PhoneNumberUtils;
import com.suisung.mall.core.web.service.impl.BaseServiceImpl;
import com.suisung.mall.shop.base.service.AccountBaseConfigService;
+import com.suisung.mall.shop.base.service.ShopBaseDistrictService;
import com.suisung.mall.shop.base.service.ShopBaseStoreCategoryService;
import com.suisung.mall.shop.esign.service.EsignPlatformInfoService;
import com.suisung.mall.shop.lakala.service.LklLedgerEcService;
@@ -91,6 +93,9 @@ public class ShopMchEntryServiceImpl extends BaseServiceImpl resultPair = lakalaApiService.applyLedgerMerEc(mchId);
if (!resultPair.getFirst()) {
- log.warn("拉卡拉电子合同签署申请失败: {}", resultPair.getSecond());
+ log.warn("拉卡拉入网电子合同提交失败: {}", resultPair.getSecond());
return CommonResult.failed(resultPair.getSecond());
}
// 执行更新操作
if (!updateMerchEntryApprovalByMchId(shopMchEntry.getId(), null, "入网申请已提交!")) {
- log.error("系统处理审批出错,请联系管理员!当前记录ID: {}", mchId);
+ log.error("系统处理审批出错,请联系管理员!当前入驻编号: {}", mchId);
return CommonResult.failed("系统处理审批出错,请联系管理员!");
}
log.info("商家入驻平台初步审批处理完成,mchId={}", mchId);
-// E签宝暂时停止使用
-// if (approvalStatus.equals(CommonConstant.Enable)) {
-// // 多线程执行电子合同生成和填充
-// taskService.executeTask(() -> {
-// log.debug("###开始异步执行生成电子合同模版和填充模版数据,并生该商家和平台方签署的未盖章合同文件###");
-// // 生成电子合同模版和填充模版数据,并生该商家和平台方签署的未盖章合同文件
-// Boolean genSuccess = esignContractFillingFileService.fillDocTemplate(record.getLogin_mobile(), "");
-// if (!genSuccess) {
-// log.error("###商家入驻电子合同生成失败###");
-// }
-//
-// // 发短信通知商家,入驻申请已通过审核
-// });
-// }
-
+ return CommonResult.success();
} catch (Exception e) {
log.error("调用拉卡拉电子合同接口异常", e);
return CommonResult.failed("调用拉卡拉服务失败,请稍后重试");
}
-
- return CommonResult.success();
}
@@ -1777,6 +1772,9 @@ public class ShopMchEntryServiceImpl extends BaseServiceImpl
+
+
+
+
+ *
+
+
diff --git a/mall-shop/src/main/resources/static/diy/js/diy.js b/mall-shop/src/main/resources/static/diy/js/diy.js
index 626ebc1e..5eeb33f6 100644
--- a/mall-shop/src/main/resources/static/diy/js/diy.js
+++ b/mall-shop/src/main/resources/static/diy/js/diy.js
@@ -20803,7 +20803,7 @@
i[_x41903[4478]][_x41903[473]][_x41903[2345]] = e[_x41903[473]][_x41903[688]],
c();
}, s, o, r)) : 16 == i[_x41903[4420]] ? $[_x41903[39]](i[_x41903[4615]][_x41903[473]], function(e, t) {
- t[_x41903[124]] == a && (s = r = o = 100, publicFun[_x41903[4586]]($(n[_x41903[476]])[_x41903[217]](_x41903[124]), function(e) {
+ t[_x41903[124]] == a && (s = r = o = 10240, publicFun[_x41903[4586]]($(n[_x41903[476]])[_x41903[217]](_x41903[124]), function(e) {
250 == e[_x41903[686]] && $[_x41903[2030]][_x41903[4089]](e[_x41903[4587]] || __(_x41903[4616])),
t[_x41903[2345]] = e[_x41903[473]][_x41903[688]],
c();
diff --git a/mall-shop/src/test/java/com/suisung/mall/shop/MallProductApplicationTests.java b/mall-shop/src/test/java/com/suisung/mall/shop/MallProductApplicationTests.java
deleted file mode 100644
index f74042fc..00000000
--- a/mall-shop/src/test/java/com/suisung/mall/shop/MallProductApplicationTests.java
+++ /dev/null
@@ -1,38 +0,0 @@
-package com.suisung.mall.shop;
-
-import com.suisung.mall.common.constant.MqConstant;
-import com.suisung.mall.shop.message.service.MqMessageService;
-import com.suisung.mall.shop.order.service.ShopOrderBaseService;
-import org.junit.jupiter.api.Test;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.boot.test.context.SpringBootTest;
-
-@SpringBootTest
-class MallProductApplicationTests {
-
- @Autowired
- ShopOrderBaseService shopOrderBaseService;
-
- @Autowired
- private MqMessageService mqMessageService;
-
- @Test
- void contextLoads() {
-
- }
-
- /**
- * 自动确认收货测试
- */
- @Test
- public void receiveTest() {
- shopOrderBaseService.autoReceive();
- }
-
- @Test
- public void test01() {
- mqMessageService.sendMqMsg(MqConstant.SHOP_EXCHANGE, MqConstant.SHOP_MSG_ROUTING_KEY, "你真好看!");
-
-
- }
-}