diff --git a/mall-account/src/main/java/com/suisung/mall/account/service/impl/AccountUserBaseServiceImpl.java b/mall-account/src/main/java/com/suisung/mall/account/service/impl/AccountUserBaseServiceImpl.java index 05344de3..3954baf6 100644 --- a/mall-account/src/main/java/com/suisung/mall/account/service/impl/AccountUserBaseServiceImpl.java +++ b/mall-account/src/main/java/com/suisung/mall/account/service/impl/AccountUserBaseServiceImpl.java @@ -1950,10 +1950,10 @@ public class AccountUserBaseServiceImpl extends BaseServiceImpl smsArgs = new HashMap<>(); smsArgs.put("password", user_password_src); - sendSmsMessage(PhoneNumberUtils.cleanPhoneNumber(user_mobile), "SMS_481085172", smsArgs); + sendSmsMessage(PhoneNumberUtils.cleanPhoneNumber(user_mobile), "SMS_496910525", smsArgs); // SMS_496910525 } //初次注册发送消息 diff --git a/mall-common/src/main/java/com/suisung/mall/common/modules/order/ShopOrderItem.java b/mall-common/src/main/java/com/suisung/mall/common/modules/order/ShopOrderItem.java index 850aa92d..a44a70aa 100644 --- a/mall-common/src/main/java/com/suisung/mall/common/modules/order/ShopOrderItem.java +++ b/mall-common/src/main/java/com/suisung/mall/common/modules/order/ShopOrderItem.java @@ -45,10 +45,13 @@ public class ShopOrderItem implements Serializable { @ApiModelProperty(value = "产品编号") private Long product_id; - + @ApiModelProperty(value = "货品编号") private Long item_id; + @ApiModelProperty(value = "产品条形码(唯一码)") + private String item_barcode; + @ApiModelProperty(value = "商品名称") private String item_name; diff --git a/mall-common/src/main/java/com/suisung/mall/common/modules/order/dto/MchOrderInfoDTO.java b/mall-common/src/main/java/com/suisung/mall/common/modules/order/dto/MchOrderInfoDTO.java index 16d9451d..10666a79 100644 --- a/mall-common/src/main/java/com/suisung/mall/common/modules/order/dto/MchOrderInfoDTO.java +++ b/mall-common/src/main/java/com/suisung/mall/common/modules/order/dto/MchOrderInfoDTO.java @@ -95,4 +95,16 @@ public class MchOrderInfoDTO implements Serializable { private Integer is_deny_return; @ApiModelProperty(value = "异常订单操作流程,0-可操作自行发货,1-可操作订单完成,2-订单完成不可操作") private String operate_flag; + + @ApiModelProperty(value = "订单配送预约状态:1-立即配送;2-预约配送") + private Integer booking_state; + + @ApiModelProperty(value = "预约送达起始时间,格式如:yyyy-MM-dd HH:mm:ss") + private Date booking_begin_time; + + @ApiModelProperty(value = "预约送达截止时间,格式如:yyyy-MM-dd HH:mm:ss") + private Date booking_end_time; + + @ApiModelProperty(value = "预订单到达时间戳(秒)") + private Long booking_at; } diff --git a/mall-common/src/main/java/com/suisung/mall/common/pojo/dto/BookingArgDTO.java b/mall-common/src/main/java/com/suisung/mall/common/pojo/dto/BookingArgDTO.java new file mode 100644 index 00000000..8b0457db --- /dev/null +++ b/mall-common/src/main/java/com/suisung/mall/common/pojo/dto/BookingArgDTO.java @@ -0,0 +1,78 @@ +package com.suisung.mall.common.pojo.dto; + +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import lombok.EqualsAndHashCode; + +import java.util.List; + +/** + * 预订参数DTO实体类 + */ +@Data +@EqualsAndHashCode(callSuper = false) +@ApiModel(value = "预约订单参数DTO", description = "预约订单参数DTO") +public class BookingArgDTO { + + /** + * 日期标题(如"今天(周二)") + */ + @ApiModelProperty(value = "日期标题") + private String date_title; + + /** + * 日期字符串(如"01月09日") + */ + @ApiModelProperty(value = "日期字符串") + private String date_str; + + /** + * 日期(如"2025-01-09") + */ + @ApiModelProperty(value = "日期") + private String date; + + /** + * 时间项列表 + */ + @ApiModelProperty(value = "时间项列表") + private List items; + + /** + * 预订时间项实体类 + */ + @Data + public static class BookingArgItem { + + /** + * 时间标题(如"立即送出"或"09:15-09:45") + */ + @ApiModelProperty(value = "时间标题") + private String time_title; + + /** + * 预订时间戳 + */ + @ApiModelProperty(value = "预订时间戳") + private Long booking_at; + + /** + * 预订状态 + */ + @ApiModelProperty(value = "预订状态:1-立即下单;2-预约下单;") + private Integer booking_state; + + /** + * 预订开始时间 + */ + @ApiModelProperty(value = "预订开始时间") + private String booking_begin_time; + + /** + * 预订结束时间 + */ + @ApiModelProperty(value = "预订结束时间") + private String booking_end_time; + } +} diff --git a/mall-common/src/main/java/com/suisung/mall/common/pojo/dto/StoreBizTimeInfoDTO.java b/mall-common/src/main/java/com/suisung/mall/common/pojo/dto/StoreBizTimeInfoDTO.java new file mode 100644 index 00000000..27239f7a --- /dev/null +++ b/mall-common/src/main/java/com/suisung/mall/common/pojo/dto/StoreBizTimeInfoDTO.java @@ -0,0 +1,29 @@ +/* + * Copyright (c) 2024. 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.pojo.dto; + +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.io.Serializable; + +@Data +@AllArgsConstructor +@NoArgsConstructor +/** + * 标准的地址实体类 + */ +public class StoreBizTimeInfoDTO implements Serializable { + private Integer store_id; + private String store_name; + private Integer store_biz_state; + private String store_opening_hours; + private String store_close_hours; +} diff --git a/mall-common/src/main/java/com/suisung/mall/common/utils/DateTimeUtils.java b/mall-common/src/main/java/com/suisung/mall/common/utils/DateTimeUtils.java index f6f0de8e..c94b058c 100644 --- a/mall-common/src/main/java/com/suisung/mall/common/utils/DateTimeUtils.java +++ b/mall-common/src/main/java/com/suisung/mall/common/utils/DateTimeUtils.java @@ -178,6 +178,23 @@ public class DateTimeUtils { } } + /** + * 根据日期获取星期几 + * + * @param date 日期 + * @return 星期几 + */ + public static String getWeekOfDate(Date date) { + String[] weekDays = {"周日", "周一", "周二", "周三", "周四", "周五", "周六"}; + Calendar cal = Calendar.getInstance(); + cal.setTime(date); + int w = cal.get(Calendar.DAY_OF_WEEK) - 1; + if (w < 0) { + w = 0; + } + return weekDays[w]; + } + /** * 将多种日期格式转换为 yyyy-MM-dd @@ -473,6 +490,7 @@ public class DateTimeUtils { } } + /** * 判断时间字符串是否与格式模式匹配 * diff --git a/mall-common/src/main/java/com/suisung/mall/common/utils/phone/PhoneNumberUtils.java b/mall-common/src/main/java/com/suisung/mall/common/utils/phone/PhoneNumberUtils.java index 454ae152..3bc93a46 100644 --- a/mall-common/src/main/java/com/suisung/mall/common/utils/phone/PhoneNumberUtils.java +++ b/mall-common/src/main/java/com/suisung/mall/common/utils/phone/PhoneNumberUtils.java @@ -352,6 +352,8 @@ public class PhoneNumberUtils { System.out.println(cleanPhoneNumber("+3541234567")); // 期望输出: 1234567 System.out.println(cleanPhoneNumber("+85298765432")); + System.out.println(PhoneNumberUtils.checkPhoneNumber("+8617777525395")); + } } diff --git a/mall-shop/src/main/java/com/suisung/mall/shop/esign/service/EsignPlatformInfoService.java b/mall-shop/src/main/java/com/suisung/mall/shop/esign/service/EsignPlatformInfoService.java index 208ca9c5..1e3c8097 100644 --- a/mall-shop/src/main/java/com/suisung/mall/shop/esign/service/EsignPlatformInfoService.java +++ b/mall-shop/src/main/java/com/suisung/mall/shop/esign/service/EsignPlatformInfoService.java @@ -73,4 +73,12 @@ public interface EsignPlatformInfoService { * @return */ EsignPlatformInfo getMch2ndAgentWithShippingFee(Long mchId); + + /** + * 根据代理商ID获取供应商 商家ID + * + * @param agentId + * @return + */ + String getSupplierIdByAgentId(Long agentId); } diff --git a/mall-shop/src/main/java/com/suisung/mall/shop/esign/service/impl/EsignPlatformInfoServiceImpl.java b/mall-shop/src/main/java/com/suisung/mall/shop/esign/service/impl/EsignPlatformInfoServiceImpl.java index f85c1fb4..6aa55a76 100644 --- a/mall-shop/src/main/java/com/suisung/mall/shop/esign/service/impl/EsignPlatformInfoServiceImpl.java +++ b/mall-shop/src/main/java/com/suisung/mall/shop/esign/service/impl/EsignPlatformInfoServiceImpl.java @@ -122,7 +122,7 @@ public class EsignPlatformInfoServiceImpl extends BaseServiceImpl 手机号和营业执照号的键值对,获取失败时返回null */ @Override public Pair getEsignPlatformMobileAndLicenseNumber() { - QueryWrapper queryWrapper = new QueryWrapper(); - queryWrapper.eq("level", 0).select("telephone", "license_number", "legal_person_mobile"); - List esignPlatformInfos = list(queryWrapper); - if (CollectionUtil.isEmpty(esignPlatformInfos)) { + log.debug("[获取平台方信息] 开始获取平台方手机号和营业执照号"); + + try { + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq("level", 0) + .eq("status", CommonConstant.Enable) + .select("telephone", "license_number", "legal_person_mobile"); + + EsignPlatformInfo esignPlatformInfo = findOne(queryWrapper); + if (esignPlatformInfo == null) { + log.warn("[获取平台方信息] 未找到有效的平台方记录"); + return null; + } + + // 优先使用telephone字段,如验证失败则使用legal_person_mobile + String mobile = esignPlatformInfo.getTelephone(); + if (!PhoneNumberUtils.checkPhoneNumber(mobile) + && StrUtil.isNotBlank(esignPlatformInfo.getLegal_person_mobile()) + && PhoneNumberUtils.checkPhoneNumber(esignPlatformInfo.getLegal_person_mobile())) { + log.debug("[获取平台方信息] 主手机号验证失败,使用法人手机号"); + mobile = esignPlatformInfo.getLegal_person_mobile(); + } + + log.debug("[获取平台方信息] 成功获取平台方信息,手机号:{},营业执照号:{}", + mobile, esignPlatformInfo.getLicense_number()); + return Pair.of(mobile, esignPlatformInfo.getLicense_number()); + + } catch (Exception e) { + log.error("[获取平台方信息] 查询平台方信息时发生异常", e); return null; } - - EsignPlatformInfo esignPlatformInfo = esignPlatformInfos.get(0); - String mobile = esignPlatformInfo.getTelephone(); - if (!PhoneNumberUtils.checkPhoneNumber(mobile) && StrUtil.isNotBlank(esignPlatformInfo.getLegal_person_mobile())) { - mobile = esignPlatformInfo.getLegal_person_mobile(); - } - - return Pair.of(mobile, esignPlatformInfo.getLicense_number()); } + /** * 根据入驻编号获取商户的二级代理 * @@ -294,4 +312,46 @@ public class EsignPlatformInfoServiceImpl extends BaseServiceImpl queryWrapper = new QueryWrapper<>(); + queryWrapper.eq("id", agentId) + .eq("level", CommonConstant.Agent_Level_2nd) + .eq("status", CommonConstant.Enable) + .select("supplier_id"); + + // 查询记录 + EsignPlatformInfo result = getOne(queryWrapper); + + // 检查结果并返回 + if (result != null && StrUtil.isNotBlank(result.getSupplier_id())) { + log.debug("[获取供应商ID] 成功获取供应商ID,agentId={}, supplierId={}", agentId, result.getSupplier_id()); + return result.getSupplier_id(); + } else { + log.debug("[获取供应商ID] 未找到有效的供应商ID,agentId={}", agentId); + return ""; + } + } catch (Exception e) { + log.error("[获取供应商ID] 查询过程中发生异常,agentId={}", agentId, e); + return ""; + } + } + + } 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 77ecfd50..1c9584c5 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 @@ -90,7 +90,9 @@ public class LakalaController extends BaseControllerImpl { @RequestMapping(value = "/testcase", method = RequestMethod.POST) public Object testcase(@RequestBody JSONObject paramsJSON) { - return lklLedgerReceiverService.selectAgentAndPlatformByMchId(36L); +// return lklLedgerReceiverService.selectAgentAndPlatformByMchId(36L); + + return lakalaApiService.ewalletWithDrawNotify(null, paramsJSON.getStr("a"), paramsJSON.getStr("b")); } @ApiOperation(value = "批量发送推送消息 - 测试案例", notes = "批量发送推送消息 - 测试案例") diff --git a/mall-shop/src/main/java/com/suisung/mall/shop/lakala/service/LklLedgerReceiverService.java b/mall-shop/src/main/java/com/suisung/mall/shop/lakala/service/LklLedgerReceiverService.java index 00666ce8..5cf0ed62 100644 --- a/mall-shop/src/main/java/com/suisung/mall/shop/lakala/service/LklLedgerReceiverService.java +++ b/mall-shop/src/main/java/com/suisung/mall/shop/lakala/service/LklLedgerReceiverService.java @@ -115,4 +115,5 @@ public interface LklLedgerReceiverService extends IBaseService signCheckResult = null; if (request != null) { // 1. 验签处理 - 验证通知来源的合法性 signCheckResult = LakalaUtil.chkLklApiNotifySign(request, lklNotifyCerPath, false); if (signCheckResult != null && !signCheckResult.getFirst()) { - log.warn("[拉卡拉D1提现结果通知] 验签失败: {}", signCheckResult.getSecond()); + log.warn("{} 验签失败: {}", signTag, signCheckResult.getSecond()); return JSONUtil.createObj() .set("code", "FAIL") .set("message", signCheckResult.getSecond()); @@ -3859,12 +3861,12 @@ public class LakalaApiServiceImpl implements LakalaApiService { paramsJSON = JSONUtil.parseObj(signCheckResult.getSecond()); } else { // 补偿机制。主动从拉卡拉上获取提现结果 + signTag = "[查询拉卡拉提现结果补偿]"; paramsJSON = ewalletWithdrawQuery(merchantNo, drawJnl); } - if (JSONUtil.isNull(paramsJSON)) { - log.warn("[拉卡拉D1提现结果通知] 回调参数解析失败"); + log.warn("{} 回调参数解析失败", signTag); return JSONUtil.createObj() .set("code", "FAIL") .set("message", "回调参数解析失败"); @@ -3875,10 +3877,10 @@ public class LakalaApiServiceImpl implements LakalaApiService { String merOrderNo = paramsJSON.getStr("merOrderNo"); String drawJnlRemote = paramsJSON.getStr("drawJnl"); - log.info("[拉卡拉D1提现结果通知] 提现通知参数: drawState={}, mercId={}, merOrderNo={},drawJnlRemote={}", drawState, mercId, merOrderNo, drawJnlRemote); + log.info("{} 提现通知参数: drawState={}, mercId={}, merOrderNo={},drawJnlRemote={}", signTag, drawState, mercId, merOrderNo, drawJnlRemote); if (StrUtil.hasBlank(mercId, merOrderNo, drawJnl, drawState)) { - log.warn("[拉卡拉提现结果通知] 回调参数缺失: drawState={}, mercId={}, merOrderNo={}, drawJnlRemote={}", drawState, mercId, merOrderNo, drawJnlRemote); + log.warn("{} 回调参数缺失: drawState={}, mercId={}, merOrderNo={}, drawJnlRemote={}", signTag, drawState, mercId, merOrderNo, drawJnlRemote); return JSONUtil.createObj() .set("code", "FAIL") .set("message", "回调参数错误"); @@ -3886,7 +3888,7 @@ public class LakalaApiServiceImpl implements LakalaApiService { Boolean isCompensate = lklOrderDrawService.isOrderDrawed(mercId, drawJnl); if (isCompensate) { - log.warn("[拉卡拉D1提现结果通知] 提现结果通知已处理,忽略处理: mercId={}, merOrderNo={}, drawJnl={}", mercId, merOrderNo, drawJnl); + log.warn("{} 提现结果通知已处理,忽略处理: mercId={}, merOrderNo={}, drawJnl={}", signTag, mercId, merOrderNo, drawJnl); return JSONUtil.createObj() .set("code", "SUCCESS") .set("message", "提现结果通知已处理"); @@ -3894,16 +3896,16 @@ public class LakalaApiServiceImpl implements LakalaApiService { // 只处理成功的提现状态 if (!"DRAW.SUCCESS".equals(drawState)) { - log.debug("[拉卡拉D1提现结果通知] 提现状态未成功,忽略处理: drawState={}", drawState); + log.debug("{} 提现状态未成功,忽略处理: drawState={}", signTag, drawState); return JSONUtil.createObj() .set("code", "FAIL") // 返回成功,避免重复通知 .set("message", "状态未成功,忽略处理"); } // 3. 转换参数并更新数据 - String snakeCaseJson = StringUtils.convertCamelToSnake(signCheckResult.getSecond()); + String snakeCaseJson = StringUtils.convertCamelToSnake(paramsJSON.toString()); if (StringUtils.isBlank(snakeCaseJson)) { - log.error("[拉卡拉D1提现结果通知] 回调参数转换失败,mercId={} merOrderNo={}", mercId, merOrderNo); + log.error("{} 回调参数转换失败,mercId={} merOrderNo={}", signTag, mercId, merOrderNo); return JSONUtil.createObj() .set("code", "FAIL") .set("message", "回调参数转换失败"); @@ -3911,21 +3913,23 @@ public class LakalaApiServiceImpl implements LakalaApiService { LklOrderDraw lklOrderDraw = JSONUtil.toBean(snakeCaseJson, LklOrderDraw.class); if (lklOrderDraw == null) { - log.error("[拉卡拉D1提现结果通知] 回调参数转换为对象失败,mercId={} merOrderNo={}", mercId, merOrderNo); + log.error("{} 回调参数转换为对象失败,mercId={} merOrderNo={}", signTag, mercId, merOrderNo); return JSONUtil.createObj() .set("code", "FAIL") .set("message", "回调参数转换失败"); } + lklOrderDraw.setRemark(lklOrderDraw.getRemark() + " " + signTag); + lklOrderDraw.setSummary(null); boolean isSuccess = lklOrderDrawService.addOrUpdateByMercIdAndMerOrderNo(lklOrderDraw); if (!isSuccess) { - log.error("[拉卡拉D1提现结果通知] 数据更新失败,mercId={} merOrderNo={}", mercId, merOrderNo); + log.error("{} 数据更新失败,mercId={} merOrderNo={}", signTag, mercId, merOrderNo); return JSONUtil.createObj() .set("code", "FAIL") .set("message", "数据更新失败"); } - log.info("[拉卡拉D1提现结果通知] 拉卡拉提现结果通知处理成功,mercId={} merOrderNo={}", mercId, merOrderNo); + log.info("{} 拉卡拉提现结果通知处理成功,mercId={} merOrderNo={}", signTag, mercId, merOrderNo); // 4. 返回成功响应 return JSONUtil.createObj() @@ -3933,7 +3937,7 @@ public class LakalaApiServiceImpl implements LakalaApiService { .set("message", "处理成功"); } catch (Exception e) { - log.error("[拉卡拉D1提现结果通知] 处理拉卡拉提现结果通知异常", e); + log.error(signTag + " 处理拉卡拉提现结果通知异常", e); return JSONUtil.createObj() .set("code", "FAIL") .set("message", "系统处理异常"); diff --git a/mall-shop/src/main/java/com/suisung/mall/shop/lakala/service/impl/LklLedgerReceiverServiceImpl.java b/mall-shop/src/main/java/com/suisung/mall/shop/lakala/service/impl/LklLedgerReceiverServiceImpl.java index 218519fd..82f436d4 100644 --- a/mall-shop/src/main/java/com/suisung/mall/shop/lakala/service/impl/LklLedgerReceiverServiceImpl.java +++ b/mall-shop/src/main/java/com/suisung/mall/shop/lakala/service/impl/LklLedgerReceiverServiceImpl.java @@ -25,7 +25,6 @@ import com.suisung.mall.core.web.service.impl.BaseServiceImpl; import com.suisung.mall.shop.esign.service.EsignPlatformInfoService; import com.suisung.mall.shop.lakala.mapper.LklLedgerReceiverMapper; import com.suisung.mall.shop.lakala.service.LakalaApiService; -import com.suisung.mall.shop.lakala.service.LklLedgerMemberService; import com.suisung.mall.shop.lakala.service.LklLedgerReceiverService; import com.suisung.mall.shop.store.service.ShopMchEntryService; import lombok.extern.slf4j.Slf4j; @@ -49,10 +48,6 @@ public class LklLedgerReceiverServiceImpl extends BaseServiceImpl list = shopOrderInfoService.genBookingOrderArgList(store_id); + return CommonResult.success(list); + } + } diff --git a/mall-shop/src/main/java/com/suisung/mall/shop/order/mapper/ShopOrderBaseMapper.java b/mall-shop/src/main/java/com/suisung/mall/shop/order/mapper/ShopOrderBaseMapper.java index cca3395f..e810443f 100644 --- a/mall-shop/src/main/java/com/suisung/mall/shop/order/mapper/ShopOrderBaseMapper.java +++ b/mall-shop/src/main/java/com/suisung/mall/shop/order/mapper/ShopOrderBaseMapper.java @@ -71,13 +71,14 @@ public interface ShopOrderBaseMapper extends BaseMapper { * @param delivery 配送方式:1-同城配送;2-物流配送 * @param status 同城配送订单状态(delivery=1时才生效):无值 or 0-全部订单;1-进行中订单;2-异常(超时)订单;3-退款订单;9-已完成订单 * @param logisticsStatus 普通快递订单状态(delivery=2时才生效):无值 or 0-全部订单;1-待支付订单;2-待发货订单;3-待接收订单;9-已完成订单 + * @param bookingState 订单配送预约状态:1-立即配送;2-预约配送 * @param expireSeconds 配送超时的秒数,单位秒 * @param beginTime 开始时间戳(13位毫秒级别) * @param endTime 截止时间戳(13位毫秒级别) * @param page 分页参数 * @return */ - IPage selectMchOrderPageList(@Param("storeId") Integer storeId, @Param("keyword") String keyword, @Param("delivery") Integer delivery, @Param("status") Integer status, @Param("logisticsStatus") Integer logisticsStatus, @Param("expireSeconds") Long expireSeconds, @Param("beginTime") Long beginTime, @Param("endTime") Long endTime, IPage page); + IPage selectMchOrderPageList(@Param("storeId") Integer storeId, @Param("keyword") String keyword, @Param("delivery") Integer delivery, @Param("status") Integer status, @Param("logisticsStatus") Integer logisticsStatus, @Param("bookingState") Integer bookingState, @Param("expireSeconds") Long expireSeconds, @Param("beginTime") Long beginTime, @Param("endTime") Long endTime, IPage page); /** @@ -97,12 +98,13 @@ public interface ShopOrderBaseMapper extends BaseMapper { * @param delivery 配送方式:1-同城配送;2-物流配送 * @param status 同城配送订单状态(delivery=1时才生效):无值 or 0-全部订单;1-进行中订单;2-异常(超时)订单;3-退款订单;9-已完成订单 * @param logisticsStatus 普通快递订单状态(delivery=2时才生效):无值 or 0-全部订单;1-待支付订单;2-待发货订单;3-待接收订单;9-已完成订单 + * @param bookingState 订单配送预约状态:1-立即配送;2-预约配送 * @param expireSeconds 配送超时的秒数,单位秒 * @param beginTime 开始时间戳(13位毫秒级别) * @param endTime 截止时间戳(13位毫秒级别) * @return */ - Long countMchOrderByCondition(@Param("storeId") Integer storeId, @Param("keyword") String keyword, @Param("delivery") Integer delivery, @Param("status") Integer status, @Param("logisticsStatus") Integer logisticsStatus, @Param("expireSeconds") Long expireSeconds, @Param("beginTime") Long beginTime, @Param("endTime") Long endTime); + Long countMchOrderByCondition(@Param("storeId") Integer storeId, @Param("keyword") String keyword, @Param("delivery") Integer delivery, @Param("status") Integer status, @Param("logisticsStatus") Integer logisticsStatus, @Param("bookingState") Integer bookingState, @Param("expireSeconds") Long expireSeconds, @Param("beginTime") Long beginTime, @Param("endTime") Long endTime); /** diff --git a/mall-shop/src/main/java/com/suisung/mall/shop/order/service/ShopOrderBaseService.java b/mall-shop/src/main/java/com/suisung/mall/shop/order/service/ShopOrderBaseService.java index 544ea9d8..d3b7965d 100644 --- a/mall-shop/src/main/java/com/suisung/mall/shop/order/service/ShopOrderBaseService.java +++ b/mall-shop/src/main/java/com/suisung/mall/shop/order/service/ShopOrderBaseService.java @@ -544,6 +544,7 @@ public interface ShopOrderBaseService extends IBaseService { * @param delivery 配送方式:1-同城配送;2-物流配送 * @param status 同城配送订单状态(delivery=1时才生效):无值 or 0-全部订单;1-进行中订单;2-异常(超时)订单;3-退款订单;9-已完成订单 * @param logisticsStatus 普通快递订单状态(delivery=2时才生效):无值 or 0-全部订单;1-待支付订单;2-待发货订单;3-待接收订单;9-已完成订单 + * @param bookingState 订单配送预约状态:1-立即配送;2-预约配送 * @param expireSeconds 配送超时的秒数,单位秒 * @param beginTime 开始时间戳(13位毫秒级别) * @param endTime 截止时间戳(13位毫秒级别) @@ -551,7 +552,7 @@ public interface ShopOrderBaseService extends IBaseService { * @param pageSize 页大小 * @return */ - IPage selectMchOrderPageList(Integer storeId, String keyword, Integer delivery, Integer status, Integer logisticsStatus, Long expireSeconds, Long beginTime, Long endTime, Integer pageNum, Integer pageSize); + IPage selectMchOrderPageList(Integer storeId, String keyword, Integer delivery, Integer status, Integer logisticsStatus, Integer bookingState, Long expireSeconds, Long beginTime, Long endTime, Integer pageNum, Integer pageSize); /** * 商家版根据条件查询订单条数(新) @@ -561,12 +562,13 @@ public interface ShopOrderBaseService extends IBaseService { * @param delivery 配送方式:1-同城配送;2-物流配送 * @param status 同城配送订单状态(delivery=1时才生效):无值 or 0-全部订单;1-进行中订单;2-异常(超时)订单;3-退款订单;9-已完成订单 * @param logisticsStatus 普通快递订单状态(delivery=2时才生效):无值 or 0-全部订单;1-待支付订单;2-待发货订单;3-待接收订单;9-已完成订单 + * @param bookingState 订单配送预约状态:1-立即配送;2-预约配送 * @param expireSeconds 配送超时的秒数,单位秒 * @param beginTime 开始时间戳(13位毫秒级别) * @param endTime 截止时间戳(13位毫秒级别) * @return */ - Long countMchOrderByCondition(Integer storeId, String keyword, Integer delivery, Integer status, Integer logisticsStatus, Long expireSeconds, Long beginTime, Long endTime); + Long countMchOrderByCondition(Integer storeId, String keyword, Integer delivery, Integer status, Integer logisticsStatus, Integer bookingState, Long expireSeconds, Long beginTime, Long endTime); /** * 获取商家订单详情 diff --git a/mall-shop/src/main/java/com/suisung/mall/shop/order/service/ShopOrderInfoService.java b/mall-shop/src/main/java/com/suisung/mall/shop/order/service/ShopOrderInfoService.java index 478a5e93..9f400d2a 100644 --- a/mall-shop/src/main/java/com/suisung/mall/shop/order/service/ShopOrderInfoService.java +++ b/mall-shop/src/main/java/com/suisung/mall/shop/order/service/ShopOrderInfoService.java @@ -2,6 +2,7 @@ package com.suisung.mall.shop.order.service; import com.suisung.mall.common.api.CommonResult; import com.suisung.mall.common.modules.order.ShopOrderInfo; +import com.suisung.mall.common.pojo.dto.BookingArgDTO; import com.suisung.mall.core.web.service.IBaseService; import org.springframework.data.util.Pair; @@ -133,4 +134,13 @@ public interface ShopOrderInfoService extends IBaseService { * @return */ Pair runBookingOrder2SfExpressOrder(String orderId); + + + /** + * 根据店铺的营业时间范围生成可预约下单的参数 + * + * @param storeId 店铺ID + * @return + */ + List genBookingOrderArgList(Integer storeId); } diff --git a/mall-shop/src/main/java/com/suisung/mall/shop/order/service/impl/ShopOrderBaseServiceImpl.java b/mall-shop/src/main/java/com/suisung/mall/shop/order/service/impl/ShopOrderBaseServiceImpl.java index 7b46bced..78991b42 100644 --- a/mall-shop/src/main/java/com/suisung/mall/shop/order/service/impl/ShopOrderBaseServiceImpl.java +++ b/mall-shop/src/main/java/com/suisung/mall/shop/order/service/impl/ShopOrderBaseServiceImpl.java @@ -573,10 +573,16 @@ public class ShopOrderBaseServiceImpl extends BaseServiceImpl pair = shopOrderInfoService.checkBookingOrderArgs(checkedStore, bookingState, bookingBeginTime, bookingEndTime); - if (!pair.getFirst()) { - throw new ApiException(I18nUtil._(pair.getSecond())); - } - - cartData.put("booking_state", bookingState); - cartData.put("booking_begin_time", bookingBeginTime); - cartData.put("booking_end_time", bookingEndTime); - } +// // 预约订单检测 +// Integer bookingState = Convert.toInt(getParameter("booking_state")); +// if (CheckUtil.isNotEmpty(bookingState) && CommonConstant.Order_Booking_State_YY.equals(bookingState)) { +// String bookingBeginTime = getParameter("booking_begin_time"); +// String bookingEndTime = getParameter("booking_end_time"); +// Long bookingAt = getParameter("booking_at", 0L); +// Pair pair = shopOrderInfoService.checkBookingOrderArgs(checkedStore, bookingState, bookingBeginTime, bookingEndTime); +// if (!pair.getFirst()) { +// throw new ApiException(I18nUtil._(pair.getSecond())); +// } +// +// cartData.put("booking_state", bookingState); +// cartData.put("booking_begin_time", bookingBeginTime); +// cartData.put("booking_end_time", bookingEndTime); +// cartData.put("booking_at", bookingAt); +// } // 添加保存订单(关键方法) List orderIdRow = addOrder(cartData, true, false, null); @@ -1666,7 +1674,6 @@ public class ShopOrderBaseServiceImpl extends BaseServiceImpl storeBizState = shopStoreBaseService.getStoreBizState(currStoreId); + if (storeBizState != null && CommonConstant.Disable2.equals(storeBizState.getFirst())) { + throw new ApiException(I18nUtil._(storeBizState.getSecond() + ",无法提交订单。")); + } + + // 每个订单记录的商品列表 List item_items = (List) store_item.get("items"); Map activitys = (Map) ObjectUtil.defaultIfNull(store_item.get("activitys"), new HashMap()); @@ -6318,6 +6334,7 @@ public class ShopOrderBaseServiceImpl extends BaseServiceImpl kinds = Arrays.asList(StateCode.PRODUCT_KIND_FUWU, StateCode.PRODUCT_KIND_CARD); // 是否为虚拟商品订单 boolean isVirtualGoods = kinds.contains(kind_id); @@ -6630,23 +6647,46 @@ public class ShopOrderBaseServiceImpl extends BaseServiceImpl pair = shopOrderInfoService.checkBookingOrderArgs(info_row.getStore_id(), bookingState, bookingBeginTimeStr, bookingEndTimeStr); + if (!pair.getFirst()) { + throw new ApiException(I18nUtil._(pair.getSecond())); + } + + Date bookingBeginTime = DateTimeUtils.tryParseDateTimeToDate(bookingBeginTimeStr); + Date bookingEndTime = DateTimeUtils.tryParseDateTimeToDate(bookingEndTimeStr); + if (bookingBeginTime == null) { + throw new ApiException(I18nUtil._("预约下单时间格式有误!")); + } + + // 设置预约时间戳 + if (CheckUtil.isEmpty(bookingAt)) { + bookingAt = bookingBeginTime.getTime() / 1000; // 预订单到达时间戳(秒) + } + info_row.setBooking_state(bookingState); - info_row.setBooking_at(bookingBeginTime.getTime() / 1000); // 预订单到达时间戳(秒) + info_row.setBooking_at(bookingAt); info_row.setBooking_begin_time(bookingBeginTime); info_row.setBooking_end_time(bookingEndTime); // 重要:预约订单任务创建处理 - Boolean isSuccess = shopOrderBookingService.setupRedisBookingTask(info_row.getOrder_id(), info_row.getBooking_at()); - if (!isSuccess) { + if (!shopOrderBookingService.setupRedisBookingTask(info_row.getOrder_id(), info_row.getBooking_at())) { throw new ApiException(I18nUtil._("保存预约订单任务失败!")); } } + info_row.setActivity_json(JSONUtil.toJsonStr(store_item.get("discount_detail_rows"))); info_row.setPayment_form_id(payment_form_id); UserDto user = getCurrentUser(); @@ -6880,13 +6920,13 @@ public class ShopOrderBaseServiceImpl extends BaseServiceImpl selectMchOrderPageList(Integer storeId, String keyword, Integer delivery, Integer status, Integer logisticsStatus, Long expireSeconds, Long beginTime, Long endTime, Integer pageNum, Integer pageSize) { + public IPage selectMchOrderPageList(Integer storeId, String keyword, Integer delivery, Integer status, Integer logisticsStatus, Integer bookingState, Long expireSeconds, Long beginTime, Long endTime, Integer pageNum, Integer pageSize) { try { // 初始化分页对象 Page page = new Page<>(pageNum, pageSize); // 查询订单基础数据 IPage pageList = shopOrderBaseMapper.selectMchOrderPageList( - storeId, keyword, delivery, status, logisticsStatus, expireSeconds, beginTime, endTime, page); + storeId, keyword, delivery, status, logisticsStatus, bookingState, expireSeconds, beginTime, endTime, page); if (CollUtil.isEmpty(pageList.getRecords())) { return pageList; @@ -9036,14 +9079,15 @@ public class ShopOrderBaseServiceImpl extends BaseServiceImpl getAutoCancelOrderIdByPage(Integer pageNum, Integer pageSize) { QueryWrapper queryWrapper = new QueryWrapper<>(); @@ -879,18 +879,18 @@ public class ShopOrderInfoServiceImpl extends BaseServiceImpl genBookingOrderArgList(Integer storeId) { + // 初始化默认营业时间 + String openingHours = "09:00"; + String closeHours = "18:00"; + + // 如果storeId不为空,则尝试获取店铺信息 + if (storeId != null) { + try { + ShopStoreInfo shopStoreInfo = shopStoreInfoService.getShopStoreInfoByStoreId(storeId); + if (shopStoreInfo != null) { + // 检查并使用店铺设置的营业时间 + if (StrUtil.isNotBlank(shopStoreInfo.getStore_opening_hours())) { + openingHours = shopStoreInfo.getStore_opening_hours(); + } + if (StrUtil.isNotBlank(shopStoreInfo.getStore_close_hours())) { + closeHours = shopStoreInfo.getStore_close_hours(); + } + logger.debug("[生成预约参数] 使用店铺营业时间,storeId: {}, opening: {}, close: {}", storeId, openingHours, closeHours); + } else { + logger.warn("[生成预约参数] 未找到店铺信息,使用默认营业时间,storeId: {}", storeId); + } + } catch (Exception e) { + logger.error("[生成预约参数] 获取店铺信息异常,使用默认营业时间,storeId: {}", storeId, e); + } + } else { + logger.warn("[生成预约参数] 店铺ID为空,使用默认营业时间"); + } + + List result = new ArrayList<>(); + + // 生成未来7天的数据 + Date now = new Date(); + for (int i = 0; i < 7; i++) { + Date currentDate = DateUtil.offsetDay(now, i); + BookingArgDTO bookingArgDTO = new BookingArgDTO(); + + // 设置日期相关信息 + String dateStr = DateUtil.format(currentDate, "yyyy-MM-dd"); + String displayDateStr = DateUtil.format(currentDate, "MM月dd日"); + + // 安全获取星期信息 + String weekStr = "未知"; + try { + weekStr = DateTimeUtils.getWeekOfDate(currentDate); + } catch (Exception e) { + logger.warn("[生成预约参数] 获取星期信息异常,使用默认值,date: {}", dateStr); + } + + // 设置date_title + if (i == 0) { + bookingArgDTO.setDate_title("今天(" + weekStr + ")"); + } else if (i == 1) { + bookingArgDTO.setDate_title("明天(" + weekStr + ")"); + } else { + bookingArgDTO.setDate_title(displayDateStr + "(" + weekStr + ")"); + } + + bookingArgDTO.setDate_str(displayDateStr); + bookingArgDTO.setDate(dateStr); + + // 生成时间项 + List items = generateTimeSlots(dateStr, openingHours, closeHours, i == 0); + bookingArgDTO.setItems(items != null ? items : new ArrayList<>()); + + result.add(bookingArgDTO); + } + + logger.debug("[生成预约参数] 成功生成预约参数,storeId: {}, opening: {}, close: {}, 参数数量: {}", + storeId, openingHours, closeHours, result.size()); + return result; + } + + + /** + * 生成时间槽列表 + * + * @param dateStr 日期字符串 yyyy-MM-dd + * @param openingHours 开始营业时间 HH:mm + * @param closeHours 结束营业时间 HH:mm + * @param isToday 是否是今天 + * @return 时间槽列表 + */ + private List generateTimeSlots(String dateStr, String openingHours, String closeHours, boolean isToday) { + // 参数校验 + if (StrUtil.isBlank(dateStr) || StrUtil.isBlank(openingHours) || StrUtil.isBlank(closeHours)) { + logger.warn("[生成时间槽] 参数为空,dateStr: {}, openingHours: {}, closeHours: {}", dateStr, openingHours, closeHours); + return Collections.emptyList(); + } + + try { + List items = new ArrayList<>(); + + // 添加"立即送出"选项(仅限今天) + if (isToday) { + BookingArgDTO.BookingArgItem immediateItem = new BookingArgDTO.BookingArgItem(); + immediateItem.setTime_title("立即送出"); + immediateItem.setBooking_at(0L); + immediateItem.setBooking_state(1); + immediateItem.setBooking_begin_time(""); + immediateItem.setBooking_end_time(""); + items.add(immediateItem); + } + + // 解析营业时间 + Date openTime = DateUtil.parse(dateStr + " " + openingHours + ":00", "yyyy-MM-dd HH:mm:ss"); + Date closeTime = DateUtil.parse(dateStr + " " + closeHours + ":00", "yyyy-MM-dd HH:mm:ss"); + + // 验证营业时间有效性 + if (openTime.after(closeTime)) { + logger.warn("[生成时间槽] 营业时间无效,openTime: {}, closeTime: {}", openTime, closeTime); + return items; + } + + // 时间槽间隔(分钟) + int slotInterval = 30; + + // 对于今天,需要特殊处理:第二个时间槽从当前时间+50分钟开始 + Date startTime = openTime; + if (isToday) { + // 当前时间+50分钟作为第二个时间槽的开始时间 + Date nowPlusFifty = DateUtil.offsetMinute(new Date(), 50); + + // 如果当前时间+50分钟在营业时间范围内,则从该时间开始 + if (nowPlusFifty.after(openTime) && nowPlusFifty.before(closeTime)) { + startTime = nowPlusFifty; + } + // 如果当前时间+50分钟已经超过营业结束时间,则不生成后续时间槽 + else if (nowPlusFifty.after(closeTime)) { + logger.debug("[生成时间槽] 当前时间+50分钟已超过营业结束时间,不生成后续时间槽"); + return items; + } + } + + // 生成时间槽 + Date currentTimeSlot = startTime; + int slotCount = 0; + final int MAX_SLOTS = 48; // 最多生成48个时间段,防止异常循环 + + while (currentTimeSlot.before(closeTime) && slotCount < MAX_SLOTS) { + Date endTimeSlot = DateUtil.offsetMinute(currentTimeSlot, slotInterval); + + // 如果结束时间超过了营业结束时间,则使用营业结束时间 + if (endTimeSlot.after(closeTime)) { + endTimeSlot = closeTime; + } + + // 创建时间段项 + BookingArgDTO.BookingArgItem timeItem = new BookingArgDTO.BookingArgItem(); + String beginTimeStr = DateUtil.format(currentTimeSlot, "HH:mm"); + String endTimeStr = DateUtil.format(endTimeSlot, "HH:mm"); + + timeItem.setTime_title(beginTimeStr + "-" + endTimeStr); + + // 时间戳计算(秒) + long bookingAt = currentTimeSlot.getTime() / 1000; + timeItem.setBooking_at(bookingAt); + + timeItem.setBooking_state(2); + timeItem.setBooking_begin_time(DateUtil.format(currentTimeSlot, "yyyy-MM-dd HH:mm:ss")); + timeItem.setBooking_end_time(DateUtil.format(endTimeSlot, "yyyy-MM-dd HH:mm:ss")); + + items.add(timeItem); + + // 移动到下一个时间段 + currentTimeSlot = endTimeSlot; + slotCount++; + + // 防止时间相同导致的死循环 + if (currentTimeSlot.equals(startTime)) { + logger.warn("[生成时间槽] 检测到时间循环,跳出循环"); + break; + } + } + + if (slotCount >= MAX_SLOTS) { + logger.warn("[生成时间槽] 时间段数量超过最大限制,date: {}", dateStr); + } + + logger.debug("[生成时间槽] 成功生成时间槽,date: {}, 时间段数量: {}", dateStr, items.size()); + return items; + } catch (Exception e) { + logger.error("[生成时间槽] 生成时间槽异常,date: {}, openingHours: {}, closeHours: {}", dateStr, openingHours, closeHours, e); + return Collections.emptyList(); + } + } + } diff --git a/mall-shop/src/main/java/com/suisung/mall/shop/sfexpress/service/SFExpressApiService.java b/mall-shop/src/main/java/com/suisung/mall/shop/sfexpress/service/SFExpressApiService.java index 4ea70306..3bd8f276 100644 --- a/mall-shop/src/main/java/com/suisung/mall/shop/sfexpress/service/SFExpressApiService.java +++ b/mall-shop/src/main/java/com/suisung/mall/shop/sfexpress/service/SFExpressApiService.java @@ -29,6 +29,7 @@ public interface SFExpressApiService { /** * 创建顺丰同店铺-连锁店铺 * + * @param mchId 商家入驻编号 * @param storeId 商家门店ID * @param shopName 店名 * @param cityName 城市 @@ -39,7 +40,7 @@ public interface SFExpressApiService { * @param latitude 纬度 * @return */ - Pair createSfExpressShop(Integer storeId, String shopName, String cityName, String shopAddress, String contactName, String contactPhone, String longitude, String latitude); + Pair createSfExpressShop(Long mchId, Integer storeId, String shopName, String cityName, String shopAddress, String contactName, String contactPhone, String longitude, String latitude); /** 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 ea46e35d..f43aed70 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 @@ -32,6 +32,7 @@ import com.suisung.mall.common.pojo.req.*; import com.suisung.mall.common.pojo.res.ThirdApiRes; import com.suisung.mall.common.pojo.to.AddressParseResultTO; import com.suisung.mall.common.utils.*; +import com.suisung.mall.shop.esign.service.EsignPlatformInfoService; import com.suisung.mall.shop.message.service.PushMessageService; import com.suisung.mall.shop.order.service.ShopOrderBaseService; import com.suisung.mall.shop.order.service.ShopOrderInfoService; @@ -119,6 +120,10 @@ public class SFExpressApiServiceImpl implements SFExpressApiService { @Autowired private ShopProductItemService shopProductItemService; + @Lazy + @Autowired + private EsignPlatformInfoService esignPlatformInfoService; + /** * 创建顺丰同店铺-连锁店铺 * @@ -180,7 +185,6 @@ public class SFExpressApiServiceImpl implements SFExpressApiService { return Pair.of(false, "联系人手机号不能为空"); } - AddressParseResultTO addressParseResultTO = AddressUtil.parseAddress(shopMchEntry.getStore_address()); // 解析城市名称 String cityName = "桂平市"; // 默认城市 @@ -212,6 +216,7 @@ public class SFExpressApiServiceImpl implements SFExpressApiService { // 调用创建店铺方法 Pair result = createSfExpressShop( + mchId, Convert.toInt(shopMchEntry.getStore_id()), shopStoreName, cityName, @@ -228,8 +233,9 @@ public class SFExpressApiServiceImpl implements SFExpressApiService { /** - * 创建顺丰同城(普通型)店铺 + * 创建顺丰同店铺-连锁店铺 * + * @param mchId 商家入驻编号 * @param storeId 商家门店ID * @param shopName 店名 * @param cityName 城市 @@ -241,19 +247,40 @@ public class SFExpressApiServiceImpl implements SFExpressApiService { * @return Pair 第一个元素表示是否成功,第二个元素表示结果信息或错误信息 */ @Override - public Pair createSfExpressShop(Integer storeId, String shopName, String cityName, + public Pair createSfExpressShop(Long mchId, Integer storeId, String shopName, String cityName, String shopAddress, String contactName, String contactPhone, String longitude, String latitude) { logger.info("开始创建顺丰同城店铺, storeId: {}", storeId); try { // 1. 验证必要参数 - if (CheckUtil.isEmpty(storeId) || StringUtils.isAnyBlank(shopName, shopAddress, contactName, contactPhone)) { - logger.error("创建顺丰店铺,缺少必要参数!storeId:{},shopName:{},shopAddress:{},contactName:{},contactPhone:{}", storeId, shopName, shopAddress, contactName, contactPhone); + if ((CheckUtil.isEmpty(mchId) && CheckUtil.isEmpty(storeId)) || + StringUtils.isAnyBlank(shopName, shopAddress, contactName, contactPhone)) { + logger.error("创建顺丰店铺,缺少必要参数!mchId:{}, storeId:{},shopName:{},shopAddress:{},contactName:{},contactPhone:{}", + mchId, storeId, shopName, shopAddress, contactName, contactPhone); return Pair.of(false, "创建顺丰店铺,缺少必要参数!"); } - // 2. 获取或初始化商家配送信息 + // 2. 获取商家入驻信息 + ShopMchEntry shopMchEntry; + if (CheckUtil.isNotEmpty(mchId)) { + shopMchEntry = shopMchEntryService.shopMerchEntryById(mchId); + if (shopMchEntry == null) { + logger.error("无法找到商家入驻信息!mchId: {}", mchId); + return Pair.of(false, "无法找到商家入驻信息"); + } + + storeId = Convert.toInt(shopMchEntry.getStore_id()); + + } else { + shopMchEntry = shopMchEntryService.getShopMerchEntryByStoreId(storeId); + if (shopMchEntry == null) { + logger.error("无法找到商家入驻信息!storeId: {}", storeId); + return Pair.of(false, "无法找到商家入驻信息"); + } + } + + // 3. 获取或初始化商家配送信息 ShopStoreSameCityTransportBase transportBase = shopStoreSameCityTransportBaseService .getShopStoreSameCityTransportBaseById(Long.valueOf(storeId)); @@ -264,46 +291,55 @@ public class SFExpressApiServiceImpl implements SFExpressApiService { } if (transportBase == null) { - logger.error("创建商家配送信息失败!"); + logger.error("创建商家配送信息失败!storeId: {}", storeId); return Pair.of(false, "创建商家配送信息失败"); } - // 3. 如果已存在顺丰店铺ID,验证其有效性 + // 4. 如果已存在顺丰店铺ID,验证其有效性 if (CheckUtil.isNotEmpty(transportBase.getShop_id())) { - logger.debug("如果存在店铺Id,从顺丰同城平台查询店铺ID,开始验证其有效性!"); + logger.debug("检测到已存在店铺Id,开始验证其有效性!shopId: {}", transportBase.getShop_id()); ThirdApiRes shopInfo = getSfShopInfo(transportBase.getShop_id()); if (shopInfo != null && shopInfo.getError_code().equals(0)) { - logger.info("已成功创建顺丰同城店铺!"); + logger.info("已成功创建顺丰同城店铺!shopId: {}", transportBase.getShop_id()); return Pair.of(true, transportBase.getShop_id()); } } - // 4. 构建请求参数 - Map params = buildCommonParams(); - params.put("supplier_id", supplierId); // 店铺所属商家id - params.put("out_shop_id", storeId); // 外部店铺ID - params.put("shop_name", shopName); // 店铺名称 - params.put("city_name", cityName); // 城市名称 + // 5. 获取供应商ID + String sfSupplierId = ""; + // 获取创建店铺的商家Id(由店铺的县级代理商提供) + if (CheckUtil.isNotEmpty(shopMchEntry.getDistributor_id())) { + logger.debug("获取创建店铺的县级代理商Id: distributorId={}", shopMchEntry.getDistributor_id()); + sfSupplierId = esignPlatformInfoService.getSupplierIdByAgentId(shopMchEntry.getDistributor_id()); + } - // RMK 1:快餐 2:药品 3:百货 4:脏衣服收 5:干净衣服派 6:生鲜 8:高端饮品 9:现场勘验 10:快递 12:文件 13:蛋糕 14:鲜花 15:数码 16:服装 17: - //汽配 18:珠宝 20:披萨 21:中餐 22:水产 27:专人直送 32:中端饮品 33:便利店 34:面包糕点 35:火锅 36:证照 40:烧烤小龙虾 41:外部落地配 47:烟酒 - //行 48:成人用品 99:其他 - // 经营类型: 快餐,百货,生鲜,高端饮品,蛋糕,鲜花,数码,服装,披萨,水产,中端饮品,便利店,面包糕点,烟酒,其他 - params.put("shop_product_types", "33"); //"1,3,6,8,13,14,15,16,20,22,32,33,34,47,99" - params.put("shop_type", 1); // 店铺类型: 1-普通型 2-平台型 - params.put("shop_address", shopAddress); // 店铺地址 - params.put("longitude", longitude); // 经度 - params.put("latitude", latitude); // 纬度 - params.put("shop_contact_name", contactName); // 联系人姓名 - params.put("shop_contact_phone", contactPhone); // 联系电话 + // 县级代理商如果没有商家Id,直接获取默认配置的商家Id + if (StrUtil.isBlank(sfSupplierId)) { + sfSupplierId = supplierId; + } + + // 6. 构建请求参数 + Map params = buildCommonParams(); + params.put("supplier_id", sfSupplierId); // 店铺所属商家id(应该由县级代理商提供) + params.put("out_shop_id", storeId); // 外部店铺ID + params.put("shop_name", shopName); // 店铺名称 + params.put("city_name", cityName); // 城市名称 + params.put("shop_product_types", "33"); // 经营类型: 33-便利店 + params.put("shop_type", 1); // 店铺类型: 1-普通型 2-平台型 + params.put("shop_address", shopAddress); // 店铺地址 + params.put("longitude", longitude); // 经度 + params.put("latitude", latitude); // 纬度 + params.put("shop_contact_name", contactName); // 联系人姓名 + params.put("shop_contact_phone", contactPhone); // 联系电话 logger.debug("开始创建顺丰店铺,参数:{}", params); - // 5. 发送请求到顺丰接口 + // 7. 发送请求到顺丰接口 String paramJSON = JsonUtil.toJSONString(params); String sendUrl = buildUrl("createShop", paramJSON); String responseStr = HttpUtil.post(sendUrl, paramJSON); - logger.debug("创建顺丰店铺结果:{}", responseStr); + logger.debug("创建顺丰店铺结果: {}", responseStr); + if (StrUtil.isBlank(responseStr)) { logger.error("创建顺丰店铺异常,无返回值!"); return Pair.of(false, "创建顺丰店铺异常,无返回值!"); @@ -315,18 +351,24 @@ public class SFExpressApiServiceImpl implements SFExpressApiService { return Pair.of(false, "创建顺丰店铺异常,返回值有误!"); } - // 6. 检查接口调用结果 + // 8. 检查接口调用结果 if (!apiRes.getError_code().equals(0) || apiRes.getResult() == null) { - String errMsg = apiRes.getError_code().equals(0) ? "创建顺丰店铺失败!" : "创建顺丰店铺失败: " + apiRes.getError_msg(); + String errMsg = StrUtil.isBlank(apiRes.getError_msg()) ? + "创建顺丰店铺失败。" : "创建顺丰店铺失败: " + apiRes.getError_msg(); logger.error("创建顺丰店铺失败: {}", errMsg); return Pair.of(false, errMsg); } - // 7. 提取顺丰店铺ID并更新数据库 + // 9. 提取顺丰店铺ID并更新数据库 JSONObject result = (JSONObject) apiRes.getResult(); String sfShopId = result.getStr("shop_id"); + if (StrUtil.isBlank(sfShopId)) { + logger.error("创建顺丰店铺失败,返回的店铺ID为空"); + return Pair.of(false, "创建顺丰店铺失败,返回的店铺ID为空"); + } + transportBase.setShop_id(sfShopId); - transportBase.setShop_state(CommonConstant.Enable);// 顺丰同城快递商品特惠 + transportBase.setShop_state(CommonConstant.Enable); // 顺丰同城快递商品特惠 transportBase.setDelivery_brand(CommonConstant.DELIVERY_BRAND_SF); Pair updateResult = shopStoreSameCityTransportBaseService @@ -346,6 +388,7 @@ public class SFExpressApiServiceImpl implements SFExpressApiService { } } + /** * 创建顺丰同城(普通型)店铺(直调顺丰同城的接口,脱离我们的业务) * diff --git a/mall-shop/src/main/java/com/suisung/mall/shop/store/mapper/ShopStoreBaseMapper.java b/mall-shop/src/main/java/com/suisung/mall/shop/store/mapper/ShopStoreBaseMapper.java index 37768251..1a41b02c 100644 --- a/mall-shop/src/main/java/com/suisung/mall/shop/store/mapper/ShopStoreBaseMapper.java +++ b/mall-shop/src/main/java/com/suisung/mall/shop/store/mapper/ShopStoreBaseMapper.java @@ -4,7 +4,9 @@ import com.baomidou.mybatisplus.core.mapper.BaseMapper; import com.baomidou.mybatisplus.core.metadata.IPage; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.suisung.mall.common.modules.store.ShopStoreBase; +import com.suisung.mall.common.pojo.dto.StoreBizTimeInfoDTO; import io.lettuce.core.dynamic.annotation.Param; +import org.apache.ibatis.annotations.Select; import org.springframework.stereotype.Repository; import java.util.List; @@ -31,10 +33,23 @@ public interface ShopStoreBaseMapper extends BaseMapper { /** * 搜索附近店铺,排序:从近到远 2024-12-26 + * * @param page * @param params 省份province_id、城市city_id、县county_id、店铺分类store_category_id、分店subsite_id,店铺名称关键字store_name、 * @return */ IPage getNearShop2(Page page, @Param("params") Map params); + + /** + * 获取店铺营业时间信息 + * + * @param storeId + * @return + */ + @Select("SELECT ssb.store_id, ssb.store_name, ssb.store_biz_state, ssi.store_opening_hours, ssi.store_close_hours " + + " FROM shop_store_base ssb LEFT JOIN shop_store_info ssi ON ssb.store_id = ssi.store_id " + + " WHERE ssb.store_id = #{storeId} LIMIT 1") + StoreBizTimeInfoDTO getStoreBizTimeInfo(@Param("storeId") Integer storeId); + } diff --git a/mall-shop/src/main/java/com/suisung/mall/shop/store/service/ShopStoreBaseService.java b/mall-shop/src/main/java/com/suisung/mall/shop/store/service/ShopStoreBaseService.java index dbfd8ef3..31a5b2ec 100644 --- a/mall-shop/src/main/java/com/suisung/mall/shop/store/service/ShopStoreBaseService.java +++ b/mall-shop/src/main/java/com/suisung/mall/shop/store/service/ShopStoreBaseService.java @@ -237,6 +237,14 @@ public interface ShopStoreBaseService extends IBaseService { */ Integer getStoreBizState(ShopStoreBase shopStoreBase, ShopStoreInfo shopStoreInfo); + /** + * 根据店铺Id获取店铺营业状态 + * + * @param storeId + * @return + */ + Pair getStoreBizState(Integer storeId); + // Page getMobileStoreList(Integer page, Integer rows); } 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 cc73839d..4e91b649 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 @@ -337,7 +337,7 @@ public class ShopMchEntryServiceImpl extends BaseServiceImpl mobileAndLicenseNumber = esignPlatformInfoService.getEsignPlatformMobileAndLicenseNumber(); if (mobileAndLicenseNumber != null) { Map tmplArgs = new HashMap<>(1); - tmplArgs.put("name", record.getBiz_license_company()); // 商家公司名称 + tmplArgs.put("name", record.getStore_name()); // 商家店铺名 shopMessageTemplateService.aliyunSmsSend(mobileAndLicenseNumber.getFirst(), "SMS_486545331", tmplArgs); } @@ -462,7 +462,7 @@ public class ShopMchEntryServiceImpl extends BaseServiceImpl mobileAndLicenseNumber = esignPlatformInfoService.getEsignPlatformMobileAndLicenseNumber(); if (mobileAndLicenseNumber != null) { - String mchName = StrUtil.isBlank(record.getBiz_license_company()) ? "重新修正" : record.getBiz_license_company(); + String mchName = StrUtil.isBlank(record.getStore_name()) ? "重新修正资料" : record.getStore_name(); Map tmplArgs = new HashMap<>(1); tmplArgs.put("name", mchName); // 商家公司名称 // 尊敬的管理员,商家 ${name},提交了入驻我们平台的申请,请及时对相关资质材料予以审核,以便推进后续流程。 @@ -928,8 +928,6 @@ public class ShopMchEntryServiceImpl extends BaseServiceImpl updateWrapper = new UpdateWrapper<>(); - updateWrapper.eq("id", mchId).eq("status", CommonConstant.Enable) - .ne("approval_status", CommonConstant.MCH_APPR_STA_PASS); + updateWrapper.eq("id", mchId).eq("status", CommonConstant.Enable); + //.ne("approval_status", CommonConstant.MCH_APPR_STA_PASS); updateWrapper.set("approval_status", CommonConstant.MCH_APPR_STA_PASS); updateWrapper.set("approval_remark", "恭喜您,入驻流程已全部完成!"); boolean updateResult = update(updateWrapper); // 更新商户入驻信息 @@ -1887,6 +1891,7 @@ public class ShopMchEntryServiceImpl extends BaseServiceImpl 0 ? areaNames[areaNames.length - 1] : storeArea.replace("/", ""); - sfExpressApiService.createSfExpressShop(storeId, shopMchEntry.getStore_name(), + + sfExpressApiService.createSfExpressShop(mchId, storeId, shopMchEntry.getStore_name(), cityName, shopMchEntry.getStore_address(), shopMchEntry.getContact_name(), contact_mobile, shopMchEntry.getStore_longitude(), shopMchEntry.getStore_latitude()); } @@ -4201,38 +4204,95 @@ public class ShopStoreBaseServiceImpl extends BaseServiceImpl getStoreBizState(Integer storeId) { + // 参数校验 + if (CheckUtil.isEmpty(storeId)) { + log.warn("店铺ID为空,无法确定营业状态"); + return Pair.of(CommonConstant.Disable2, "店铺营业状态有误"); + } + + try { + StoreBizTimeInfoDTO storeBizTimeInfo = baseMapper.getStoreBizTimeInfo(storeId); + if (storeBizTimeInfo == null) { + log.warn("未找到店铺营业时间信息,storeId: {}", storeId); + return Pair.of(CommonConstant.Disable2, "店铺营业状态有误"); + } + + Integer storeBizState = storeBizTimeInfo.getStore_biz_state(); + String openingHours = storeBizTimeInfo.getStore_opening_hours(); + String closingHours = storeBizTimeInfo.getStore_close_hours(); + + // 检查店铺是否营业中且营业时间已设置 + if (CommonConstant.Enable.equals(storeBizState) + && StrUtil.isNotBlank(openingHours) + && StrUtil.isNotBlank(closingHours)) { + // 检查当前时间是否在营业时间内 + if (!DateTimeUtils.isCurrentTimeInRange(openingHours, closingHours)) { + // 不在营业时间内,返回已打烊状态 + log.debug("店铺当前不在营业时间内,storeId: {}, openingHours: {}, closingHours: {}", + storeId, openingHours, closingHours); + return Pair.of(CommonConstant.Disable2, String.format("%s营业时间段%s-%s", storeBizTimeInfo.getStore_name(), + openingHours, closingHours)); + } + + return Pair.of(CommonConstant.Enable, ""); + } + + // 返回原始营业状态(处理null情况) + Integer resultState = storeBizState != null ? storeBizState : CommonConstant.Disable2; + log.debug("返回店铺营业状态,storeId: {}, state: {}", storeId, resultState); + if (resultState == CommonConstant.Disable2) { + return Pair.of(resultState, String.format("%s打烊中", storeBizTimeInfo.getStore_name())); + } + return Pair.of(resultState, ""); + + } catch (Exception e) { + // 处理异常,避免影响主流程 + log.error("检查店铺营业状态发生异常,storeId: {}", storeId, e); + return Pair.of(CommonConstant.Disable2, "无法获取店铺营业状态"); + } + } + + /** * 更新店铺分账比例 * 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 5bc42de8..a0061a14 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 @@ -58,6 +58,7 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Lazy; +import org.springframework.data.util.Pair; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; @@ -1049,6 +1050,14 @@ public class ShopUserCartServiceImpl extends BaseServiceImpl storeBizState = shopStoreBaseService.getStoreBizState(storeId); + if (storeBizState != null && CommonConstant.Disable2.equals(storeBizState.getFirst())) { + throw new ApiException(I18nUtil._(storeBizState.getSecond() + ",无法加购商品。")); + } + Integer cart_type = Convert.toInt(data.get("cart_type")); // 判断是新增还是更新 @@ -1117,7 +1126,7 @@ public class ShopUserCartServiceImpl extends BaseServiceImpl + + + + + @@ -752,6 +757,11 @@ AND oi.order_time #{end_time} + + + + AND oi.booking_state = #{bookingState} + @@ -788,6 +798,10 @@ 2013, 2014, 2020, 2030, 2040))>1,2,1) AS is_new_buyer, oi.payment_time, + oi.booking_state, + oi.booking_begin_time, + oi.booking_end_time, + oi.booking_at, od.order_shipping_fee, IFNULL(od.order_shipping_fee_inner, 0) as order_shipping_fee_inner, IFNULL(od.lkl_fee, 0) as lkl_fee, @@ -843,7 +857,6 @@ osf.feed - SELECT shop_order_item.store_id, shop_order_item.product_id, shop_order_item.item_id, - + shop_order_item.item_barcode, shop_order_item.item_name, shop_order_item.item_unit_price, shop_order_item.order_item_image, @@ -86,6 +87,7 @@ ORDER BY item_total DESC +