From 07a420c1e6a2cfa79d62121b3f6ced6a99648126 Mon Sep 17 00:00:00 2001 From: Jack <46790855@qq.com> Date: Fri, 26 Sep 2025 00:56:18 +0800 Subject: [PATCH 1/5] =?UTF-8?q?=E5=95=86=E6=88=B7=E5=85=A5=E9=A9=BB?= =?UTF-8?q?=E5=90=8E=E5=A2=9E=E5=8A=A0=E4=BA=86=E8=AE=BE=E7=BD=AE=E6=8F=90?= =?UTF-8?q?=E7=8E=B0=E6=A8=A1=E5=BC=8F=EF=BC=9A=E8=87=AA=E5=8A=A8=E7=BB=93?= =?UTF-8?q?=E7=AE=97=E4=BD=99=E9=A2=9D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../modules/lakala/LklLedgerMember.java | 1 + .../impl/ShopBaseCrontabServiceImpl.java | 2 +- .../quartz/job/UpdateOrderStatusJob.java | 4 +- .../service/impl/QuartzServiceImpl.java | 8 ++ .../admin/LakalaAdminController.java | 24 +++- .../controller/mobile/LakalaController.java | 19 +++ .../shop/lakala/service/LakalaApiService.java | 20 +++ .../service/LklLedgerMemberService.java | 9 ++ .../service/impl/LakalaApiServiceImpl.java | 119 +++++++++++++++++- .../impl/LklLedgerMemberServiceImpl.java | 36 ++++++ .../service/impl/SFExpressApiServiceImpl.java | 63 ++++++---- .../service/impl/ShopMchEntryServiceImpl.java | 3 + 12 files changed, 282 insertions(+), 26 deletions(-) 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-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 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/service/LakalaApiService.java b/mall-shop/src/main/java/com/suisung/mall/shop/lakala/service/LakalaApiService.java index 1b28f065..8d1ff881 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,25 @@ 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); } 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/impl/LakalaApiServiceImpl.java b/mall-shop/src/main/java/com/suisung/mall/shop/lakala/service/impl/LakalaApiServiceImpl.java index c04d3518..6f004db7 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 @@ -682,7 +682,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 +1800,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 +3257,121 @@ 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", "处理成功"); + } + } 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/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/impl/ShopMchEntryServiceImpl.java b/mall-shop/src/main/java/com/suisung/mall/shop/store/service/impl/ShopMchEntryServiceImpl.java index f47f5463..b2d7568e 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 @@ -1777,6 +1777,9 @@ public class ShopMchEntryServiceImpl extends BaseServiceImpl Date: Fri, 26 Sep 2025 08:58:47 +0800 Subject: [PATCH 2/5] =?UTF-8?q?=E5=95=86=E6=88=B7=E5=85=A5=E9=A9=BB?= =?UTF-8?q?=E5=90=8E=E5=A2=9E=E5=8A=A0=E4=BA=86=E8=AE=BE=E7=BD=AE=E6=8F=90?= =?UTF-8?q?=E7=8E=B0=E6=A8=A1=E5=BC=8F=EF=BC=9A=E8=87=AA=E5=8A=A8=E7=BB=93?= =?UTF-8?q?=E7=AE=97=E4=BD=99=E9=A2=9D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../service/AccountBaseConfigService.java | 15 ++ .../base/service/ShopBaseDistrictService.java | 29 +++ .../impl/AccountBaseConfigServiceImpl.java | 39 ++++ .../impl/ShopBaseDistrictServiceImpl.java | 202 ++++++++++++++++++ .../service/impl/ShopUserCartServiceImpl.java | 14 +- .../shop/MallProductApplicationTests.java | 38 ---- 6 files changed, 298 insertions(+), 39 deletions(-) delete mode 100644 mall-shop/src/test/java/com/suisung/mall/shop/MallProductApplicationTests.java 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/ShopBaseDistrictServiceImpl.java b/mall-shop/src/main/java/com/suisung/mall/shop/base/service/impl/ShopBaseDistrictServiceImpl.java index 833187ae..e484a094 100644 --- a/mall-shop/src/main/java/com/suisung/mall/shop/base/service/impl/ShopBaseDistrictServiceImpl.java +++ b/mall-shop/src/main/java/com/suisung/mall/shop/base/service/impl/ShopBaseDistrictServiceImpl.java @@ -13,6 +13,7 @@ import com.suisung.mall.core.web.service.impl.BaseServiceImpl; import com.suisung.mall.shop.base.mapper.ShopBaseDistrictMapper; import com.suisung.mall.shop.base.service.AccountBaseConfigService; import com.suisung.mall.shop.base.service.ShopBaseDistrictService; +import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.core.io.ClassPathResource; import org.springframework.stereotype.Service; @@ -30,6 +31,7 @@ import java.util.*; * @author Xinze * @since 2021-06-28 */ +@Slf4j @Service public class ShopBaseDistrictServiceImpl extends BaseServiceImpl implements ShopBaseDistrictService { @@ -339,4 +341,204 @@ 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); + List districts = new ArrayList<>(idStrs.length); + + // 先获取所有地区对象 + for (String idStr : idStrs) { + Integer districtId = Convert.toInt(idStr); + if (districtId == null) { + log.warn("[地区转换] ID格式不正确: {}", idStr); + return ""; + } + + ShopBaseDistrict district = get(districtId); + if (district == null) { + log.warn("[地区转换] 未找到对应地区信息, districtId: {}", districtId); + return ""; + } + + districts.add(district); + } + + // 按照层级关系重新排序 + List sortedDistricts = sortDistrictsByHierarchy(districts); + + // 提取名称 + for (ShopBaseDistrict district : sortedDistricts) { + 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 districts = new ArrayList<>(names.length); + + // 先根据名称获取所有地区对象(不考虑顺序) + for (String name : names) { + if (StrUtil.isBlank(name)) { + log.warn("[地区转换] 名称不能为空"); + return ""; + } + + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq("district_name", name.trim()); + + ShopBaseDistrict district = findOne(queryWrapper); + if (district == null) { + log.warn("[地区转换] 未找到对应地区信息, name: {}", name); + return ""; + } + + districts.add(district); + } + + // 按照层级关系重新排序 + List sortedDistricts = sortDistrictsByHierarchy(districts); + + // 提取ID + List ids = new ArrayList<>(sortedDistricts.size()); + for (ShopBaseDistrict district : sortedDistricts) { + ids.add(district.getDistrict_id().toString()); + } + + return String.join("/", ids); + } + + /** + * 根据层级关系对地区进行排序 + * + * @param districts 地区列表 + * @return 按层级排序后的地区列表 + */ + private List sortDistrictsByHierarchy(List districts) { + if (districts.size() <= 1) { + return districts; + } + + // 构建ID到地区的映射 + Map districtMap = new HashMap<>(); + for (ShopBaseDistrict district : districts) { + districtMap.put(district.getDistrict_id(), district); + } + + // 构建层级关系 + List result = new ArrayList<>(districts.size()); + Set processedIds = new HashSet<>(); + + // 找到最顶级的地区(parent_id为0或者parent不在列表中的) + for (ShopBaseDistrict district : districts) { + if (district.getDistrict_parent_id() == 0 || !districtMap.containsKey(district.getDistrict_parent_id())) { + result.add(district); + processedIds.add(district.getDistrict_id()); + break; + } + } + + // 逐级查找子地区 + while (result.size() < districts.size()) { + ShopBaseDistrict lastDistrict = result.get(result.size() - 1); + boolean found = false; + + for (ShopBaseDistrict district : districts) { + if (!processedIds.contains(district.getDistrict_id()) && + district.getDistrict_parent_id().equals(lastDistrict.getDistrict_id())) { + result.add(district); + processedIds.add(district.getDistrict_id()); + found = true; + break; + } + } + + // 如果找不到下一级,则添加剩余未处理的地区 + if (!found) { + for (ShopBaseDistrict district : districts) { + if (!processedIds.contains(district.getDistrict_id())) { + result.add(district); + processedIds.add(district.getDistrict_id()); + } + } + break; + } + } + + return result; + } + + } diff --git a/mall-shop/src/main/java/com/suisung/mall/shop/user/service/impl/ShopUserCartServiceImpl.java b/mall-shop/src/main/java/com/suisung/mall/shop/user/service/impl/ShopUserCartServiceImpl.java index 4b38b8c0..2de90dc0 100644 --- a/mall-shop/src/main/java/com/suisung/mall/shop/user/service/impl/ShopUserCartServiceImpl.java +++ b/mall-shop/src/main/java/com/suisung/mall/shop/user/service/impl/ShopUserCartServiceImpl.java @@ -2653,12 +2653,24 @@ public class ShopUserCartServiceImpl extends BaseServiceImpl Date: Fri, 26 Sep 2025 10:01:19 +0800 Subject: [PATCH 3/5] =?UTF-8?q?=E5=9C=B0=E5=8C=BA=E5=A2=9E=E5=8A=A0?= =?UTF-8?q?=E4=BA=86=E4=B8=89=E4=B8=AA=E6=96=B9=E6=B3=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../mall/shop/base/service/impl/ShopBaseDistrictServiceImpl.java | 1 - 1 file changed, 1 deletion(-) diff --git a/mall-shop/src/main/java/com/suisung/mall/shop/base/service/impl/ShopBaseDistrictServiceImpl.java b/mall-shop/src/main/java/com/suisung/mall/shop/base/service/impl/ShopBaseDistrictServiceImpl.java index e484a094..7730dc48 100644 --- a/mall-shop/src/main/java/com/suisung/mall/shop/base/service/impl/ShopBaseDistrictServiceImpl.java +++ b/mall-shop/src/main/java/com/suisung/mall/shop/base/service/impl/ShopBaseDistrictServiceImpl.java @@ -536,7 +536,6 @@ public class ShopBaseDistrictServiceImpl extends BaseServiceImpl Date: Fri, 26 Sep 2025 15:11:50 +0800 Subject: [PATCH 4/5] =?UTF-8?q?=E5=AE=9A=E6=97=B6=E4=BB=BB=E5=8A=A1=20?= =?UTF-8?q?=E7=98=A6=E8=BA=AB?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ShopOrderBaseServiceImpl.java | 119 ------------------ .../impl/ShopBaseDistrictServiceImpl.java | 118 ++++------------- .../service/impl/QuartzServiceImpl.java | 93 +++++--------- .../controller/mobile/LakalaController.java | 11 +- .../store/service/ShopMchEntryService.java | 10 ++ .../service/impl/ShopMchEntryServiceImpl.java | 84 ++++++++++--- .../src/main/resources/bootstrap-dev.yml | 8 ++ .../src/main/resources/bootstrap-local.yml | 8 ++ .../src/main/resources/bootstrap-prod.yml | 8 ++ .../src/main/resources/bootstrap-test.yml | 8 ++ .../src/main/resources/bootstrap-uat.yml | 8 ++ 11 files changed, 180 insertions(+), 295 deletions(-) delete mode 100644 ShopOrderBaseServiceImpl.java 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-shop/src/main/java/com/suisung/mall/shop/base/service/impl/ShopBaseDistrictServiceImpl.java b/mall-shop/src/main/java/com/suisung/mall/shop/base/service/impl/ShopBaseDistrictServiceImpl.java index 7730dc48..1ace1af5 100644 --- a/mall-shop/src/main/java/com/suisung/mall/shop/base/service/impl/ShopBaseDistrictServiceImpl.java +++ b/mall-shop/src/main/java/com/suisung/mall/shop/base/service/impl/ShopBaseDistrictServiceImpl.java @@ -352,39 +352,37 @@ public class ShopBaseDistrictServiceImpl extends BaseServiceImpl names = new ArrayList<>(idStrs.length); - List districts = new ArrayList<>(idStrs.length); - // 先获取所有地区对象 + // 先获取所有地区对象的名称 for (String idStr : idStrs) { Integer districtId = Convert.toInt(idStr); if (districtId == null) { log.warn("[地区转换] ID格式不正确: {}", idStr); - return ""; + names.add(""); // 添加空字符串而不是直接返回 + continue; // 继续处理下一个 } ShopBaseDistrict district = get(districtId); if (district == null) { log.warn("[地区转换] 未找到对应地区信息, districtId: {}", districtId); - return ""; + names.add(""); // 添加空字符串而不是直接返回 + continue; // 继续处理下一个 } - districts.add(district); - } - - // 按照层级关系重新排序 - List sortedDistricts = sortDistrictsByHierarchy(districts); - - // 提取名称 - for (ShopBaseDistrict district : sortedDistricts) { names.add(district.getDistrict_name()); } return String.join("/", names); } + /** * 根据省市区名称路径获取对应的ID路径 * 例如:广西壮族自治区/贵港市/桂平市 -> 450000/450800/450881 @@ -447,13 +439,14 @@ public class ShopBaseDistrictServiceImpl extends BaseServiceImpl districts = new ArrayList<>(names.length); + List ids = new ArrayList<>(names.length); - // 先根据名称获取所有地区对象(不考虑顺序) + // 先根据名称获取所有地区对象的ID for (String name : names) { if (StrUtil.isBlank(name)) { log.warn("[地区转换] 名称不能为空"); - return ""; + ids.add(""); // 添加空字符串而不是直接返回 + continue; // 继续处理下一个 } QueryWrapper queryWrapper = new QueryWrapper<>(); @@ -462,82 +455,15 @@ public class ShopBaseDistrictServiceImpl extends BaseServiceImpl sortedDistricts = sortDistrictsByHierarchy(districts); - - // 提取ID - List ids = new ArrayList<>(sortedDistricts.size()); - for (ShopBaseDistrict district : sortedDistricts) { ids.add(district.getDistrict_id().toString()); } return String.join("/", ids); } - /** - * 根据层级关系对地区进行排序 - * - * @param districts 地区列表 - * @return 按层级排序后的地区列表 - */ - private List sortDistrictsByHierarchy(List districts) { - if (districts.size() <= 1) { - return districts; - } - - // 构建ID到地区的映射 - Map districtMap = new HashMap<>(); - for (ShopBaseDistrict district : districts) { - districtMap.put(district.getDistrict_id(), district); - } - - // 构建层级关系 - List result = new ArrayList<>(districts.size()); - Set processedIds = new HashSet<>(); - - // 找到最顶级的地区(parent_id为0或者parent不在列表中的) - for (ShopBaseDistrict district : districts) { - if (district.getDistrict_parent_id() == 0 || !districtMap.containsKey(district.getDistrict_parent_id())) { - result.add(district); - processedIds.add(district.getDistrict_id()); - break; - } - } - - // 逐级查找子地区 - while (result.size() < districts.size()) { - ShopBaseDistrict lastDistrict = result.get(result.size() - 1); - boolean found = false; - - for (ShopBaseDistrict district : districts) { - if (!processedIds.contains(district.getDistrict_id()) && - district.getDistrict_parent_id().equals(lastDistrict.getDistrict_id())) { - result.add(district); - processedIds.add(district.getDistrict_id()); - found = true; - break; - } - } - - // 如果找不到下一级,则添加剩余未处理的地区 - if (!found) { - for (ShopBaseDistrict district : districts) { - if (!processedIds.contains(district.getDistrict_id())) { - result.add(district); - processedIds.add(district.getDistrict_id()); - } - } - break; - } - } - return result; - } - } 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 f46dc356..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,52 +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)); } - logger.info("Trigger当前状态: {}", scheduler.getTriggerState(triggerKey)); - - // 在调度器启动检查前添加 - logger.debug("[Quartz] 调度器当前状态 - isStarted: {}, SchedulerName: {}", - scheduler.isStarted(), scheduler.getSchedulerName()); - } 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); } } @@ -140,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; } } @@ -170,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); } } @@ -199,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); } } @@ -228,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/mobile/LakalaController.java b/mall-shop/src/main/java/com/suisung/mall/shop/lakala/controller/mobile/LakalaController.java index f4403d5c..fbe88173 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 = "批量发送推送消息 - 测试案例") 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 b2d7568e..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(); } @@ -2470,6 +2465,57 @@ public class ShopMchEntryServiceImpl extends BaseServiceImpl Date: Sat, 27 Sep 2025 11:28:02 +0800 Subject: [PATCH 5/5] =?UTF-8?q?=E7=99=BE=E5=BA=A6=E5=9C=B0=E5=9B=BE=20ak?= =?UTF-8?q?=20=E9=85=8D=E7=BD=AE=E6=9B=B4=E6=94=B9=EF=BC=8C=E6=8B=89?= =?UTF-8?q?=E5=8D=A1=E6=8B=89=E6=8F=90=E7=8E=B0=E4=BB=A3=E7=A0=81=E5=BC=80?= =?UTF-8?q?=E5=8F=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../common/modules/lakala/LklOrderDraw.java | 185 +++++++++++++++ .../src/main/resources/application-dev.yml | 4 +- .../src/main/resources/application-local.yml | 4 +- .../src/main/resources/application-prod.yml | 4 +- .../src/main/resources/application-test.yml | 4 +- .../src/main/resources/application-uat.yml | 4 +- .../admin/LakalaAdminController.java | 23 +- .../controller/mobile/LakalaController.java | 19 ++ .../lakala/mapper/LklOrderDrawMapper.java | 19 ++ .../shop/lakala/service/LakalaApiService.java | 21 ++ .../lakala/service/LklOrderDrawService.java | 32 +++ .../service/impl/LakalaApiServiceImpl.java | 213 ++++++++++++++++++ .../service/impl/LklOrderDrawServiceImpl.java | 105 +++++++++ mall-shop/src/main/resources/application.yml | 34 +-- .../src/main/resources/bootstrap-dev.yml | 38 +++- .../src/main/resources/bootstrap-local.yml | 38 +++- .../src/main/resources/bootstrap-prod.yml | 38 +++- .../src/main/resources/bootstrap-test.yml | 38 +++- .../src/main/resources/bootstrap-uat.yml | 38 +++- .../mapper/lakala/LklOrderDrawMapper.xml | 8 + .../src/main/resources/static/diy/js/diy.js | 2 +- 21 files changed, 791 insertions(+), 80 deletions(-) create mode 100644 mall-common/src/main/java/com/suisung/mall/common/modules/lakala/LklOrderDraw.java create mode 100644 mall-shop/src/main/java/com/suisung/mall/shop/lakala/mapper/LklOrderDrawMapper.java create mode 100644 mall-shop/src/main/java/com/suisung/mall/shop/lakala/service/LklOrderDrawService.java create mode 100644 mall-shop/src/main/java/com/suisung/mall/shop/lakala/service/impl/LklOrderDrawServiceImpl.java create mode 100644 mall-shop/src/main/resources/mapper/lakala/LklOrderDrawMapper.xml 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/lakala/controller/admin/LakalaAdminController.java b/mall-shop/src/main/java/com/suisung/mall/shop/lakala/controller/admin/LakalaAdminController.java index d57863b4..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 @@ -39,6 +39,27 @@ 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) { @@ -47,7 +68,7 @@ public class LakalaAdminController extends BaseControllerImpl { if (paramsJSON == null) { return CommonResult.failed("请求参数不能为空"); } - + // 执行业务逻辑 Boolean success = lakalaPayService.ewalletSettleProfile(paramsJSON.getStr("mercId"), paramsJSON.getStr("settleType"), paramsJSON.getStr("settleTime")); 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 fbe88173..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 @@ -248,6 +248,25 @@ 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 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 8d1ff881..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 @@ -330,4 +330,25 @@ public interface LakalaApiService { */ 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/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 6f004db7..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; @@ -3373,5 +3377,214 @@ public class LakalaApiServiceImpl implements LakalaApiService { .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/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/resources/application.yml b/mall-shop/src/main/resources/application.yml index dca587a2..3f0e2695 100644 --- a/mall-shop/src/main/resources/application.yml +++ b/mall-shop/src/main/resources/application.yml @@ -28,38 +28,6 @@ spring: content-type: text/html; charset=utf-8 suffix: .html template-loader-path: classpath:/templates/ - quartz: - job-store-type: jdbc - jdbc: - initialize-schema: always # 每次启动项目都重新清空定时任务 - properties: - org: - quartz: - scheduler: - instanceName: DefaultQuartzScheduler - instanceId: AUTO - rmi: - export: false - proxy: false - jobStore: - class: org.quartz.impl.jdbcjobstore.JobStoreTX - driverDelegateClass: org.quartz.impl.jdbcjobstore.StdJDBCDelegate - tablePrefix: QRTZ_ - isClustered: false - useProperties: false - misfireThreshold: 60000 - threadPool: - class: org.quartz.simpl.SimpleThreadPool - threadCount: 10 - threadPriority: 5 - threadsInheritContextClassLoaderOfInitializingThread: true - dataSource: - myDS: - URL: jdbc:mysql:///test?characterEncoding=utf8&serverTimezone=UTC - user: store - password: brCnv0qLt8s0VqhI - driver: com.mysql.jdbc.Driver - maxConnections: 5 mybatis-plus: mapper-locations: classpath:/mapper/**/*.xml global-config: @@ -100,7 +68,7 @@ ribbon: ConnectTimeout: 60000 #服务请求连接超时时间(毫秒) ReadTimeout: 60000 #服务请求处理超时时间(毫秒) baidu: - ak: "uwBrIUOZuTDMHsuRGm0hdmeG9sosN8sQ" # 百度地图ak + ak: "YzRPLAOTYyCFVjvlh2vxnaUnH4jPjufM" # 百度地图ak # 定时任务列表 job: diff --git a/mall-shop/src/main/resources/bootstrap-dev.yml b/mall-shop/src/main/resources/bootstrap-dev.yml index ff304d3a..6245658f 100644 --- a/mall-shop/src/main/resources/bootstrap-dev.yml +++ b/mall-shop/src/main/resources/bootstrap-dev.yml @@ -66,13 +66,37 @@ spring: dashboard: @sentinel.transport.dashboard@ eager: true quartz: - # 调度器实例名称 - scheduler-name: mallScheduler - # 线程池配置 - thread-pool: - thread-count: 15 # 增加线程数以处理更多并发任务 - # 错过触发器策略 - job-store-type: memory + job-store-type: jdbc + jdbc: + initialize-schema: always + properties: + org: + quartz: + scheduler: + instanceName: DefaultQuartzScheduler + instanceId: AUTO + rmi: + export: false + proxy: false + jobStore: + class: org.quartz.impl.jdbcjobstore.JobStoreTX + driverDelegateClass: org.quartz.impl.jdbcjobstore.StdJDBCDelegate + tablePrefix: QRTZ_ + isClustered: false + useProperties: false + misfireThreshold: 120000 + threadPool: + class: org.quartz.simpl.SimpleThreadPool + threadCount: 15 + threadPriority: 5 + threadsInheritContextClassLoaderOfInitializingThread: true + dataSource: + myDS: + URL: jdbc:mysql://@mysql.host@:@mysql.port@/@mysql.db@?rewriteBatchedStatements=true&useUnicode=true&characterEncoding=utf-8&serverTimezone=Asia/Shanghai&&zeroDateTimeBehavior=convertToNull&autoReconnect=true&failOverReadOnly=false&maxReconnects=5 + user: @mysql.user@ + password: @mysql.pwd@ + driver: @mysql.driver@ + maxConnections: 5 upload: # 图片上传配置 filepath: @upload.filepath@ # 本地环境静态文件路径 seata: diff --git a/mall-shop/src/main/resources/bootstrap-local.yml b/mall-shop/src/main/resources/bootstrap-local.yml index 055e954e..4820f882 100644 --- a/mall-shop/src/main/resources/bootstrap-local.yml +++ b/mall-shop/src/main/resources/bootstrap-local.yml @@ -66,13 +66,37 @@ spring: dashboard: @sentinel.transport.dashboard@ eager: true quartz: - # 调度器实例名称 - scheduler-name: mallScheduler - # 线程池配置 - thread-pool: - thread-count: 15 # 增加线程数以处理更多并发任务 - # 错过触发器策略 - job-store-type: memory + job-store-type: jdbc + jdbc: + initialize-schema: always + properties: + org: + quartz: + scheduler: + instanceName: DefaultQuartzScheduler + instanceId: AUTO + rmi: + export: false + proxy: false + jobStore: + class: org.quartz.impl.jdbcjobstore.JobStoreTX + driverDelegateClass: org.quartz.impl.jdbcjobstore.StdJDBCDelegate + tablePrefix: QRTZ_ + isClustered: false + useProperties: false + misfireThreshold: 120000 + threadPool: + class: org.quartz.simpl.SimpleThreadPool + threadCount: 15 + threadPriority: 5 + threadsInheritContextClassLoaderOfInitializingThread: true + dataSource: + myDS: + URL: jdbc:mysql://@mysql.host@:@mysql.port@/@mysql.db@?rewriteBatchedStatements=true&useUnicode=true&characterEncoding=utf-8&serverTimezone=Asia/Shanghai&&zeroDateTimeBehavior=convertToNull&autoReconnect=true&failOverReadOnly=false&maxReconnects=5 + user: @mysql.user@ + password: @mysql.pwd@ + driver: @mysql.driver@ + maxConnections: 5 upload: # 图片上传配置 filepath: @upload.filepath@ # 本地环境静态文件路径 seata: diff --git a/mall-shop/src/main/resources/bootstrap-prod.yml b/mall-shop/src/main/resources/bootstrap-prod.yml index bdfb2296..7470b438 100644 --- a/mall-shop/src/main/resources/bootstrap-prod.yml +++ b/mall-shop/src/main/resources/bootstrap-prod.yml @@ -73,13 +73,37 @@ spring: dashboard: @sentinel.transport.dashboard@ eager: true quartz: - # 调度器实例名称 - scheduler-name: mallScheduler - # 线程池配置 - thread-pool: - thread-count: 15 # 增加线程数以处理更多并发任务 - # 错过触发器策略 - job-store-type: memory + job-store-type: jdbc + jdbc: + initialize-schema: always + properties: + org: + quartz: + scheduler: + instanceName: DefaultQuartzScheduler + instanceId: AUTO + rmi: + export: false + proxy: false + jobStore: + class: org.quartz.impl.jdbcjobstore.JobStoreTX + driverDelegateClass: org.quartz.impl.jdbcjobstore.StdJDBCDelegate + tablePrefix: QRTZ_ + isClustered: false + useProperties: false + misfireThreshold: 120000 + threadPool: + class: org.quartz.simpl.SimpleThreadPool + threadCount: 15 + threadPriority: 5 + threadsInheritContextClassLoaderOfInitializingThread: true + dataSource: + myDS: + URL: jdbc:mysql://@mysql.host@:@mysql.port@/@mysql.db@?rewriteBatchedStatements=true&useUnicode=true&characterEncoding=utf-8&serverTimezone=Asia/Shanghai&&zeroDateTimeBehavior=convertToNull&autoReconnect=true&failOverReadOnly=false&maxReconnects=5 + user: @mysql.user@ + password: @mysql.pwd@ + driver: @mysql.driver@ + maxConnections: 5 upload: # 图片上传配置 filepath: @upload.filepath@ # 本地环境静态文件路径 seata: diff --git a/mall-shop/src/main/resources/bootstrap-test.yml b/mall-shop/src/main/resources/bootstrap-test.yml index 41089593..1500963d 100644 --- a/mall-shop/src/main/resources/bootstrap-test.yml +++ b/mall-shop/src/main/resources/bootstrap-test.yml @@ -70,13 +70,37 @@ spring: dashboard: @sentinel.transport.dashboard@ eager: true quartz: - # 调度器实例名称 - scheduler-name: mallScheduler - # 线程池配置 - thread-pool: - thread-count: 15 # 增加线程数以处理更多并发任务 - # 错过触发器策略 - job-store-type: memory + job-store-type: jdbc + jdbc: + initialize-schema: always + properties: + org: + quartz: + scheduler: + instanceName: DefaultQuartzScheduler + instanceId: AUTO + rmi: + export: false + proxy: false + jobStore: + class: org.quartz.impl.jdbcjobstore.JobStoreTX + driverDelegateClass: org.quartz.impl.jdbcjobstore.StdJDBCDelegate + tablePrefix: QRTZ_ + isClustered: false + useProperties: false + misfireThreshold: 120000 + threadPool: + class: org.quartz.simpl.SimpleThreadPool + threadCount: 15 + threadPriority: 5 + threadsInheritContextClassLoaderOfInitializingThread: true + dataSource: + myDS: + URL: jdbc:mysql://@mysql.host@:@mysql.port@/@mysql.db@?rewriteBatchedStatements=true&useUnicode=true&characterEncoding=utf-8&serverTimezone=Asia/Shanghai&&zeroDateTimeBehavior=convertToNull&autoReconnect=true&failOverReadOnly=false&maxReconnects=5 + user: @mysql.user@ + password: @mysql.pwd@ + driver: @mysql.driver@ + maxConnections: 5 upload: # 图片上传配置 filepath: @upload.filepath@ # 本地环境静态文件路径 seata: diff --git a/mall-shop/src/main/resources/bootstrap-uat.yml b/mall-shop/src/main/resources/bootstrap-uat.yml index 41089593..1500963d 100644 --- a/mall-shop/src/main/resources/bootstrap-uat.yml +++ b/mall-shop/src/main/resources/bootstrap-uat.yml @@ -70,13 +70,37 @@ spring: dashboard: @sentinel.transport.dashboard@ eager: true quartz: - # 调度器实例名称 - scheduler-name: mallScheduler - # 线程池配置 - thread-pool: - thread-count: 15 # 增加线程数以处理更多并发任务 - # 错过触发器策略 - job-store-type: memory + job-store-type: jdbc + jdbc: + initialize-schema: always + properties: + org: + quartz: + scheduler: + instanceName: DefaultQuartzScheduler + instanceId: AUTO + rmi: + export: false + proxy: false + jobStore: + class: org.quartz.impl.jdbcjobstore.JobStoreTX + driverDelegateClass: org.quartz.impl.jdbcjobstore.StdJDBCDelegate + tablePrefix: QRTZ_ + isClustered: false + useProperties: false + misfireThreshold: 120000 + threadPool: + class: org.quartz.simpl.SimpleThreadPool + threadCount: 15 + threadPriority: 5 + threadsInheritContextClassLoaderOfInitializingThread: true + dataSource: + myDS: + URL: jdbc:mysql://@mysql.host@:@mysql.port@/@mysql.db@?rewriteBatchedStatements=true&useUnicode=true&characterEncoding=utf-8&serverTimezone=Asia/Shanghai&&zeroDateTimeBehavior=convertToNull&autoReconnect=true&failOverReadOnly=false&maxReconnects=5 + user: @mysql.user@ + password: @mysql.pwd@ + driver: @mysql.driver@ + maxConnections: 5 upload: # 图片上传配置 filepath: @upload.filepath@ # 本地环境静态文件路径 seata: diff --git a/mall-shop/src/main/resources/mapper/lakala/LklOrderDrawMapper.xml b/mall-shop/src/main/resources/mapper/lakala/LklOrderDrawMapper.xml new file mode 100644 index 00000000..d82d81e8 --- /dev/null +++ b/mall-shop/src/main/resources/mapper/lakala/LklOrderDrawMapper.xml @@ -0,0 +1,8 @@ + + + + + + * + + 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();