Compare commits
38 Commits
36982e053e
...
fd2fd5c899
| Author | SHA1 | Date | |
|---|---|---|---|
| fd2fd5c899 | |||
| 85294f332a | |||
| 81fe3a88b8 | |||
| eb5ddd03df | |||
| ddd20b825e | |||
| f7a6cecd31 | |||
| 88e9a52071 | |||
| d3790fae0d | |||
| 2746f11442 | |||
| 7932c2cdf7 | |||
| 3b7a923109 | |||
| 98f5a160af | |||
| ee3437005b | |||
| 3d31e4cd74 | |||
| 2af8bc966a | |||
| abfefb6f57 | |||
| 6acf94acb5 | |||
| 60c4df7625 | |||
| fd88f45625 | |||
| eb268d35b3 | |||
| c91fc181c9 | |||
| 002baf3ffd | |||
| a20ca370b9 | |||
| 3aef824fbe | |||
| a0b92c219e | |||
| a7f2a7ac14 | |||
| 621f557e34 | |||
| c64c404495 | |||
| 6315b69246 | |||
| c3997d074f | |||
| 5ff094de7a | |||
| 6a335ef1aa | |||
| 0248a38268 | |||
| 7810340cde | |||
| 975f438137 | |||
| 32ef77830d | |||
| 8815fb9d94 | |||
| a6877b3684 |
@ -125,4 +125,6 @@ public class CommonConstant {
|
||||
public static final Integer Order_Booking_State_LJ = 1;
|
||||
public static final Integer Order_Booking_State_YY = 2;
|
||||
|
||||
// 预约下单从当前时间延迟的最小分钟数(单位分钟),不能低于35分钟
|
||||
public final static Integer MIN_DELAY_MINUTES_FOR_BOOKING_ORDER = 50;
|
||||
}
|
||||
|
||||
@ -326,5 +326,16 @@ public interface ShopService {
|
||||
BigDecimal getOrderShippingFee(@RequestParam(name = "order_id") String order_id);
|
||||
|
||||
|
||||
/**
|
||||
* 获取店铺的内部运费 shopping_fee_inner (远程调用用途)
|
||||
*
|
||||
* @param store_id
|
||||
* @return
|
||||
*/
|
||||
@ApiOperation(value = "获取店铺的内部运费 shopping_fee_inner", notes = "获取店铺的内部运费 shopping_fee_inner (远程调用用途)")
|
||||
@RequestMapping(value = "/admin/shop/shop-store-info/shopping-fee-inner", method = RequestMethod.POST)
|
||||
Integer storeShoppingFeeInner(@RequestParam(name = "store_id") Integer store_id);
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
@ -155,6 +155,9 @@ public class LklOrderDraw {
|
||||
@ApiModelProperty(value = "异步通知地址", example = "https://api.example.com/notify")
|
||||
private String notify_url;
|
||||
|
||||
@ApiModelProperty(value = "接口请求报文")
|
||||
private String lkl_req;
|
||||
|
||||
/**
|
||||
* 异步通知返回的JSON数据
|
||||
*/
|
||||
|
||||
@ -94,6 +94,9 @@ public class LklOrderSeparate {
|
||||
@ApiModelProperty(value = "处理状态:ACCEPTED-已受理, PROCESSING-处理中, FAIL-失败, SUCCESS-成功")
|
||||
private String final_status;
|
||||
|
||||
@ApiModelProperty(value = "接口请求报文")
|
||||
private String lkl_req;
|
||||
|
||||
@ApiModelProperty(value = "异步通知数据")
|
||||
private String notify_resp;
|
||||
|
||||
|
||||
@ -3,11 +3,13 @@ package com.suisung.mall.common.modules.store;
|
||||
import com.baomidou.mybatisplus.annotation.IdType;
|
||||
import com.baomidou.mybatisplus.annotation.TableId;
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
import com.fasterxml.jackson.annotation.JsonFormat;
|
||||
import io.swagger.annotations.ApiModel;
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.experimental.Accessors;
|
||||
import org.springframework.format.annotation.DateTimeFormat;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.math.BigDecimal;
|
||||
@ -121,5 +123,18 @@ public class ShopStoreInfo implements Serializable {
|
||||
@ApiModelProperty(value = "线下买单折扣:10代表原价")
|
||||
private BigDecimal store_discount;
|
||||
|
||||
@ApiModelProperty(value = "店铺内部运费,单位(分)0-使用平台的内部运费;>0 使用店铺的内部运费")
|
||||
private Integer shopping_fee_inner;
|
||||
|
||||
@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
|
||||
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
|
||||
@ApiModelProperty(value = "新增时间")
|
||||
private Date created_at;
|
||||
|
||||
@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
|
||||
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
|
||||
@ApiModelProperty(value = "最后更新时间")
|
||||
private Date updated_at;
|
||||
|
||||
|
||||
}
|
||||
|
||||
@ -33,6 +33,11 @@ public class BookingArgDTO {
|
||||
@ApiModelProperty(value = "日期")
|
||||
private String date;
|
||||
|
||||
/**
|
||||
* 工作时间依据(如"09:00-21:00")
|
||||
*/
|
||||
private String working_hours;
|
||||
|
||||
/**
|
||||
* 时间项列表
|
||||
*/
|
||||
|
||||
@ -10,8 +10,7 @@ import java.time.format.DateTimeFormatter;
|
||||
import java.time.format.DateTimeFormatterBuilder;
|
||||
import java.time.format.DateTimeParseException;
|
||||
import java.time.temporal.ChronoField;
|
||||
import java.util.Calendar;
|
||||
import java.util.Date;
|
||||
import java.util.*;
|
||||
|
||||
@Slf4j
|
||||
public class DateTimeUtils {
|
||||
@ -363,6 +362,76 @@ public class DateTimeUtils {
|
||||
return count;
|
||||
}
|
||||
|
||||
/**
|
||||
* 计算多个时间段之间的交集(不跨天)
|
||||
* <p>
|
||||
* 算法逻辑:
|
||||
* 1. 遍历所有时间段,找到最晚的开始时间和最早的结束时间
|
||||
* 2. 如果最晚开始时间小于等于最早结束时间,则存在交集
|
||||
* 3. 如果最晚开始时间大于最早结束时间,则不存在交集
|
||||
*
|
||||
* @param timeList 时间段列表,每个时间段是一个Map,包含开始时间startTimeStr和结束时间endTimeStr
|
||||
* startTimeStr 开始时间字符串,支持格式如 HH:mm, HH:mm:ss, HH:mm:ss.SSS 等
|
||||
* endTimeStr 结束时间字符串,支持格式如 HH:mm, HH:mm:ss, HH:mm:ss.SSS 等
|
||||
* @return 返回一个Map,包含交集的时间段(startTimeStr和endTimeStr),如果无交集则返回空Map
|
||||
*/
|
||||
public static Map<String, String> findTimeInterSection(List<Map<String, String>> timeList) {
|
||||
// 参数校验
|
||||
if (timeList == null || timeList.isEmpty()) {
|
||||
log.warn("时间段列表为空或null,无法计算交集");
|
||||
return new HashMap<>();
|
||||
}
|
||||
|
||||
try {
|
||||
LocalTime latestStartTime = null;
|
||||
LocalTime earliestEndTime = null;
|
||||
|
||||
// 遍历所有时间段
|
||||
for (Map<String, String> timeMap : timeList) {
|
||||
if (timeMap == null || !timeMap.containsKey("startTimeStr") || !timeMap.containsKey("endTimeStr")) {
|
||||
log.warn("时间段数据不完整或格式不正确: {}", timeMap);
|
||||
continue;
|
||||
}
|
||||
|
||||
String startTimeStr = timeMap.get("startTimeStr");
|
||||
String endTimeStr = timeMap.get("endTimeStr");
|
||||
|
||||
if (startTimeStr == null || endTimeStr == null) {
|
||||
log.warn("时间段的开始或结束时间为空: startTime={}, endTime={}", startTimeStr, endTimeStr);
|
||||
continue;
|
||||
}
|
||||
|
||||
LocalTime startTime = parseTime(startTimeStr);
|
||||
LocalTime endTime = parseTime(endTimeStr);
|
||||
|
||||
// 更新最晚开始时间和最早结束时间
|
||||
if (latestStartTime == null || startTime.isAfter(latestStartTime)) {
|
||||
latestStartTime = startTime;
|
||||
}
|
||||
|
||||
if (earliestEndTime == null || endTime.isBefore(earliestEndTime)) {
|
||||
earliestEndTime = endTime;
|
||||
}
|
||||
}
|
||||
|
||||
// 检查是否存在交集
|
||||
if (latestStartTime != null && earliestEndTime != null && !latestStartTime.isAfter(earliestEndTime)) {
|
||||
Map<String, String> result = new HashMap<>();
|
||||
result.put("startTimeStr", latestStartTime.toString());
|
||||
result.put("endTimeStr", earliestEndTime.toString());
|
||||
return result;
|
||||
} else {
|
||||
// 无交集情况
|
||||
log.debug("给定的时间段列表无交集");
|
||||
return new HashMap<>();
|
||||
}
|
||||
} catch (Exception e) {
|
||||
log.error("计算时间段交集时发生异常", e);
|
||||
return new HashMap<>();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 判断指定时间是否在两个时间点之间(包含边界)
|
||||
*
|
||||
@ -537,14 +606,52 @@ public class DateTimeUtils {
|
||||
// System.out.println(formatLocalDate(LocalDate.now(), "yyyy-MM-dd"));
|
||||
|
||||
// 判断当前时间是否在工作时间(9:00-18:00)内
|
||||
boolean isWorkTime = isCurrentTimeInRange("09:00", "22:36");
|
||||
// boolean isWorkTime = isCurrentTimeInRange("09:00", "22:36");
|
||||
|
||||
// 判断特定时间是否在夜间时间(22:00-06:00)内
|
||||
// LocalDateTime testTime = LocalDateTime.of(2025, 1, 1, 23, 30);
|
||||
Date testTime = Date.from(LocalDateTime.of(2025, 10, 23, 21, 30).atZone(ZoneId.systemDefault()).toInstant());
|
||||
boolean isNight = isTimeInRange("08:30", "22:20", testTime);
|
||||
// Date testTime = Date.from(LocalDateTime.of(2025, 10, 23, 21, 30).atZone(ZoneId.systemDefault()).toInstant());
|
||||
// boolean isNight = isTimeInRange("08:30", "22:20", testTime);
|
||||
|
||||
// System.out.println("当前时间是否在工作时间内:" + isWorkTime);
|
||||
// System.out.println("多个时间段的交集结果:" + isNight);
|
||||
|
||||
System.out.println("=== 测试 findTimeIntersection ===");
|
||||
|
||||
// 测试正常交集情况
|
||||
List<Map<String, String>> timeList1 = new ArrayList<>();
|
||||
Map<String, String> range1 = new HashMap<>();
|
||||
range1.put("startTimeStr", "06:00");
|
||||
range1.put("endTimeStr", "17:00");
|
||||
timeList1.add(range1);
|
||||
|
||||
Map<String, String> range2 = new HashMap<>();
|
||||
range2.put("startTimeStr", "06:00");
|
||||
range2.put("endTimeStr", "17:00");
|
||||
timeList1.add(range2);
|
||||
|
||||
Map<String, String> intersection1 = findTimeInterSection(timeList1);
|
||||
System.out.println("交集结果1: " + intersection1); // 应该是 10:00 - 17:00
|
||||
|
||||
// 测试无交集情况
|
||||
List<Map<String, String>> timeList2 = new ArrayList<>();
|
||||
Map<String, String> range3 = new HashMap<>();
|
||||
range3.put("startTimeStr", "09:00");
|
||||
range3.put("endTimeStr", "12:00");
|
||||
timeList2.add(range3);
|
||||
|
||||
Map<String, String> range4 = new HashMap<>();
|
||||
range4.put("startTimeStr", "13:00");
|
||||
range4.put("endTimeStr", "17:00");
|
||||
timeList2.add(range4);
|
||||
|
||||
Map<String, String> intersection2 = findTimeInterSection(timeList2);
|
||||
System.out.println("交集结果2: " + intersection2); // 应该是空Map
|
||||
|
||||
// 测试空列表
|
||||
Map<String, String> intersection3 = findTimeInterSection(null);
|
||||
System.out.println("交集结果3 (null输入): " + intersection3); // 应该是空Map
|
||||
|
||||
|
||||
System.out.println("当前时间是否在工作时间内:" + isWorkTime);
|
||||
System.out.println("特定时间是否在夜间时间段内:" + isNight);
|
||||
}
|
||||
}
|
||||
@ -48,10 +48,11 @@ public interface AccountBaseConfigService extends IBaseService<AccountBaseConfig
|
||||
String getSystemConfig(String configKey);
|
||||
|
||||
/**
|
||||
* 获取平台内部最低配送费,单位(分)
|
||||
* 获取店铺或平台内部最低配送费,单位(分)
|
||||
*
|
||||
* @return
|
||||
* @param storeId 店铺Id
|
||||
* @return 配送费,单位分
|
||||
*/
|
||||
Integer getInnerMinDeliveryFee();
|
||||
Integer getInnerMinDeliveryFee(Integer storeId);
|
||||
|
||||
}
|
||||
|
||||
@ -10,6 +10,7 @@ import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||
import com.suisung.mall.common.constant.CommonConstant;
|
||||
import com.suisung.mall.common.constant.RedisConstant;
|
||||
import com.suisung.mall.common.feignService.AccountService;
|
||||
import com.suisung.mall.common.feignService.ShopService;
|
||||
import com.suisung.mall.common.modules.account.AccountBaseConfig;
|
||||
import com.suisung.mall.common.modules.account.AccountUserInfo;
|
||||
import com.suisung.mall.common.utils.CheckUtil;
|
||||
@ -20,6 +21,7 @@ import com.suisung.mall.pay.service.AccountBaseConfigService;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.CommandLineRunner;
|
||||
import org.springframework.context.annotation.Lazy;
|
||||
import org.springframework.scheduling.annotation.Async;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
@ -47,6 +49,11 @@ public class AccountBaseConfigServiceImpl extends BaseServiceImpl<AccountBaseCon
|
||||
public static Long version = 0L;
|
||||
@Autowired
|
||||
private AccountService accountService;
|
||||
|
||||
@Lazy
|
||||
@Autowired
|
||||
private ShopService shopService;
|
||||
|
||||
@Autowired
|
||||
private RedisService redisService;
|
||||
|
||||
@ -254,16 +261,41 @@ public class AccountBaseConfigServiceImpl extends BaseServiceImpl<AccountBaseCon
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取平台内部最低配送费,单位(分)
|
||||
* 获取店铺或平台内部最低配送费,单位(分)
|
||||
*
|
||||
* @return
|
||||
* @param storeId 店铺Id
|
||||
* @return 配送费,单位分
|
||||
*/
|
||||
@Override
|
||||
public Integer getInnerMinDeliveryFee() {
|
||||
String v = getSystemConfig(CommonConstant.Inner_Min_DeliveryFee_Key);
|
||||
return NumberUtil.isNumber(v) ? Convert.toInt(v) : 0;
|
||||
public Integer getInnerMinDeliveryFee(Integer storeId) {
|
||||
// 如果storeId无效,直接使用平台默认配置
|
||||
if (storeId == null || storeId <= 0) {
|
||||
return getDefaultMinDeliveryFee();
|
||||
}
|
||||
|
||||
// 获取店铺内部运费
|
||||
Integer storeFee = shopService.storeShoppingFeeInner(storeId);
|
||||
|
||||
// 如果店铺未设置有效运费,则使用平台默认配置
|
||||
if (storeFee == null || storeFee <= 0) {
|
||||
return getDefaultMinDeliveryFee();
|
||||
}
|
||||
|
||||
return storeFee;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取平台默认最低配送费
|
||||
*
|
||||
* @return 默认配送费,单位分
|
||||
*/
|
||||
private Integer getDefaultMinDeliveryFee() {
|
||||
String configValue = getSystemConfig(CommonConstant.Inner_Min_DeliveryFee_Key);
|
||||
int fee = NumberUtil.isNumber(configValue) ? Convert.toInt(configValue) : 0;
|
||||
return fee > 0 ? fee : 0;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 交易模式 2直接交易:商家直接收款; 1担保交易:平台收款,平台和商家结算。
|
||||
*/
|
||||
|
||||
@ -251,8 +251,8 @@ public class LakalaPayServiceImpl implements LakalaPayService {
|
||||
}
|
||||
|
||||
// 平台最低配送费,单位(分)
|
||||
Integer innerMinDeliverFee = accountBaseConfigService.getInnerMinDeliveryFee();
|
||||
reqData.set("shopping_fee_inner", innerMinDeliverFee); // 平台内部最低配送费,单位(分)
|
||||
Integer innerMinDeliverFee = accountBaseConfigService.getInnerMinDeliveryFee(Convert.toInt(storeId));
|
||||
reqData.set("shopping_fee_inner", innerMinDeliverFee); // 重要:平台内部最低配送费,单位(分)
|
||||
|
||||
log.info("[拉卡拉预下单] 支付成功,准备保存订单记录, orderId={}", orderId);
|
||||
// 新增一个拉卡拉订单记录 shop_order_lkl 表
|
||||
@ -280,7 +280,7 @@ public class LakalaPayServiceImpl implements LakalaPayService {
|
||||
|
||||
|
||||
/**
|
||||
* 拉卡拉合单预下单(主要有运费的订单使用合单)
|
||||
* 【暂时废弃】拉卡拉合单预下单(主要有运费的订单使用合单)
|
||||
* 参考:https://o.lakala.com/#/home/document/detail?id=208
|
||||
*
|
||||
* @param merchantNo 商户号(商城商家)
|
||||
@ -299,6 +299,7 @@ public class LakalaPayServiceImpl implements LakalaPayService {
|
||||
* @param remark 备注
|
||||
* @return 拉卡拉合单预下单响应结果
|
||||
**/
|
||||
@Deprecated
|
||||
@Override
|
||||
public JSONObject lklTransMergePreOrder(String merchantNo, String termNo, String agentMerchantNo, String agentTermNo, String xcxAppId, String openId, String storeId, String orderId, String subject, String totalAmount, String agentAmount, String notifyURL, String requestIP, String remark) {
|
||||
log.info("[拉卡拉合单预下单] 开始处理请求, merchantNo={}, termNo={}, agentMerchantNo={}, agentTermNo={}, orderId={}",
|
||||
@ -558,7 +559,7 @@ public class LakalaPayServiceImpl implements LakalaPayService {
|
||||
log.warn("[拉卡拉退款] 退款金额不合法: refundAmount={}", refundAmount);
|
||||
return Pair.of(false, I18nUtil._("退款金额不合法!"));
|
||||
}
|
||||
|
||||
|
||||
if (StrUtil.hasBlank(lklMerchantNo, lklTermNo)) {
|
||||
// 4. 获取店铺的拉卡拉商户号和终端号
|
||||
ShopStoreBase shopStoreBase = shopService.getLklMerchantNoAndTermNo(storeId);
|
||||
|
||||
@ -671,15 +671,14 @@ public class PayUserPayServiceImpl extends BaseServiceImpl<PayUserPayMapper, Pay
|
||||
String requestIP = IpKit.getRealIp(request);
|
||||
String notifyUrl = domain + "/lkl_wxPay_notify_url";
|
||||
String storeIdStr = Convert.toStr(storeId);// 店铺Id
|
||||
|
||||
|
||||
BigDecimal shippingFee = shopService.getOrderShippingFee(out_trade_no);
|
||||
if (shippingFee == null || shippingFee.intValue() <= 0) {
|
||||
shippingFee = BigDecimal.ZERO;
|
||||
}
|
||||
|
||||
// 平台最低配送费,单位(分)
|
||||
Integer innerMinDeliverFee = accountBaseConfigService.getInnerMinDeliveryFee();
|
||||
|
||||
Integer innerMinDeliverFee = accountBaseConfigService.getInnerMinDeliveryFee(storeId);
|
||||
logger.debug("预支付时,查到的订单{},商家配送费:{}元,平台最低配送费要求:{}分", out_trade_no, shippingFee, innerMinDeliverFee);
|
||||
|
||||
// 平台最低配送费,单位(分)
|
||||
@ -687,7 +686,7 @@ public class PayUserPayServiceImpl extends BaseServiceImpl<PayUserPayMapper, Pay
|
||||
// 内部运费统一由分账接收方收取了 2025-10-11
|
||||
// 拉卡拉预支付返回参数
|
||||
|
||||
// TODO 判断订单有没有运费,有运费请求合单交易,没有运费,请求聚合主扫交易
|
||||
// 聚合主扫交易
|
||||
cn.hutool.json.JSONObject lakalaRespJSON = lakalaPayService.lklTransPreOrder(shopStoreBase.getLkl_merchant_no(), shopStoreBase.getLkl_term_no(),
|
||||
appId, openId, storeIdStr, out_trade_no, subject, total_amt,
|
||||
notifyUrl,
|
||||
|
||||
@ -10,6 +10,7 @@ import com.suisung.mall.common.exception.ApiUserException;
|
||||
import com.suisung.mall.common.modules.activity.ShopActivityGroupbookingHistory;
|
||||
import com.suisung.mall.common.modules.activity.ShopActivityGroupbuyStoreHistory;
|
||||
import com.suisung.mall.common.service.impl.BaseControllerImpl;
|
||||
import com.suisung.mall.common.utils.CheckUtil;
|
||||
import com.suisung.mall.common.utils.I18nUtil;
|
||||
import com.suisung.mall.shop.activity.service.ShopActivityCutpriceHistoryService;
|
||||
import com.suisung.mall.shop.activity.service.ShopActivityCutpriceService;
|
||||
@ -64,6 +65,7 @@ public class UserActivityController extends BaseControllerImpl {
|
||||
@Autowired
|
||||
private ShopStoreActivityBaseService shopStoreActivityBaseService;
|
||||
|
||||
@ApiOperation(value = "列出我的团购", notes = "列出我的团购")
|
||||
@RequestMapping(value = "/listsUserGroupbooking", method = RequestMethod.GET)
|
||||
public CommonResult listsUserGroupbooking(@RequestParam(name = "page", defaultValue = "1") Integer page,
|
||||
@RequestParam(name = "rows", defaultValue = "10") Integer rows,
|
||||
@ -96,6 +98,7 @@ public class UserActivityController extends BaseControllerImpl {
|
||||
return CommonResult.success(shopActivityGroupbookingService.listsUserGroupbooking(queryWrapper, page, rows));
|
||||
}
|
||||
|
||||
@ApiOperation(value = "我的团购详情", notes = "我的团购详情")
|
||||
@RequestMapping(value = "/getUserGroupbooking", method = RequestMethod.GET)
|
||||
public CommonResult getUserGroupbooking(@RequestParam(name = "gb_id") Integer gb_id) {
|
||||
return CommonResult.success(shopActivityGroupbookingService.getUserGroupbooking(gb_id));
|
||||
@ -111,10 +114,28 @@ public class UserActivityController extends BaseControllerImpl {
|
||||
|
||||
@ApiOperation(value = "砍价活动详情", notes = "砍价活动详情")
|
||||
@RequestMapping(value = "/getCutPriceActivity", method = RequestMethod.GET)
|
||||
public CommonResult getCutPriceActivity() {
|
||||
public CommonResult getCutPriceActivityDetail() {
|
||||
return CommonResult.success(shopActivityCutpriceService.getCutPriceActivity());
|
||||
}
|
||||
|
||||
@ApiOperation(value = "立即砍价", notes = "自己砍价、要求朋友过来也能砍价")
|
||||
@RequestMapping(value = "/doCutPrice", method = RequestMethod.GET)
|
||||
public CommonResult doCutPrice(@RequestParam(name = "ac_id", defaultValue = "0") Integer ac_id) {
|
||||
UserDto user = getCurrentUser();
|
||||
if (user == null || CheckUtil.isEmpty(user.getId())) {
|
||||
throw new ApiException(ResultCode.NEED_LOGIN);
|
||||
}
|
||||
Integer user_id = user.getId();
|
||||
return shopActivityCutpriceService.doCutPrice(ac_id, user_id);
|
||||
}
|
||||
|
||||
@ApiOperation(value = "砍价历史记录", notes = "砍价历史记录(砍价排行榜)")
|
||||
@RequestMapping(value = "/listsCutPriceHistory", method = RequestMethod.GET)
|
||||
public CommonResult listsCutPriceHistory() {
|
||||
return CommonResult.success(shopStoreActivityBaseService.listsCutPriceHistory());
|
||||
}
|
||||
|
||||
|
||||
@ApiOperation(value = "列出我的团购记录", notes = "列出我的团购记录")
|
||||
@RequestMapping(value = "/listsUserGroupbuyStore", method = RequestMethod.GET)
|
||||
public CommonResult listsUserGroupbuyStore(@RequestParam(name = "page", defaultValue = "1") Integer page,
|
||||
@ -216,22 +237,6 @@ public class UserActivityController extends BaseControllerImpl {
|
||||
return CommonResult.success(shopStoreActivityBaseService.listsLotteryHistory());
|
||||
}
|
||||
|
||||
@ApiOperation(value = "参加活动,并报名", notes = "参加活动,并报名")
|
||||
@RequestMapping(value = "/doCutPrice", method = RequestMethod.GET)
|
||||
public CommonResult doCutPrice(@RequestParam(name = "ac_id", defaultValue = "0") Integer ac_id) {
|
||||
UserDto user = getCurrentUser();
|
||||
if (user == null) {
|
||||
throw new ApiException(ResultCode.NEED_LOGIN);
|
||||
}
|
||||
Integer user_id = user.getId();
|
||||
return shopActivityCutpriceService.doCutPrice(ac_id, user_id);
|
||||
}
|
||||
|
||||
@ApiOperation(value = "砍价历史记录", notes = "砍价历史记录")
|
||||
@RequestMapping(value = "/listsCutPriceHistory", method = RequestMethod.GET)
|
||||
public CommonResult listsCutPriceHistory() {
|
||||
return CommonResult.success(shopStoreActivityBaseService.listsCutPriceHistory());
|
||||
}
|
||||
|
||||
@ApiOperation(value = "根据条件列出形成的团", notes = "根据条件列出形成的团")
|
||||
@RequestMapping(value = "/listsGroupbooking", method = RequestMethod.GET)
|
||||
@ -246,6 +251,5 @@ public class UserActivityController extends BaseControllerImpl {
|
||||
public CommonResult getGiftbag(@RequestParam(name = "activity_id") Integer activity_id) {
|
||||
return CommonResult.success(shopStoreActivityBaseService.getGiftbag(activity_id));
|
||||
}
|
||||
//
|
||||
}
|
||||
|
||||
|
||||
@ -4,6 +4,7 @@ import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||
import com.suisung.mall.common.api.CommonResult;
|
||||
import com.suisung.mall.common.modules.activity.ShopActivityCutprice;
|
||||
import com.suisung.mall.core.web.service.IBaseService;
|
||||
import org.springframework.data.util.Pair;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
@ -28,4 +29,13 @@ public interface ShopActivityCutpriceService extends IBaseService<ShopActivityCu
|
||||
|
||||
CommonResult doCutPrice(Integer ac_id, Integer user_id);
|
||||
|
||||
/**
|
||||
* 砍价活动是否可以下单
|
||||
*
|
||||
* @param ac_id 活动 自增Id
|
||||
* @param order_user_id 下单用户
|
||||
* @return
|
||||
*/
|
||||
Pair<Boolean, String> canDoOrderCutPriceActivity(Integer ac_id, Integer order_user_id);
|
||||
|
||||
}
|
||||
|
||||
@ -13,6 +13,7 @@ import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import com.suisung.mall.common.api.CommonResult;
|
||||
import com.suisung.mall.common.api.StateCode;
|
||||
import com.suisung.mall.common.constant.CommonConstant;
|
||||
import com.suisung.mall.common.domain.UserDto;
|
||||
import com.suisung.mall.common.exception.ApiException;
|
||||
import com.suisung.mall.common.exception.ApiUserException;
|
||||
@ -33,8 +34,10 @@ import com.suisung.mall.shop.activity.service.ShopActivityGroupbookingHistorySer
|
||||
import com.suisung.mall.shop.activity.service.ShopActivityGroupbookingService;
|
||||
import com.suisung.mall.shop.base.service.AccountBaseConfigService;
|
||||
import com.suisung.mall.shop.store.service.ShopStoreActivityBaseService;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
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;
|
||||
|
||||
@ -54,6 +57,7 @@ import static com.suisung.mall.common.utils.ContextUtil.getCurrentUser;
|
||||
* @author Xinze
|
||||
* @since 2021-07-12
|
||||
*/
|
||||
@Slf4j
|
||||
@Service
|
||||
public class ShopActivityCutpriceServiceImpl extends BaseServiceImpl<ShopActivityCutpriceMapper, ShopActivityCutprice> implements ShopActivityCutpriceService {
|
||||
|
||||
@ -319,9 +323,30 @@ public class ShopActivityCutpriceServiceImpl extends BaseServiceImpl<ShopActivit
|
||||
// activity_row.put("activity_endtime", Convert.toDate(time));
|
||||
// }
|
||||
|
||||
// 界面做一个简单的底价验证:
|
||||
boolean canBuyNow = cutprice_row != null
|
||||
&& CheckUtil.isNotEmpty(cutprice_row.getAc_sale_price())
|
||||
&& CheckUtil.isNotEmpty(cutprice_row.getAc_mix_limit_price())
|
||||
&& NumberUtil.isLessOrEqual(cutprice_row.getAc_sale_price(), cutprice_row.getAc_mix_limit_price());
|
||||
|
||||
BigDecimal subtractPrice = NumberUtil.sub(cutprice_row.getAc_sale_price(), cutprice_row.getAc_mix_limit_price());
|
||||
|
||||
// 能否立即出手 1-可以;2-不可以
|
||||
activity_row.put("can_buy_now", canBuyNow ? CommonConstant.Enable : CommonConstant.Disable2);
|
||||
activity_row.put("cannot_buy_now_reason",
|
||||
canBuyNow ? "恭喜您,商品可以立即出手了。" :
|
||||
String.format("还剩%.2f元到达商品底价,请继续加油!", subtractPrice));
|
||||
|
||||
return activity_row;
|
||||
}
|
||||
|
||||
/**
|
||||
* 砍价
|
||||
*
|
||||
* @param ac_id 活动 Id
|
||||
* @param user_id 砍价用户
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
@Transactional
|
||||
public CommonResult doCutPrice(Integer ac_id, Integer user_id) {
|
||||
@ -344,7 +369,7 @@ public class ShopActivityCutpriceServiceImpl extends BaseServiceImpl<ShopActivit
|
||||
Integer activity_id = cutprice_row.getActivity_id();
|
||||
ShopStoreActivityBase storeActivityBase = shopStoreActivityBaseService.get(activity_id);
|
||||
Map activity_row = Convert.toMap(String.class, Object.class, storeActivityBase);
|
||||
if (!shopStoreActivityBaseService.verifyActivity(activity_row)) {
|
||||
if (!shopStoreActivityBaseService.isActivityTimeValid(activity_row)) {
|
||||
throw new ApiException(I18nUtil._("该活动不存在!"));
|
||||
}
|
||||
|
||||
@ -390,4 +415,82 @@ public class ShopActivityCutpriceServiceImpl extends BaseServiceImpl<ShopActivit
|
||||
return CommonResult.success(ach_data);
|
||||
}
|
||||
|
||||
/**
|
||||
* 砍价活动是否符合立即下单了?
|
||||
*
|
||||
* @param activity_id 活动 Id
|
||||
* @param order_user_id 下单用户
|
||||
* <p>
|
||||
* 判断逻辑:
|
||||
* 1、活动是否过期
|
||||
* 2、活动是否是下单用户的
|
||||
* 3、活动是否是砍到最低价
|
||||
* @return Pair<Boolean, String> 第一个值表示是否可以下单,第二个值是相关信息或错误信息
|
||||
*/
|
||||
@Override
|
||||
public Pair<Boolean, String> canDoOrderCutPriceActivity(Integer activity_id, Integer order_user_id) {
|
||||
try {
|
||||
// 参数校验
|
||||
if (activity_id == null || activity_id <= 0) {
|
||||
return Pair.of(false, I18nUtil._("活动ID无效。"));
|
||||
}
|
||||
|
||||
if (order_user_id == null || order_user_id <= 0) {
|
||||
return Pair.of(false, I18nUtil._("用户ID无效。"));
|
||||
}
|
||||
|
||||
// 1. 检查活动是否存在
|
||||
QueryWrapper<ShopStoreActivityBase> params = new QueryWrapper<>();
|
||||
params.eq("activity_id", activity_id);
|
||||
ShopStoreActivityBase storeActivityBase = shopStoreActivityBaseService.getOne(params);
|
||||
if (storeActivityBase == null) {
|
||||
return Pair.of(false, I18nUtil._("抱歉,系统未找到活动记录。"));
|
||||
}
|
||||
|
||||
// 2. 检查活动是否在有效期内
|
||||
if (!shopStoreActivityBaseService.isActivityTimeValid(storeActivityBase.getActivity_starttime(), storeActivityBase.getActivity_endtime())) {
|
||||
return Pair.of(false, I18nUtil._("该活动已过期,请检查。"));
|
||||
}
|
||||
|
||||
// 3. 检查用户是否有发起的砍价记录
|
||||
QueryWrapper<ShopActivityCutprice> queryWrapper = new QueryWrapper<>();
|
||||
queryWrapper.eq("activity_id", activity_id);
|
||||
queryWrapper.eq("user_id", order_user_id);
|
||||
queryWrapper.orderByDesc("ac_id");
|
||||
ShopActivityCutprice shopActivityCutprice = getOne(queryWrapper);
|
||||
if (shopActivityCutprice == null) {
|
||||
return Pair.of(false, I18nUtil._("系统未找到您发起的砍价记录。"));
|
||||
}
|
||||
|
||||
// 4. 检查是否已砍到最低价
|
||||
// 砍价底价
|
||||
BigDecimal mixSalePrice = shopActivityCutprice.getAc_mix_limit_price();
|
||||
// 当前最终被砍价后的最新价格
|
||||
BigDecimal currPrice = shopActivityCutprice.getAc_sale_price();
|
||||
|
||||
// 还剩多少到底价 = 当前价格 - 活动底价
|
||||
BigDecimal subPrice = NumberUtil.sub(currPrice, mixSalePrice);
|
||||
// 当前价格已经等于或低于底价,可以立即出手下单
|
||||
if (NumberUtil.isGreater(subPrice, BigDecimal.ZERO)) {
|
||||
return Pair.of(false, String.format(I18nUtil._("还剩%.2f元可达活动底价,请继续加油。"), subPrice));
|
||||
}
|
||||
// 5. 检查是否存在砍价历史记录
|
||||
QueryWrapper<ShopActivityCutpriceHistory> queryWrapperHistory = new QueryWrapper<>();
|
||||
queryWrapperHistory.eq("ac_id", shopActivityCutprice.getAc_id());
|
||||
queryWrapperHistory.eq("activity_id", shopActivityCutprice.getActivity_id());
|
||||
List<ShopActivityCutpriceHistory> shopActivityCutpriceHistoryList = shopActivityCutpriceHistoryService.list(queryWrapperHistory);
|
||||
if (CollUtil.isEmpty(shopActivityCutpriceHistoryList)) {
|
||||
return Pair.of(false, I18nUtil._("未找到砍价记录,请检查"));
|
||||
}
|
||||
|
||||
// 所有条件都满足,可以下单
|
||||
return Pair.of(true, "");
|
||||
} catch (Exception e) {
|
||||
// 异常处理,防止影响主流程
|
||||
log.error("检查砍价活动是否可下单时发生异常,activity_id={}, order_user_id={}", activity_id, order_user_id, e);
|
||||
return Pair.of(false, I18nUtil._("系统繁忙,请稍后再试。"));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@ -13,6 +13,7 @@ import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import com.suisung.mall.common.api.ResultCode;
|
||||
import com.suisung.mall.common.api.StateCode;
|
||||
import com.suisung.mall.common.constant.CommonConstant;
|
||||
import com.suisung.mall.common.domain.UserDto;
|
||||
import com.suisung.mall.common.exception.ApiException;
|
||||
import com.suisung.mall.common.exception.ApiUserException;
|
||||
@ -474,7 +475,7 @@ public class ShopActivityGroupbookingServiceImpl extends BaseServiceImpl<ShopAct
|
||||
ShopStoreActivityBase activityBase = shopStoreActivityBaseService.get(gbh_row.getActivity_id());
|
||||
Map activity_row = Convert.toMap(String.class, Object.class, activityBase);
|
||||
|
||||
if (shopStoreActivityBaseService.verifyActivity(activity_row)) if (gbh_row != null && gb_row != null) {
|
||||
if (shopStoreActivityBaseService.isActivityTimeValid(activity_row)) if (gbh_row != null && gb_row != null) {
|
||||
// 判断拼团是否满员在加入该成员后是否满员
|
||||
if (ifFull(gb_row, true)) {
|
||||
// 修改拼团记录
|
||||
@ -648,8 +649,10 @@ public class ShopActivityGroupbookingServiceImpl extends BaseServiceImpl<ShopAct
|
||||
for (ShopActivityGroupbookingHistory history : historyList) {
|
||||
// 已支付
|
||||
ShopOrderInfo order_info_data = shopOrderInfoService.get(history.getOrder_id());
|
||||
if (history.getGbh_flag() == 1) {
|
||||
boolean used = shopUserVoucherService.useNeedNotPin(history.getUser_id(), history.getOrder_id());
|
||||
if (history.getGbh_flag() == 1) { // 已支付
|
||||
|
||||
// 是否使用了免拼券
|
||||
boolean used = shopUserVoucherService.tryUseFreeGroupVoucher(history.getUser_id(), history.getOrder_id());
|
||||
|
||||
if (used) {
|
||||
if (order_info_data.getOrder_is_sync() == 2) {
|
||||
@ -664,30 +667,33 @@ public class ShopActivityGroupbookingServiceImpl extends BaseServiceImpl<ShopAct
|
||||
// 如果使用免拼券成功,则改变参团人员拼单状态为成功.不往下走。
|
||||
ShopActivityGroupbookingHistory groupbookingHistory = new ShopActivityGroupbookingHistory();
|
||||
groupbookingHistory.setGbh_id(history.getGbh_id());
|
||||
groupbookingHistory.setGb_enable(1);
|
||||
groupbookingHistory.setGb_enable(CommonConstant.Enable);
|
||||
if (!shopActivityGroupbookingHistoryService.edit(groupbookingHistory)) {
|
||||
throw new ApiException(I18nUtil._("修正订单为可同步状态失败!"));
|
||||
}
|
||||
|
||||
free_fight_num++;
|
||||
|
||||
// TODO 平团成功,需要发同城配送
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
// 取消订单
|
||||
|
||||
List<String> order_ids = Convert.toList(String.class, history.getOrder_id());
|
||||
|
||||
//只有一条记录
|
||||
List<ShopOrderInfo> shopOrderInfos = shopOrderInfoService.gets(order_ids);
|
||||
List<Map> rows = Convert.toList(Map.class, shopOrderInfos);
|
||||
|
||||
// 取消订单
|
||||
flag = shopOrderBaseService.cancel(order_ids, rows, false);
|
||||
//已经调用cancelActivity, 重复
|
||||
if (flag) {
|
||||
// 改变参团人员拼单状态
|
||||
ShopActivityGroupbookingHistory groupbookingHistory = new ShopActivityGroupbookingHistory();
|
||||
groupbookingHistory.setGbh_id(history.getGbh_id());
|
||||
groupbookingHistory.setGb_enable(0);
|
||||
groupbookingHistory.setGb_enable(CommonConstant.Disable);
|
||||
if (!shopActivityGroupbookingHistoryService.edit(groupbookingHistory)) {
|
||||
throw new ApiException(I18nUtil._("改变参团人员拼单状态失败!"));
|
||||
}
|
||||
@ -727,12 +733,10 @@ public class ShopActivityGroupbookingServiceImpl extends BaseServiceImpl<ShopAct
|
||||
orderReturn.setReturn_tel("");
|
||||
orderReturn.setReturn_store_user_id(buyer_store_id);
|
||||
orderReturn.setReturn_telephone("");
|
||||
|
||||
orderReturn.setSubsite_id(order_info_data.getSubsite_id());
|
||||
|
||||
|
||||
ShopOrderReturnItem orderReturnItem = new ShopOrderReturnItem();
|
||||
|
||||
orderReturnItem.setOrder_item_id(order_item_row.getOrder_item_id()); // 退货商品编号(DOT):0为退款
|
||||
orderReturnItem.setOrder_id(history.getOrder_id()); // 订单编号
|
||||
orderReturnItem.setReturn_item_num(order_item_row.getOrder_item_quantity()); // 退货商品编号(DOT):0为退款
|
||||
@ -760,7 +764,7 @@ public class ShopActivityGroupbookingServiceImpl extends BaseServiceImpl<ShopAct
|
||||
}
|
||||
}
|
||||
|
||||
//如果免拼数量等于成团数量,则此团完成
|
||||
//如果使用免拼券人数等于成团数量,则此团完成
|
||||
if (gb_quantity <= free_fight_num) {
|
||||
groupbooking.setGb_enable(1);
|
||||
shopActivityGroupbookingService.saveOrUpdate(groupbooking);
|
||||
|
||||
@ -152,7 +152,7 @@ public class ShopActivityGroupbuyStoreServiceImpl extends BaseServiceImpl<ShopAc
|
||||
ShopStoreActivityBase storeActivityBase = shopStoreActivityBaseService.findOne(baseQueryWrapper);
|
||||
Map activity_base_row = Convert.toMap(String.class, Object.class, storeActivityBase);
|
||||
|
||||
if (gbsh_row != null && activity_base_row != null && shopStoreActivityBaseService.verifyActivity(activity_base_row)) {
|
||||
if (gbsh_row != null && activity_base_row != null && shopStoreActivityBaseService.isActivityTimeValid(activity_base_row)) {
|
||||
|
||||
// 修改团员支付状态
|
||||
ShopActivityGroupbuyStoreHistory storeHistory = new ShopActivityGroupbuyStoreHistory();
|
||||
|
||||
@ -168,7 +168,7 @@ public class ShopActivityPfGroupbuyStoreHistoryServiceImpl extends BaseServiceIm
|
||||
Map activity_base_row = Convert.toMap(String.class, Object.class, storeActivityBase);
|
||||
|
||||
if (pfgbsh_row != null && activity_base_row != null
|
||||
&& shopStoreActivityBaseService.verifyActivity(activity_base_row)) {
|
||||
&& shopStoreActivityBaseService.isActivityTimeValid(activity_base_row)) {
|
||||
|
||||
// 修改团员支付状态
|
||||
ShopActivityPfGroupbuyStoreHistory storeHistory = new ShopActivityPfGroupbuyStoreHistory();
|
||||
|
||||
@ -60,9 +60,10 @@ public interface AccountBaseConfigService extends IBaseService<AccountBaseConfig
|
||||
String getSystemConfig(String configKey);
|
||||
|
||||
/**
|
||||
* 获取平台内部最低配送费,单位(分)
|
||||
* 获取店铺或平台内部最低配送费,单位(分)
|
||||
*
|
||||
* @return
|
||||
* @param storeId 店铺Id
|
||||
* @return 配送费,单位分
|
||||
*/
|
||||
Integer getInnerMinDeliveryFee();
|
||||
Integer getInnerMinDeliveryFee(Integer storeId);
|
||||
}
|
||||
|
||||
@ -22,9 +22,11 @@ import com.suisung.mall.core.web.service.impl.BaseServiceImpl;
|
||||
import com.suisung.mall.shop.base.mapper.AccountBaseConfigMapper;
|
||||
import com.suisung.mall.shop.base.service.AccountBaseConfigService;
|
||||
import com.suisung.mall.shop.config.CookieUtil;
|
||||
import com.suisung.mall.shop.store.service.ShopStoreInfoService;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.CommandLineRunner;
|
||||
import org.springframework.context.annotation.Lazy;
|
||||
import org.springframework.scheduling.annotation.Async;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
@ -51,6 +53,11 @@ public class AccountBaseConfigServiceImpl extends BaseServiceImpl<AccountBaseCon
|
||||
public static Long version = 0L;
|
||||
@Autowired
|
||||
private AccountService accountService;
|
||||
|
||||
@Lazy
|
||||
@Autowired
|
||||
private ShopStoreInfoService shopStoreInfoService;
|
||||
|
||||
@Autowired
|
||||
private RedisService redisService;
|
||||
|
||||
@ -369,14 +376,38 @@ public class AccountBaseConfigServiceImpl extends BaseServiceImpl<AccountBaseCon
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取平台内部最低配送费,单位(分)
|
||||
* 获取店铺或平台内部最低配送费,单位(分)
|
||||
*
|
||||
* @return
|
||||
* @param storeId 店铺Id
|
||||
* @return 配送费,单位分
|
||||
*/
|
||||
@Override
|
||||
public Integer getInnerMinDeliveryFee() {
|
||||
String v = getSystemConfig(CommonConstant.Inner_Min_DeliveryFee_Key);
|
||||
return NumberUtil.isNumber(v) ? Convert.toInt(v) : 0;
|
||||
public Integer getInnerMinDeliveryFee(Integer storeId) {
|
||||
// 如果storeId无效,直接使用平台默认配置
|
||||
if (storeId == null || storeId <= 0) {
|
||||
return getDefaultMinDeliveryFee();
|
||||
}
|
||||
|
||||
// 获取店铺内部运费
|
||||
Integer storeFee = shopStoreInfoService.getStoreShippingFeeInner(storeId);
|
||||
|
||||
// 如果店铺未设置有效运费,则使用平台默认配置
|
||||
if (storeFee == null || storeFee <= 0) {
|
||||
return getDefaultMinDeliveryFee();
|
||||
}
|
||||
|
||||
return storeFee;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取平台默认最低配送费
|
||||
*
|
||||
* @return 默认配送费,单位分
|
||||
*/
|
||||
private Integer getDefaultMinDeliveryFee() {
|
||||
String configValue = getSystemConfig(CommonConstant.Inner_Min_DeliveryFee_Key);
|
||||
int fee = NumberUtil.isNumber(configValue) ? Convert.toInt(configValue) : 0;
|
||||
return fee > 0 ? fee : 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@ -176,19 +176,7 @@ public interface LakalaApiService {
|
||||
* @return
|
||||
*/
|
||||
CommonResult getBankCardBin(String bankCardNo);
|
||||
|
||||
|
||||
/**
|
||||
* 拉卡拉订单分账,用户下单成功之后,进行分账
|
||||
* 说明:分账指令是异步处理模式,响应报文成功时,指令状态是”status”: “PROCESSING”,需要等待分账结果通知,或者主动发起查询,建议主动发起查询与分账指令动作之间间隔15秒以上。
|
||||
* 参考:https://o.lakala.com/#/home/document/detail?id=389
|
||||
*
|
||||
* @param orderId 平台订单号,必填参数
|
||||
* @param storeId 商户门店编号,非必填参数
|
||||
* @return
|
||||
*/
|
||||
Pair<Boolean, String> innerDoOrderSeparate(String orderId, String storeId);
|
||||
|
||||
|
||||
/**
|
||||
* 根据商户号、交易号和收货流水号执行订单分账操作
|
||||
* <p>
|
||||
|
||||
@ -65,7 +65,6 @@ import java.time.LocalDateTime;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
|
||||
@Slf4j
|
||||
@ -1838,7 +1837,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", "分账接收方绑定成功");
|
||||
@ -2265,270 +2264,6 @@ public class LakalaApiServiceImpl implements LakalaApiService {
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 执行拉卡拉订单分账操作
|
||||
* <p>
|
||||
* 用户确认收货成功之后(大约15秒后),进行分账操作。
|
||||
* 分账指令是异步处理模式,响应报文成功时,指令状态是"status": "PROCESSING",
|
||||
* 需要等待分账结果通知,或者主动发起查询。
|
||||
* 建议主动发起查询与分账指令动作之间间隔15秒以上。
|
||||
* </p>
|
||||
* <p>
|
||||
* 参考文档:https://o.lakala.com/#/home/document/detail?id=389
|
||||
* </p>
|
||||
*
|
||||
* @param orderId 平台订单Id
|
||||
* @param storeId 店铺Id,可为空
|
||||
* @return Pair<Boolean, String> 处理结果对,first为是否成功,second为结果描述信息
|
||||
*/
|
||||
@Override
|
||||
public Pair<Boolean, String> innerDoOrderSeparate(String orderId, String storeId) {
|
||||
// 1. 输入参数校验
|
||||
if (StrUtil.isBlank(orderId)) {
|
||||
log.warn("[分账操作] 参数校验失败:订单号为空");
|
||||
return Pair.of(false, "订单号不能为空");
|
||||
}
|
||||
|
||||
try {
|
||||
// TODO 检查可分账余额是否足够?
|
||||
|
||||
// 2. 查询订单信息
|
||||
log.info("[分账操作] 开始执行订单[{}]分账操作", orderId);
|
||||
List<ShopOrderLkl> shopOrderLklList = shopOrderLklService.selectByOrderId(orderId, "", storeId);
|
||||
if (CollectionUtil.isEmpty(shopOrderLklList)) {
|
||||
log.warn("[分账操作] 失败:订单[{}]不存在", orderId);
|
||||
return Pair.of(false, "订单不存在");
|
||||
}
|
||||
|
||||
int totalCount = shopOrderLklList.size();
|
||||
int successCount = 0;
|
||||
StringBuilder errorMessages = new StringBuilder();
|
||||
|
||||
// 3. 初始化拉卡拉SDK
|
||||
initLKLSDK();
|
||||
|
||||
// 4. 遍历处理每个店铺订单的分账
|
||||
log.info("[分账操作] 订单[{}]包含{}个子订单,开始逐一处理", orderId, totalCount);
|
||||
for (ShopOrderLkl shopOrderLkl : shopOrderLklList) {
|
||||
log.debug("[分账操作] 处理子订单:storeId={}, subLogNo={}, receive_log_no={}", shopOrderLkl.getStore_id(), shopOrderLkl.getLkl_sub_log_no(), shopOrderLkl.getLkl_receive_log_no());
|
||||
|
||||
if (!CommonConstant.Enable.equals(shopOrderLkl.getReceive_status()) || StrUtil.isBlank(shopOrderLkl.getLkl_receive_log_no())) {
|
||||
log.warn("[分账操作] 订单[{}]对账流水号[{}]未被确认收货,跳过处理", orderId, shopOrderLkl.getLkl_receive_log_no());
|
||||
continue;
|
||||
}
|
||||
|
||||
// 5. 检查分账状态,避免重复处理
|
||||
LklOrderSeparate existingSeparateRecord = lklOrderSeparateService.getByLogNoAndOutTradeNo(shopOrderLkl.getLkl_sub_log_no(), orderId);
|
||||
if (existingSeparateRecord != null) {
|
||||
String status = existingSeparateRecord.getStatus();
|
||||
if ("SUCCESS".equals(status)) {
|
||||
log.info("[分账操作] 订单[{}]交易对账流水号[{}]已完成分账,跳过处理", orderId, shopOrderLkl.getLkl_sub_log_no());
|
||||
successCount++;
|
||||
continue;
|
||||
}
|
||||
if ("PROCESSING".equals(status) || "ACCEPTED".equals(status)) {
|
||||
log.info("[分账操作] 订单[{}]交易对账流水号[{}]分账处理中或已受理,跳过处理", orderId, shopOrderLkl.getLkl_sub_log_no());
|
||||
successCount++;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
// 6. 获取订单分账相关参数
|
||||
String merchantNo = shopOrderLkl.getLkl_merchant_no();
|
||||
|
||||
// 分账金额 = 应付总金额-运费(支付时已计算好)
|
||||
Integer splitAmount = shopOrderLkl.getSplit_amt();
|
||||
splitAmount = CheckUtil.isEmpty(splitAmount) ? 0 : splitAmount;
|
||||
|
||||
// 7. 分账金额校验
|
||||
if (splitAmount < 1) {
|
||||
String errorMsg = String.format("[分账操作] 店铺[%s]订单[%s]分账金额[%d]低于1分钱,跳过分账",
|
||||
shopOrderLkl.getStore_id(), orderId, splitAmount);
|
||||
log.error(errorMsg);
|
||||
errorMessages.append(errorMsg).append("; ");
|
||||
if (existingSeparateRecord != null) {
|
||||
lklOrderSeparateService.updateRemark(existingSeparateRecord.getId(), errorMsg);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
// 获取分账平台接收方信息
|
||||
LklLedgerMerReceiverBind platformReceiver = lklLedgerMerReceiverBindService.getPlatformByMerCupNo(merchantNo);
|
||||
|
||||
if (platformReceiver == null) {
|
||||
String errorMsg = String.format("[分账操作] 店铺[%s]未绑定平台方接收账户,跳过分账", shopOrderLkl.getStore_id());
|
||||
log.error(errorMsg);
|
||||
errorMessages.append(errorMsg).append("; ");
|
||||
continue;
|
||||
}
|
||||
|
||||
// 8. 构建分账接收方列表
|
||||
List<V3SacsSeparateRecvDatas> recvDatas = new ArrayList<>();
|
||||
|
||||
// 9. 获取商家分账比例并校验
|
||||
BigDecimal merchantSplitRatioRaw = shopOrderLkl.getSplit_ratio(); // 如:94 代表94%
|
||||
// 判断商家分账比例是否有效(必须在(0, 100]范围内)
|
||||
boolean canSplitForMerchant = merchantSplitRatioRaw != null
|
||||
&& merchantSplitRatioRaw.compareTo(BigDecimal.ZERO) > 0
|
||||
&& merchantSplitRatioRaw.compareTo(new BigDecimal(100)) <= 0;
|
||||
if (!canSplitForMerchant) {
|
||||
String errorMsg = String.format("[分账操作] 店铺[%s]商家分账比例[%s]不在(0-100]范围内,无法分账",
|
||||
shopOrderLkl.getStore_id(), merchantSplitRatioRaw);
|
||||
log.error(errorMsg);
|
||||
errorMessages.append(errorMsg).append("; ");
|
||||
continue;
|
||||
}
|
||||
// 商家分账
|
||||
BigDecimal merchantSplitRatio = merchantSplitRatioRaw.divide(new BigDecimal(100)); // 比如:94%
|
||||
|
||||
BigDecimal distributorSplitRatio = BigDecimal.ZERO;
|
||||
BigDecimal platformSplitRatio = BigDecimal.ONE;
|
||||
// 分账代理商接收方信息
|
||||
List<LklLedgerMerReceiverBind> distributorReceivers = lklLedgerMerReceiverBindService.selectAgentByMerCupNo(merchantNo);
|
||||
if (distributorReceivers != null && !distributorReceivers.isEmpty()) {
|
||||
distributorSplitRatio = new BigDecimal("0.8");
|
||||
platformSplitRatio = new BigDecimal("0.2");
|
||||
}
|
||||
|
||||
// 记录关键分账参数,便于问题排查
|
||||
log.info("[分账操作] 参数信息:订单={}, 商户={}, 总金额={}分, 商家比例={}, 平台比例={}, 代理商比例={}, 是否有代理商={}",
|
||||
orderId, merchantNo, splitAmount, merchantSplitRatio, platformSplitRatio, distributorSplitRatio,
|
||||
(distributorReceivers != null && !distributorReceivers.isEmpty()));
|
||||
|
||||
// 返回值如下:{platformAmount=6, merchantAmount=94, agentAmount=0}
|
||||
Map<String, Integer> splitAmountMap = CommonUtil.calculateProfitSharing(splitAmount, merchantSplitRatio, platformSplitRatio, distributorSplitRatio);
|
||||
Integer merchantAmount = splitAmountMap.get("merchantAmount");
|
||||
Integer platformAmount = splitAmountMap.get("platformAmount");
|
||||
Integer agentAmount = splitAmountMap.get("agentAmount");
|
||||
|
||||
// 记录分账结果,便于问题排查
|
||||
log.info("[分账操作] 金额计算结果:订单={}, 商户={}, 总金额={}分, 商家分得={}分, 平台分得={}分, 代理商分得={}分",
|
||||
orderId, merchantNo, splitAmount, merchantAmount, platformAmount, agentAmount);
|
||||
|
||||
if (merchantAmount > 0) {
|
||||
V3SacsSeparateRecvDatas receiver = new V3SacsSeparateRecvDatas();
|
||||
receiver.setRecvMerchantNo(merchantNo);
|
||||
receiver.setSeparateValue(merchantAmount.toString());
|
||||
recvDatas.add(receiver);
|
||||
}
|
||||
|
||||
if (platformAmount > 0) {
|
||||
V3SacsSeparateRecvDatas receiver = new V3SacsSeparateRecvDatas();
|
||||
receiver.setRecvNo(platformReceiver.getReceiver_no());
|
||||
receiver.setSeparateValue(platformAmount.toString());
|
||||
recvDatas.add(receiver);
|
||||
}
|
||||
|
||||
if (agentAmount > 0 && distributorReceivers != null && !distributorReceivers.isEmpty()) {
|
||||
V3SacsSeparateRecvDatas receiver = new V3SacsSeparateRecvDatas();
|
||||
receiver.setRecvNo(distributorReceivers.get(0).getReceiver_no());
|
||||
receiver.setSeparateValue(agentAmount.toString());
|
||||
recvDatas.add(receiver);
|
||||
}
|
||||
|
||||
// 14. 构建分账请求对象
|
||||
V3SacsSeparateRequest separateRequest = new V3SacsSeparateRequest();
|
||||
separateRequest.setMerchantNo(merchantNo);
|
||||
separateRequest.setLogNo(shopOrderLkl.getLkl_receive_log_no()); // 合单和非合单的流水号保存在此字段
|
||||
separateRequest.setLogDate(shopOrderLkl.getLkl_log_date());
|
||||
separateRequest.setOutSeparateNo(shopOrderLkl.getOut_separate_no());
|
||||
separateRequest.setTotalAmt(splitAmount.toString());
|
||||
separateRequest.setLklOrgNo(orgCode);
|
||||
separateRequest.setCalType("0"); // 0- 按照指定金额,1- 按照指定比例。默认 0
|
||||
separateRequest.setNotifyUrl(projectDomain + "/api/mobile/shop/lakala/sacs/separateNotify");
|
||||
|
||||
// 15. 设置分账接收方列表
|
||||
separateRequest.setRecvDatas(recvDatas);
|
||||
log.info("[分账操作] 请求参数: 订单={}, 商户={}, 金额={}分, 分账接收方数量={}",
|
||||
orderId, merchantNo, splitAmount, recvDatas.size());
|
||||
|
||||
log.debug("[分账操作] 请求详细参数: {}", JSONUtil.toJsonStr(separateRequest));
|
||||
|
||||
// 16. 发送分账请求
|
||||
log.info("[分账操作] 向拉卡拉发送分账请求:订单={}, 商户={}, 分账流水号={}",
|
||||
orderId, merchantNo, shopOrderLkl.getLkl_sub_log_no());
|
||||
String response = LKLSDK.httpPost(separateRequest);
|
||||
if (StrUtil.isBlank(response)) {
|
||||
String errorMsg = String.format("[分账操作] 拉卡拉无响应,订单=%s,商户=%s,分账流水号=%s",
|
||||
orderId, merchantNo, shopOrderLkl.getLkl_sub_log_no());
|
||||
log.error(errorMsg);
|
||||
errorMessages.append(errorMsg).append("; ");
|
||||
continue;
|
||||
}
|
||||
|
||||
log.debug("[分账操作] 响应结果: {}", response);
|
||||
|
||||
// 17. 解析响应结果
|
||||
JSONObject respJson = JSONUtil.parseObj(response);
|
||||
if (respJson == null || !lklSacsSuccessCode.equals(respJson.getStr("code")) || respJson.getJSONObject("resp_data") == null) {
|
||||
String errorMsg = String.format("[分账操作] 拉卡拉返回格式异常,订单=%s,商户=%s,分账流水号=%s,响应=%s,respJson=%s",
|
||||
orderId, merchantNo, shopOrderLkl.getLkl_sub_log_no(), response, respJson);
|
||||
log.error(errorMsg);
|
||||
errorMessages.append(errorMsg).append("; ");
|
||||
continue;
|
||||
}
|
||||
|
||||
// 18. 保存分账记录
|
||||
JSONObject respData = respJson.getJSONObject("resp_data");
|
||||
LklOrderSeparate separateRecord = new LklOrderSeparate();
|
||||
separateRecord.setSeparate_no(respData.getStr("separate_no"));
|
||||
separateRecord.setOut_separate_no(separateRequest.getOutSeparateNo());
|
||||
separateRecord.setMerchant_no(merchantNo);
|
||||
separateRecord.setLog_no(separateRequest.getLogNo()); // 发货完成交易流水号后14位 。分账商户用该流水号发起分账
|
||||
separateRecord.setLog_date(separateRequest.getLogDate());
|
||||
separateRecord.setOrder_id(shopOrderLkl.getOrder_id());
|
||||
separateRecord.setNotify_url(separateRequest.getNotifyUrl());
|
||||
separateRecord.setLkl_org_no(separateRequest.getLklOrgNo());
|
||||
separateRecord.setRecv_datas(JSONUtil.toJsonStr(separateRequest.getRecvDatas()));
|
||||
separateRecord.setStatus(respData.getStr("status"));
|
||||
separateRecord.setTotal_amt(separateRequest.getTotalAmt());
|
||||
separateRecord.setActual_separate_amt(Convert.toStr(shopOrderLkl.getSplit_amt()));
|
||||
|
||||
try {
|
||||
if (lklOrderSeparateService.addOrUpdateByReceiverNo(separateRecord)) {
|
||||
log.info("[分账操作] 记录保存成功:订单={}, 分账单号={}, 状态={}, 分账流水号={}",
|
||||
orderId, separateRecord.getSeparate_no(), separateRecord.getStatus(), separateRecord.getLog_no());
|
||||
successCount++;
|
||||
} else {
|
||||
String errorMsg = String.format("[分账操作] 保存分账记录失败,订单=%s,分账单号=%s,分账流水号=%s",
|
||||
orderId, separateRecord.getSeparate_no(), separateRecord.getLog_no());
|
||||
log.error(errorMsg);
|
||||
lklOrderSeparateService.updateRemark(separateRecord.getLog_no(), separateRecord.getSeparate_no(), errorMsg);
|
||||
errorMessages.append(errorMsg).append("; ");
|
||||
}
|
||||
} catch (Exception e) {
|
||||
String errorMsg = String.format("[分账操作] 保存分账记录异常,订单=%s,分账单号=%s,流水号=%s,错误=%s",
|
||||
orderId,
|
||||
separateRecord.getSeparate_no(),
|
||||
separateRecord.getLog_no(),
|
||||
e.getMessage());
|
||||
log.error(errorMsg, e);
|
||||
errorMessages.append(errorMsg).append("; ");
|
||||
}
|
||||
}
|
||||
|
||||
// 19. 返回最终处理结果
|
||||
log.info("[分账操作] 处理完成:总订单数={},成功处理数={}", orderId, totalCount, successCount);
|
||||
if (successCount == 0) {
|
||||
String result = "分账全部失败: " + errorMessages;
|
||||
log.warn("[分账操作] 结果:订单[{}] {}", orderId, result);
|
||||
return Pair.of(false, result);
|
||||
} else if (successCount < totalCount) {
|
||||
String result = "部分分账成功,处理中: " + errorMessages;
|
||||
log.info("[分账操作] 结果:订单[{}] {}", orderId, result);
|
||||
return Pair.of(true, result);
|
||||
} else {
|
||||
String result = "全部订单分账已提交处理";
|
||||
log.info("[分账操作] 结果:订单[{}] {}", orderId, result);
|
||||
return Pair.of(true, result);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
String errorMsg = String.format("[分账操作] 系统异常,订单=%s,错误=%s", orderId, e.getMessage());
|
||||
log.error(errorMsg, e);
|
||||
return Pair.of(false, "系统异常,请稍后重试");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据商户号、交易号和收货流水号执行订单分账操作
|
||||
* <p>
|
||||
@ -2838,6 +2573,9 @@ public class LakalaApiServiceImpl implements LakalaApiService {
|
||||
separateRecord.setTotal_amt(separateRequest.getTotalAmt());
|
||||
separateRecord.setActual_separate_amt(Convert.toStr(refCanSeparateAmt));
|
||||
separateRecord.setTotal_fee_amt(Convert.toStr(lklSeparateDTO.getLklAmount()));
|
||||
if (separateRequest != null) {
|
||||
separateRecord.setLkl_req(JSONUtil.toJsonStr(separateRequest));
|
||||
}
|
||||
|
||||
if (lklOrderSeparateService.addOrUpdateByReceiverNo(separateRecord)) {
|
||||
log.info("[分账操作] 分账记录保存成功, orderId={}, separateNo={}, status={}, logNo={}",
|
||||
@ -3798,6 +3536,9 @@ public class LakalaApiServiceImpl implements LakalaApiService {
|
||||
lklOrderDraw.setBatch_auto_settle(payType);
|
||||
lklOrderDraw.setNotify_url(request.getNotifyUrl());
|
||||
lklOrderDraw.setNotify_resp(responseStr);
|
||||
if (request != null) {
|
||||
lklOrderDraw.setLkl_req(JSONUtil.toJsonStr(request));
|
||||
}
|
||||
lklOrderDraw.setRemark(remark);
|
||||
if (StrUtil.isNotBlank(summary)) {
|
||||
lklOrderDraw.setSummary(summary);
|
||||
|
||||
@ -322,10 +322,10 @@ public class UserOrderController extends BaseControllerImpl {
|
||||
return CommonResult.success(data);
|
||||
}
|
||||
|
||||
@ApiOperation(value = "可预约订单的时间槽", notes = "可预约订单的时间槽")
|
||||
@ApiOperation(value = "可预约订单的时间槽", notes = "结算中心页面,可预约订单的时间槽")
|
||||
@RequestMapping(value = "/booking_time_args", method = RequestMethod.GET)
|
||||
public CommonResult listInvoice(@RequestParam(name = "store_id", defaultValue = "0") Integer store_id) {
|
||||
List<BookingArgDTO> list = shopOrderInfoService.genBookingOrderArgList(store_id);
|
||||
public CommonResult listInvoice(@RequestParam(name = "store_ids", defaultValue = "") String store_ids) {
|
||||
List<BookingArgDTO> list = shopOrderInfoService.genBookingOrderArgList(store_ids);
|
||||
return CommonResult.success(list);
|
||||
}
|
||||
|
||||
|
||||
@ -187,12 +187,13 @@ public class OrderPayedListener {
|
||||
continue;
|
||||
}
|
||||
|
||||
// 同城配送或普通快递,都发送 unipush 推送:您有一个新的订单,请查收!
|
||||
// 同城配送或普通快递,都发送 unipush 推送:您有一个新的[同城][预约]订单,请及时拣货配送[请及时查看预约订单]。
|
||||
String bookingTip = isBookingOrder ? "预约" : "";
|
||||
|
||||
String orderType = orderInfoOld.getDelivery_type_id() == StateCode.DELIVERY_TYPE_SAME_CITY ? "同城" + bookingTip : bookingTip;
|
||||
String title = String.format("您有一笔新的%s订单,请注意查收。", orderType);
|
||||
String content = String.format("这笔新的%s订单:%s,用户于%s下的单,请注意查收。", orderType, orderId, DateTimeUtils.formatDateTime(LocalDateTime.now(), "yyyy-MM-dd HH:mm:ss"));
|
||||
String actionTip = isBookingOrder ? "请及时检查预约订单信息" : "请及时拣货配送";
|
||||
String orderType = (orderInfoOld.getDelivery_type_id() == StateCode.DELIVERY_TYPE_SAME_CITY ? "同城" : "") + bookingTip;
|
||||
String title = String.format("您有一笔新的%s订单,%s。", orderType, actionTip);
|
||||
String content = String.format("这笔新的%s订单:%s,用户于%s下的单,%s。", orderType, orderId,
|
||||
DateTimeUtils.formatDateTime(LocalDateTime.now(), "yyyy-MM-dd HH:mm:ss"), actionTip);
|
||||
JSONObject payload = new JSONObject();
|
||||
payload.put("category", CommonConstant.PUSH_MSG_CATE_MCH_ONLINE_ORDER_LIST);
|
||||
payload.put("orderId", orderId);
|
||||
|
||||
@ -96,6 +96,7 @@ public class RedisKeyExpiredListener implements MessageListener {
|
||||
|
||||
// orderId
|
||||
String orderId = expiredKey.replace(RedisConstant.Order_Booking_Task_Key, "");
|
||||
log.info("[预约订单顺丰同城下单Redis过期监听] 处理预约订单顺丰同城下单超时消息. 订单号: {}", orderId);
|
||||
if (StrUtil.isBlank(orderId)) {
|
||||
log.error("[预约订单顺丰同城下单Redis过期监听] 键: {} 不符合预期格式,无法解析订单号", expiredKey);
|
||||
return;
|
||||
|
||||
@ -607,4 +607,13 @@ public interface ShopOrderBaseService extends IBaseService<ShopOrderBase> {
|
||||
* @return
|
||||
*/
|
||||
Long sameCityOrderExpireSeconds(Long defaultValue);
|
||||
|
||||
/**
|
||||
* 更新订单下单时间
|
||||
*
|
||||
* @param orderId
|
||||
* @param orderTime
|
||||
* @return
|
||||
*/
|
||||
Boolean updateOrderTime(String orderId, Date orderTime);
|
||||
}
|
||||
|
||||
@ -8,7 +8,6 @@
|
||||
|
||||
package com.suisung.mall.shop.order.service;
|
||||
|
||||
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import com.suisung.mall.common.modules.order.ShopOrderBooking;
|
||||
import com.suisung.mall.core.web.service.IBaseService;
|
||||
@ -40,15 +39,7 @@ public interface ShopOrderBookingService extends IBaseService<ShopOrderBooking>
|
||||
* @return 分页结果
|
||||
*/
|
||||
Page<ShopOrderBooking> findValidBookingList(Integer pageNum, Integer pageSize);
|
||||
|
||||
/**
|
||||
* 更新预约订单任务
|
||||
*
|
||||
* @param updateWrapper 更新条件包装器
|
||||
* @return 是否更新成功
|
||||
*/
|
||||
Boolean update(UpdateWrapper<ShopOrderBooking> updateWrapper);
|
||||
|
||||
|
||||
/**
|
||||
* 更改预约订单任务下单完成状态(同时删除 redis 的定时任务)
|
||||
*
|
||||
|
||||
@ -139,8 +139,8 @@ public interface ShopOrderInfoService extends IBaseService<ShopOrderInfo> {
|
||||
/**
|
||||
* 根据店铺的营业时间范围生成可预约下单的参数
|
||||
*
|
||||
* @param storeId 店铺ID
|
||||
* @param storeId 店铺ID,多个店铺,使用英文半角逗号隔开,如:57,58,59
|
||||
* @return
|
||||
*/
|
||||
List<BookingArgDTO> genBookingOrderArgList(Integer storeId);
|
||||
List<BookingArgDTO> genBookingOrderArgList(String storeId);
|
||||
}
|
||||
|
||||
@ -171,7 +171,7 @@ public interface ShopOrderReturnService extends IBaseService<ShopOrderReturn> {
|
||||
* @param productId 商品ID
|
||||
* @return boolean true表示禁止退货,false表示允许退货
|
||||
*/
|
||||
boolean ifOrderItemDenyReturn(String orderId, Long productId);
|
||||
boolean isOrderItemDenyReturn(String orderId, Long productId);
|
||||
|
||||
/**
|
||||
* 判断订单是否禁止退货
|
||||
|
||||
@ -1395,8 +1395,8 @@ public class ShopOrderBaseServiceImpl extends BaseServiceImpl<ShopOrderBaseMappe
|
||||
|
||||
Integer quantity = getParameter("quantity", 1);
|
||||
Integer channelType = getParameter("channel_type", 0);
|
||||
Map activityRows = new HashMap();
|
||||
|
||||
Map activityRows = new HashMap();
|
||||
if (!activityId.equals(0)) {
|
||||
activityRows = shopStoreActivityBaseService.getActivityFormatOne(activityId, quantity);
|
||||
}
|
||||
@ -1580,8 +1580,17 @@ public class ShopOrderBaseServiceImpl extends BaseServiceImpl<ShopOrderBaseMappe
|
||||
|
||||
// 判断是否砍价购买
|
||||
Integer acId = getParameter("ac_id", Integer.class);
|
||||
if (acId != null) {
|
||||
cartData.put("ac_id", acId); // 拼团ID, 为0,在创建拼团
|
||||
// 判断是否为砍价活动
|
||||
Boolean isCutPriceActivity = shopStoreActivityBaseService.isCutPriceActivity(activityId);
|
||||
if (CheckUtil.isNotEmpty(acId) && isCutPriceActivity) {
|
||||
cartData.put("ac_id", acId);
|
||||
|
||||
// 校验砍价活动,用户是否可以立即购买了?
|
||||
Pair<Boolean, String> canDoOrderCutPriceActivity = shopActivityCutpriceService.canDoOrderCutPriceActivity(acId, userId);
|
||||
if (!canDoOrderCutPriceActivity.getFirst()) {
|
||||
logger.error(canDoOrderCutPriceActivity.getSecond());
|
||||
throw new ApiException(I18nUtil._("砍价活动未达标,请继续努力,再提交订单。"));
|
||||
}
|
||||
}
|
||||
|
||||
// 注:(重要)邮费检测和计算
|
||||
@ -6675,15 +6684,22 @@ public class ShopOrderBaseServiceImpl extends BaseServiceImpl<ShopOrderBaseMappe
|
||||
bookingAt = bookingBeginTime.getTime() / 1000; // 预订单到达时间戳(秒)
|
||||
}
|
||||
|
||||
// 计算订单下单时间:预约开始时间前35分钟
|
||||
Date scheduledOrderTime = DateUtil.offsetSecond(bookingBeginTime, -Convert.toInt(sameCityOrderExpireSeconds(2100L))); // 35分钟超时,60秒*35分钟 = 2100秒
|
||||
|
||||
info_row.setBooking_state(bookingState);
|
||||
info_row.setBooking_at(bookingAt);
|
||||
info_row.setBooking_begin_time(bookingBeginTime);
|
||||
info_row.setBooking_end_time(bookingEndTime);
|
||||
info_row.setOrder_time(scheduledOrderTime.getTime());
|
||||
|
||||
// 重要:预约订单任务创建处理
|
||||
if (!shopOrderBookingService.setupRedisBookingTask(info_row.getOrder_id(), info_row.getBooking_at())) {
|
||||
throw new ApiException(I18nUtil._("保存预约订单任务失败!"));
|
||||
}
|
||||
|
||||
// 更新订单的下单时间
|
||||
updateOrderTime(order_id, scheduledOrderTime);
|
||||
}
|
||||
|
||||
|
||||
@ -7756,7 +7772,7 @@ public class ShopOrderBaseServiceImpl extends BaseServiceImpl<ShopOrderBaseMappe
|
||||
data_row.setPacking_fee(packingFee);
|
||||
|
||||
// 平台最低配送费,单位(分)
|
||||
Integer innerMinDeliverFee = accountBaseConfigService.getInnerMinDeliveryFee();
|
||||
Integer innerMinDeliverFee = accountBaseConfigService.getInnerMinDeliveryFee(store_id);
|
||||
|
||||
// 平台最低配送费,单位(元)
|
||||
BigDecimal shoppingFeeInner = Convert.toBigDecimal(innerMinDeliverFee).divide(BigDecimal.valueOf(100));
|
||||
@ -8759,7 +8775,7 @@ public class ShopOrderBaseServiceImpl extends BaseServiceImpl<ShopOrderBaseMappe
|
||||
// 支付渠道处理
|
||||
m.put("payment_channel_name", m.getOrDefault("payment_channel_name", "线上支付").toString());
|
||||
|
||||
// 配送时间= 支付时间+35分钟
|
||||
// 配送到达时间= 支付时间+35分钟
|
||||
Long mchOrderExpireSeconds = shopOrderBaseService.sameCityOrderExpireSeconds(2100L);
|
||||
// 配送时间
|
||||
Date paymentTime = Convert.toDate(m.get("payment_time"));
|
||||
@ -9054,13 +9070,22 @@ public class ShopOrderBaseServiceImpl extends BaseServiceImpl<ShopOrderBaseMappe
|
||||
order.setOrder_pickup_num_str(StringUtils.fmtPickNum(order.getOrder_pickup_num()));
|
||||
|
||||
// 订单是否禁止退款
|
||||
int isOrderDenyReturn = shopOrderReturnService.isOrderDenyReturn(order.getOrder_id()) ? 1 : 2;
|
||||
order.setIs_deny_return(isOrderDenyReturn);
|
||||
boolean isOrderDenyReturn = shopOrderReturnService.isOrderDenyReturn(order.getOrder_id());
|
||||
order.setIs_deny_return(isOrderDenyReturn ? CommonConstant.Enable : CommonConstant.Disable2);
|
||||
|
||||
// 订单商品列表是否禁止退款
|
||||
order.getOrder_items().forEach(item -> {
|
||||
item.setIs_deny_return(isOrderDenyReturn);
|
||||
});
|
||||
if (CollUtil.isNotEmpty(order.getOrder_items())) {
|
||||
if (!isOrderDenyReturn) { // 允许退款的订单,再进一步检查每个商品是否不能退款
|
||||
// 订单商品列表是否禁止退款
|
||||
order.getOrder_items().forEach(item -> {
|
||||
// 注意:应该使用 order_item_id 而不是 product_id
|
||||
boolean isOrderItemDenyReturn = shopOrderReturnService.isOrderItemDenyReturn(order.getOrder_id(), item.getProduct_id());
|
||||
item.setIs_deny_return(isOrderItemDenyReturn ? CommonConstant.Enable : CommonConstant.Disable2);
|
||||
});
|
||||
} else {
|
||||
// 如果整个订单都禁止退款,则所有商品都禁止退款
|
||||
order.getOrder_items().forEach(item -> item.setIs_deny_return(CommonConstant.Enable));
|
||||
}
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
@ -9161,13 +9186,22 @@ public class ShopOrderBaseServiceImpl extends BaseServiceImpl<ShopOrderBaseMappe
|
||||
orderDetail.setOrder_pickup_num_str(StringUtils.fmtPickNum(orderDetail.getOrder_pickup_num()));
|
||||
|
||||
// 订单是否禁止退款
|
||||
int isOrderDenyReturn = shopOrderReturnService.isOrderDenyReturn(orderId) ? 1 : 2;
|
||||
orderDetail.setIs_deny_return(isOrderDenyReturn);
|
||||
boolean isOrderDenyReturn = shopOrderReturnService.isOrderDenyReturn(orderId);
|
||||
orderDetail.setIs_deny_return(isOrderDenyReturn ? CommonConstant.Enable : CommonConstant.Disable2);
|
||||
|
||||
// 订单商品列表是否禁止退款
|
||||
orderDetail.getOrder_items().forEach(item -> {
|
||||
item.setIs_deny_return(isOrderDenyReturn);
|
||||
});
|
||||
if (CollUtil.isNotEmpty(orderDetail.getOrder_items())) {
|
||||
if (!isOrderDenyReturn) { // 允许退款的订单,再进一步检查每个商品是否不能退款
|
||||
// 订单商品列表是否禁止退款
|
||||
orderDetail.getOrder_items().forEach(item -> {
|
||||
// 注意:应该使用 order_item_id 而不是 product_id
|
||||
boolean isOrderItemDenyReturn = shopOrderReturnService.isOrderItemDenyReturn(orderId, item.getProduct_id());
|
||||
item.setIs_deny_return(isOrderItemDenyReturn ? CommonConstant.Enable : CommonConstant.Disable2);
|
||||
});
|
||||
} else {
|
||||
// 如果整个订单都禁止退款,则所有商品都禁止退款
|
||||
orderDetail.getOrder_items().forEach(item -> item.setIs_deny_return(CommonConstant.Enable));
|
||||
}
|
||||
}
|
||||
|
||||
return orderDetail;
|
||||
}
|
||||
@ -9271,6 +9305,10 @@ public class ShopOrderBaseServiceImpl extends BaseServiceImpl<ShopOrderBaseMappe
|
||||
*/
|
||||
@Override
|
||||
public Long sameCityOrderExpireSeconds(Long defaultValue) {
|
||||
if (CheckUtil.isEmpty(defaultValue)) {
|
||||
defaultValue = 2100L;
|
||||
}
|
||||
|
||||
try {
|
||||
String value = accountService.getAccountBaseConfigValue(CommonConstant.CONF_KEY_SAME_CITY_ORDER_EXPIRE_SECONDS);
|
||||
if (StringUtils.isBlank(value)) {
|
||||
@ -9284,4 +9322,48 @@ public class ShopOrderBaseServiceImpl extends BaseServiceImpl<ShopOrderBaseMappe
|
||||
return defaultValue;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 更新订单下单时间
|
||||
*
|
||||
* @param orderId 订单ID
|
||||
* @param orderTime 新的订单时间
|
||||
* @return Boolean 更新是否成功
|
||||
*/
|
||||
@Override
|
||||
public Boolean updateOrderTime(String orderId, Date orderTime) {
|
||||
// 1. 参数校验
|
||||
if (StrUtil.isBlank(orderId)) {
|
||||
log.warn("[更新订单时间] 订单ID不能为空");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (orderTime == null) {
|
||||
log.warn("[更新订单时间] 订单时间不能为空, orderId={}", orderId);
|
||||
return false;
|
||||
}
|
||||
|
||||
try {
|
||||
// 2. 构建更新条件
|
||||
UpdateWrapper<ShopOrderBase> updateWrapper = new UpdateWrapper<>();
|
||||
updateWrapper.eq("order_id", orderId)
|
||||
.set("order_time", orderTime);
|
||||
|
||||
// 3. 执行更新操作
|
||||
boolean result = update(updateWrapper);
|
||||
|
||||
if (result) {
|
||||
log.info("[更新订单时间] 订单时间更新成功, orderId={}, orderTime={}", orderId, orderTime);
|
||||
} else {
|
||||
log.warn("[更新订单时间] 订单时间更新失败, 可能订单不存在, orderId={}", orderId);
|
||||
}
|
||||
|
||||
return result;
|
||||
} catch (Exception e) {
|
||||
// 4. 异常处理
|
||||
log.error("[更新订单时间] 更新订单时间时发生异常, orderId={}, orderTime={}", orderId, orderTime, e);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -21,6 +21,7 @@ import com.suisung.mall.common.utils.CheckUtil;
|
||||
import com.suisung.mall.core.web.service.RedisService;
|
||||
import com.suisung.mall.core.web.service.impl.BaseServiceImpl;
|
||||
import com.suisung.mall.shop.order.mapper.ShopOrderBookingMapper;
|
||||
import com.suisung.mall.shop.order.service.ShopOrderBaseService;
|
||||
import com.suisung.mall.shop.order.service.ShopOrderBookingService;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
@ -30,17 +31,18 @@ import org.springframework.util.StringUtils;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
@Slf4j
|
||||
@Service
|
||||
public class ShopOrderBookingServiceImpl extends BaseServiceImpl<ShopOrderBookingMapper, ShopOrderBooking> implements ShopOrderBookingService {
|
||||
|
||||
private static final Long MINUTES_BEFORE_BOOKING = 35L;
|
||||
|
||||
@Resource
|
||||
private ShopOrderBookingMapper shopOrderBookingMapper;
|
||||
|
||||
@Lazy
|
||||
@Resource
|
||||
private ShopOrderBaseService shopOrderBaseService;
|
||||
|
||||
@Lazy
|
||||
@Autowired
|
||||
private RedisService redisService;
|
||||
@ -64,7 +66,8 @@ public class ShopOrderBookingServiceImpl extends BaseServiceImpl<ShopOrderBookin
|
||||
|
||||
try {
|
||||
// 计算执行时间(预约时间前35分钟)
|
||||
long runAt = bookingAt - TimeUnit.MINUTES.toSeconds(MINUTES_BEFORE_BOOKING);
|
||||
// long runAt = bookingAt - TimeUnit.MINUTES.toSeconds(CommonConstant.MIN_DELAY_MINUTES_FOR_SF_EXPRESS_ORDER);
|
||||
long runAt = bookingAt - shopOrderBaseService.sameCityOrderExpireSeconds(2100L); // 35分钟超时,60秒*35分钟 = 2100秒
|
||||
|
||||
ShopOrderBooking shopOrderBooking = new ShopOrderBooking();
|
||||
shopOrderBooking.setOrder_id(orderId);
|
||||
@ -77,9 +80,10 @@ public class ShopOrderBookingServiceImpl extends BaseServiceImpl<ShopOrderBookin
|
||||
// 如果保存成功,设置Redis过期键
|
||||
if (shopOrderBooking != null) {
|
||||
String redisKey = RedisConstant.Order_Booking_Task_Key + orderId;
|
||||
long remainingSeconds = runAt - System.currentTimeMillis() / 1000;
|
||||
// 设置过期时间为runAt时间点(相对于当前时间的秒数)
|
||||
if (runAt > 0) {
|
||||
redisService.set(redisKey, Convert.toStr(shopOrderBooking.getRun_at()), runAt);
|
||||
if (remainingSeconds > 0) {
|
||||
redisService.set(redisKey, Convert.toStr(shopOrderBooking.getRun_at()), remainingSeconds);
|
||||
log.debug("Redis键设置成功: key={}, bookingAt={}, runAt={}", redisKey, bookingAt, runAt);
|
||||
} else {
|
||||
log.warn("过期时间无效,未设置Redis键: key={}, bookingAt={}, runAt={}", redisKey, bookingAt, runAt);
|
||||
@ -111,7 +115,7 @@ public class ShopOrderBookingServiceImpl extends BaseServiceImpl<ShopOrderBookin
|
||||
|
||||
try {
|
||||
if (CheckUtil.isEmpty(shopOrderBooking.getRun_at())) {
|
||||
long runAt = shopOrderBooking.getBooking_at() - TimeUnit.MINUTES.toSeconds(MINUTES_BEFORE_BOOKING);
|
||||
long runAt = shopOrderBooking.getBooking_at() - shopOrderBaseService.sameCityOrderExpireSeconds(2100L); // 35分钟超时,60秒*35分钟 = 2100秒
|
||||
shopOrderBooking.setRun_at(runAt);
|
||||
}
|
||||
|
||||
@ -166,22 +170,6 @@ public class ShopOrderBookingServiceImpl extends BaseServiceImpl<ShopOrderBookin
|
||||
return this.page(page, queryWrapper);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Boolean update(UpdateWrapper<ShopOrderBooking> updateWrapper) {
|
||||
log.debug("更新预约订单任务");
|
||||
if (updateWrapper == null) {
|
||||
log.warn("更新条件不能为空");
|
||||
return false;
|
||||
}
|
||||
|
||||
try {
|
||||
return this.update(updateWrapper);
|
||||
} catch (Exception e) {
|
||||
log.error("更新预约订单任务时发生异常", e);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 更改预约订单任务下单完成状态(同时删除 redis 的定时任务)
|
||||
*
|
||||
@ -205,7 +193,7 @@ public class ShopOrderBookingServiceImpl extends BaseServiceImpl<ShopOrderBookin
|
||||
updateWrapper.set("status", CommonConstant.Disable2);
|
||||
|
||||
// 执行更新操作
|
||||
boolean result = this.update(updateWrapper);
|
||||
boolean result = update(updateWrapper);
|
||||
|
||||
if (result) {
|
||||
log.debug("成功完成预约订单任务的同城配送下单: orderId={}", orderId);
|
||||
@ -246,13 +234,18 @@ public class ShopOrderBookingServiceImpl extends BaseServiceImpl<ShopOrderBookin
|
||||
continue;
|
||||
}
|
||||
|
||||
redisService.set(redisKey, Convert.toStr(shopOrderBooking.getRun_at()), shopOrderBooking.getRun_at());
|
||||
if (shopOrderBooking == null || shopOrderBooking.getRun_at() == null) {
|
||||
log.debug("run_at 参数空不能同步到 Redis");
|
||||
continue;
|
||||
}
|
||||
|
||||
count++;
|
||||
long remainingSeconds = shopOrderBooking.getRun_at() - System.currentTimeMillis() / 1000;
|
||||
if (remainingSeconds > 0) {
|
||||
redisService.set(redisKey, Convert.toStr(shopOrderBooking.getRun_at()), remainingSeconds);
|
||||
count++;
|
||||
}
|
||||
}
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@ -1,5 +1,6 @@
|
||||
package com.suisung.mall.shop.order.service.impl;
|
||||
|
||||
import cn.hutool.core.collection.CollUtil;
|
||||
import cn.hutool.core.convert.Convert;
|
||||
import cn.hutool.core.date.DateUtil;
|
||||
import cn.hutool.core.util.NumberUtil;
|
||||
@ -118,27 +119,21 @@ public class ShopOrderInfoServiceImpl extends BaseServiceImpl<ShopOrderInfoMappe
|
||||
private ShopStorePrinterService shopStorePrinterService;
|
||||
@Autowired
|
||||
private ShopOrderInfoMapper shopOrderInfoMapper;
|
||||
|
||||
@Lazy
|
||||
@Autowired
|
||||
private ShopStoreSfOrderService shopStoreSfOrderService;
|
||||
|
||||
@Lazy
|
||||
@Autowired
|
||||
private ShopOrderBookingService shopOrderBookingService;
|
||||
|
||||
@Lazy
|
||||
@Autowired
|
||||
private SFExpressApiService sfExpressApiService;
|
||||
|
||||
@Lazy
|
||||
@Autowired
|
||||
private PushMessageService pushMessageService;
|
||||
|
||||
@Autowired
|
||||
private ThreadPoolExecutor executor;
|
||||
|
||||
|
||||
@Override
|
||||
public Map dashboard() {
|
||||
|
||||
@ -870,55 +865,55 @@ public class ShopOrderInfoServiceImpl extends BaseServiceImpl<ShopOrderInfoMappe
|
||||
public Pair<Boolean, String> checkBookingOrderArgs(Integer storeId, Integer bookingState, String bookingBeginTimeStr, String bookingEndTimeStr) {
|
||||
// 1. 必填参数检查
|
||||
if (CheckUtil.isEmpty(storeId) || CheckUtil.isEmpty(bookingState)) {
|
||||
return Pair.of(false, "[预约订单校验] 缺少必要参数");
|
||||
return Pair.of(false, "[预约单校验] 缺少必要参数");
|
||||
}
|
||||
|
||||
// 2. 预约状态检查
|
||||
if (!CommonConstant.Order_Booking_State_YY.equals(bookingState)) {
|
||||
return Pair.of(true, "[预约订单校验] 非预订单,跳过验证");
|
||||
return Pair.of(true, "[预约单校验] 非预订单,跳过验证");
|
||||
}
|
||||
|
||||
// 3. 时间格式检查
|
||||
if (StrUtil.isBlank(bookingBeginTimeStr)) {
|
||||
return Pair.of(false, "[预约订单校验] 预约时间不能为空");
|
||||
return Pair.of(false, "[预约单校验] 预约时间不能为空");
|
||||
}
|
||||
|
||||
Date bookingBeginTime = DateTimeUtils.tryParseDateTimeToDate(bookingBeginTimeStr);
|
||||
Date bookingEndTime = DateTimeUtils.tryParseDateTimeToDate(bookingEndTimeStr);
|
||||
if (bookingBeginTime == null) {
|
||||
return Pair.of(false, "[预约订单校验] 预约时间格式有误");
|
||||
return Pair.of(false, "[预约单校验] 预约时间格式有误");
|
||||
}
|
||||
|
||||
// 4. 时间逻辑检查 - 开始时间不能晚于结束时间
|
||||
if (bookingEndTime != null && bookingBeginTime.after(bookingEndTime)) {
|
||||
return Pair.of(false, "[预约订单校验] 开始时间不能晚于截止时间");
|
||||
return Pair.of(false, "[预约单校验] 开始时间不能晚于截止时间");
|
||||
}
|
||||
|
||||
// 5. 店铺信息检查
|
||||
ShopStoreInfo shopStoreInfo = shopStoreInfoService.getShopStoreInfoByStoreId(storeId);
|
||||
if (shopStoreInfo == null) {
|
||||
return Pair.of(false, "[预约订单校验] 店铺信息有误");
|
||||
return Pair.of(false, "[预约单校验] 店铺信息有误");
|
||||
}
|
||||
|
||||
if (StrUtil.isBlank(shopStoreInfo.getStore_opening_hours()) || StrUtil.isBlank(shopStoreInfo.getStore_close_hours())) {
|
||||
shopStoreInfo.setStore_opening_hours("09:00");
|
||||
shopStoreInfo.setStore_close_hours("06:00");
|
||||
logger.warn("[预约订单校验] 店铺营业时间未设置,请联系商家,默认指定 {}-{}", shopStoreInfo.getStore_opening_hours(), shopStoreInfo.getStore_close_hours());
|
||||
logger.warn("[预约单校验] 店铺营业时间未设置,请联系商家,默认指定 {}-{}", shopStoreInfo.getStore_opening_hours(), shopStoreInfo.getStore_close_hours());
|
||||
}
|
||||
|
||||
// 6. 店铺营业时间检查
|
||||
if (!DateTimeUtils.isTimeInRange(shopStoreInfo.getStore_opening_hours(), shopStoreInfo.getStore_close_hours(), bookingBeginTime)) {
|
||||
String message = StrUtil.format("[预约订单校验] 请在 {}-{} 店铺营业时间内预约下单", shopStoreInfo.getStore_opening_hours(), shopStoreInfo.getStore_close_hours());
|
||||
String message = StrUtil.format("[预约单校验] 请在 {}-{} 店铺营业时间内预约下单", shopStoreInfo.getStore_opening_hours(), shopStoreInfo.getStore_close_hours());
|
||||
return Pair.of(false, message);
|
||||
}
|
||||
|
||||
// 7. 预约时间范围检查 - 仅能预约50分钟后的订单(防止用户在下单页面停留太长,45分钟也是可以通过的)
|
||||
Date fortyFiveMinutesLater = DateUtil.offsetMinute(new Date(), 45);
|
||||
if (!bookingBeginTime.after(fortyFiveMinutesLater)) {
|
||||
return Pair.of(false, "[预约订单校验] 请预约50分后的订单");
|
||||
Date fortyFiveMinutesLater = DateUtil.offsetMinute(new Date(), CommonConstant.MIN_DELAY_MINUTES_FOR_BOOKING_ORDER - 5);
|
||||
if (bookingBeginTime.before(fortyFiveMinutesLater)) {
|
||||
return Pair.of(false, String.format("[预约单校验] 请预约%d分后的订单", CommonConstant.MIN_DELAY_MINUTES_FOR_BOOKING_ORDER));
|
||||
}
|
||||
|
||||
return Pair.of(true, "[预约订单校验] 成功");
|
||||
return Pair.of(true, "[预约单校验] 成功");
|
||||
}
|
||||
|
||||
/**
|
||||
@ -974,7 +969,6 @@ public class ShopOrderInfoServiceImpl extends BaseServiceImpl<ShopOrderInfoMappe
|
||||
return Pair.of(false, "预约订单已下过单,请勿重复操作");
|
||||
}
|
||||
|
||||
|
||||
// 调用顺丰接口创建订单
|
||||
Pair<Boolean, String> sfResult = sfExpressApiService.innerCreateSfExpressOrder(orderId, 0L);
|
||||
if (sfResult == null) {
|
||||
@ -997,8 +991,8 @@ public class ShopOrderInfoServiceImpl extends BaseServiceImpl<ShopOrderInfoMappe
|
||||
shopOrderBookingService.updateOrderBookingFinishState(orderId);
|
||||
|
||||
// 发送推送消息给商家
|
||||
String title = "您有一笔新的订单,请注意查收。";
|
||||
String content = String.format("这笔新的订单:%s,用户于%s下的单,请注意查收。",
|
||||
String title = "您有一笔新的订单,请及时拣货配送。";
|
||||
String content = String.format("这笔新的订单:%s,用户于%s下的单,请及时拣货配送。",
|
||||
orderId, DateTimeUtils.formatDateTime(LocalDateTime.now(), "yyyy-MM-dd HH:mm:ss"));
|
||||
JSONObject payload = new JSONObject();
|
||||
payload.set("category", CommonConstant.PUSH_MSG_CATE_MCH_ONLINE_ORDER_LIST);
|
||||
@ -1017,36 +1011,20 @@ public class ShopOrderInfoServiceImpl extends BaseServiceImpl<ShopOrderInfoMappe
|
||||
/**
|
||||
* 根据店铺的营业时间范围生成可预约下单的参数
|
||||
*
|
||||
* @param storeId 店铺ID
|
||||
* @param storeIds 店铺ID,多个店铺,使用英文半角逗号隔开,如:57,58,59
|
||||
* @return 预约参数列表
|
||||
*/
|
||||
@Override
|
||||
public List<BookingArgDTO> genBookingOrderArgList(Integer storeId) {
|
||||
public List<BookingArgDTO> genBookingOrderArgList(String storeIds) {
|
||||
// 初始化默认营业时间
|
||||
String openingHours = "09:00";
|
||||
String closeHours = "18:00";
|
||||
Map<String, String> timesMap = new HashMap<>();
|
||||
|
||||
// 如果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);
|
||||
if (StrUtil.isNotBlank(storeIds)) {
|
||||
List<Map<String, String>> timesMapList = selStoreBizTimeMapList(storeIds);
|
||||
if (!CollUtil.isEmpty(timesMapList)) {
|
||||
timesMap = DateTimeUtils.findTimeInterSection(timesMapList);
|
||||
}
|
||||
} else {
|
||||
logger.warn("[生成预约参数] 店铺ID为空,使用默认营业时间");
|
||||
}
|
||||
|
||||
List<BookingArgDTO> result = new ArrayList<>();
|
||||
@ -1061,8 +1039,9 @@ public class ShopOrderInfoServiceImpl extends BaseServiceImpl<ShopOrderInfoMappe
|
||||
String dateStr = DateUtil.format(currentDate, "yyyy-MM-dd");
|
||||
String displayDateStr = DateUtil.format(currentDate, "MM月dd日");
|
||||
|
||||
|
||||
// 安全获取星期信息
|
||||
String weekStr = "未知";
|
||||
String weekStr = "星期";
|
||||
try {
|
||||
weekStr = DateTimeUtils.getWeekOfDate(currentDate);
|
||||
} catch (Exception e) {
|
||||
@ -1082,14 +1061,48 @@ public class ShopOrderInfoServiceImpl extends BaseServiceImpl<ShopOrderInfoMappe
|
||||
bookingArgDTO.setDate(dateStr);
|
||||
|
||||
// 生成时间项
|
||||
List<BookingArgDTO.BookingArgItem> items = generateTimeSlots(dateStr, openingHours, closeHours, i == 0);
|
||||
bookingArgDTO.setItems(items != null ? items : new ArrayList<>());
|
||||
List<BookingArgDTO.BookingArgItem> items = new ArrayList<>();
|
||||
|
||||
// 如果是今天,始终添加"立即送出"选项
|
||||
if (i == 0) {
|
||||
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);
|
||||
}
|
||||
|
||||
// 只有当 timesMap 不为空时才生成其他时间槽
|
||||
if (!ObjectUtil.isEmpty(timesMap) && StrUtil.isNotBlank(timesMap.get("startTimeStr")) && StrUtil.isNotBlank(timesMap.get("endTimeStr"))) {
|
||||
String startTimeStr = timesMap.get("startTimeStr");
|
||||
String endTimeStr = timesMap.get("endTimeStr");
|
||||
List<BookingArgDTO.BookingArgItem> timeSlots = generateTimeSlots(dateStr, startTimeStr, endTimeStr, i == 0);
|
||||
if (i == 0) {
|
||||
// 对于今天,移除除"立即送出"外的所有时间槽
|
||||
items.addAll(timeSlots.stream().filter(item -> item.getBooking_state() != 1).collect(Collectors.toList()));
|
||||
} else {
|
||||
// 对于其他日期,添加所有时间槽
|
||||
items.addAll(timeSlots);
|
||||
}
|
||||
|
||||
bookingArgDTO.setWorking_hours(String.format("%s-%s", startTimeStr, endTimeStr));
|
||||
} else if (i == 0) {
|
||||
// 如果timesMap为空,今天只保留"立即送出"选项
|
||||
logger.debug("[生成预约参数] timesMap为空,今天只生成立即送出选项");
|
||||
} else {
|
||||
// 如果timesMap为空,其他日期不生成任何时间槽
|
||||
logger.debug("[生成预约参数] timesMap为空,不生成{}的预约时间槽", dateStr);
|
||||
continue; // 跳过当前日期
|
||||
}
|
||||
|
||||
bookingArgDTO.setItems(items);
|
||||
result.add(bookingArgDTO);
|
||||
}
|
||||
|
||||
logger.debug("[生成预约参数] 成功生成预约参数,storeId: {}, opening: {}, close: {}, 参数数量: {}",
|
||||
storeId, openingHours, closeHours, result.size());
|
||||
logger.debug("[生成预约参数] 成功生成预约参数,storeId: {}, timesMap: {}, 参数数量: {}",
|
||||
storeIds, timesMap, result.size());
|
||||
return result;
|
||||
}
|
||||
|
||||
@ -1135,13 +1148,13 @@ public class ShopOrderInfoServiceImpl extends BaseServiceImpl<ShopOrderInfoMappe
|
||||
}
|
||||
|
||||
// 时间槽间隔(分钟)
|
||||
int slotInterval = 30;
|
||||
int slotInterval = 15;
|
||||
|
||||
// 对于今天,需要特殊处理:第二个时间槽从当前时间+50分钟开始
|
||||
Date startTime = openTime;
|
||||
if (isToday) {
|
||||
// 当前时间+50分钟作为第二个时间槽的开始时间
|
||||
Date nowPlusFifty = DateUtil.offsetMinute(new Date(), 50);
|
||||
Date nowPlusFifty = DateUtil.offsetMinute(new Date(), CommonConstant.MIN_DELAY_MINUTES_FOR_BOOKING_ORDER);
|
||||
|
||||
// 如果当前时间+50分钟在营业时间范围内,则从该时间开始
|
||||
if (nowPlusFifty.after(openTime) && nowPlusFifty.before(closeTime)) {
|
||||
@ -1207,5 +1220,55 @@ public class ShopOrderInfoServiceImpl extends BaseServiceImpl<ShopOrderInfoMappe
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据 storeIds(一个或多个 storeid,如 34,23,43,23,),先对id去重,再获取多个店铺的营业时间 List<map{startTimeStr, endTimeStr}> 列表list
|
||||
*
|
||||
* @param storeIds 以逗号分隔的店铺ID字符串
|
||||
* @return 包含店铺营业时间信息的列表,每个元素为包含opening_hours和close_hours的Map
|
||||
*/
|
||||
private List<Map<String, String>> selStoreBizTimeMapList(String storeIds) {
|
||||
// 参数校验
|
||||
if (StrUtil.isBlank(storeIds)) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
try {
|
||||
// 1. 解析并去重店铺ID
|
||||
List<Integer> uniqueStoreIds = Arrays.stream(storeIds.split(","))
|
||||
.map(String::trim)
|
||||
.filter(StrUtil::isNotBlank)
|
||||
.map(Integer::valueOf)
|
||||
.distinct()
|
||||
.collect(Collectors.toList());
|
||||
|
||||
// 2. 如果没有有效的店铺ID,返回空列表
|
||||
if (uniqueStoreIds.isEmpty()) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
// 3. 批量获取店铺信息
|
||||
QueryWrapper<ShopStoreInfo> queryWrapper = new QueryWrapper<>();
|
||||
queryWrapper.select("store_opening_hours", "store_close_hours"); // 只查询必要字段
|
||||
queryWrapper.in("store_id", storeIds);
|
||||
|
||||
List<ShopStoreInfo> shopStoreInfos = shopStoreInfoService.find(queryWrapper);
|
||||
|
||||
// 4. 转换为营业时间映射列表
|
||||
return shopStoreInfos.stream()
|
||||
.filter(Objects::nonNull)
|
||||
.map(storeInfo -> {
|
||||
Map<String, String> timeSlot = new HashMap<>();
|
||||
timeSlot.put("startTimeStr", storeInfo.getStore_opening_hours());
|
||||
timeSlot.put("endTimeStr", storeInfo.getStore_close_hours());
|
||||
return timeSlot;
|
||||
})
|
||||
.collect(Collectors.toList());
|
||||
|
||||
} catch (Exception e) {
|
||||
logger.error("[获取店铺营业时间] 处理店铺营业时间异常,storeIds: {}", storeIds, e);
|
||||
return Collections.emptyList();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@ -1512,7 +1512,7 @@ public class ShopOrderReturnServiceImpl extends BaseServiceImpl<ShopOrderReturnM
|
||||
if (lestFrozenQuantity.compareTo(0) < 0) {
|
||||
lestFrozenQuantity = 0;
|
||||
}
|
||||
ShopProductItem upadteShopProductItem=new ShopProductItem();
|
||||
ShopProductItem upadteShopProductItem = new ShopProductItem();
|
||||
upadteShopProductItem.setItem_id(shopOrderItem.getItem_id());
|
||||
upadteShopProductItem.setItem_quantity(productItem.getItem_quantity() + returnNum);
|
||||
upadteShopProductItem.setItem_quantity_frozen(lestFrozenQuantity);
|
||||
@ -2112,32 +2112,27 @@ public class ShopOrderReturnServiceImpl extends BaseServiceImpl<ShopOrderReturnM
|
||||
* 如果订单状态为"已收货"或"已完成",并且当前时间超过允许提现时间,则标记为不可退货。
|
||||
*
|
||||
* @param shopOrderInfo 订单信息
|
||||
* @param shopOrderItem 订单商品项
|
||||
* @param shopProductIndex 商品索引信息
|
||||
* @param shopOrderItem 订单商品项(可选)
|
||||
* @param shopProductIndex 商品索引信息(可选,如果shopOrderItem存在则可以为空)
|
||||
* @return boolean true表示禁止退货,false表示允许退货
|
||||
*/
|
||||
public boolean ifDenyReturn(ShopOrderInfo shopOrderInfo, ShopOrderItem shopOrderItem, ShopProductIndex shopProductIndex) {
|
||||
// 1. 参数校验
|
||||
if (shopOrderItem == null) {
|
||||
log.debug("[是否禁止退货] 订单商品数据为空,不允许退货");
|
||||
return true;
|
||||
}
|
||||
|
||||
if (shopOrderInfo == null) {
|
||||
log.debug("[是否禁止退货] 订单信息为空,不允许退货");
|
||||
log.debug("[是否禁止退货] 订单信息为空,禁止退货");
|
||||
return true;
|
||||
}
|
||||
|
||||
String orderId = shopOrderInfo.getOrder_id();
|
||||
Integer orderStateId = shopOrderInfo.getOrder_state_id();
|
||||
if (StrUtil.isBlank(orderId) || CheckUtil.isEmpty(orderStateId)) {
|
||||
log.debug("[是否禁止退货] 订单ID或订单状态为空,不允许退货");
|
||||
log.debug("[是否禁止退货] 订单ID或订单状态为空,禁止退货");
|
||||
return true;
|
||||
}
|
||||
|
||||
if (orderStateId.intValue() == StateCode.ORDER_STATE_CANCEL ||
|
||||
orderStateId.intValue() == StateCode.ORDER_STATE_WAIT_PAY) {
|
||||
log.debug("[是否禁止退货] 订单已取消或未支付,不允许退货 order_id: {}", orderId);
|
||||
log.debug("[是否禁止退货] 订单状态为已取消或未支付,禁止退货,order_id: {}, orderStateId: {}", orderId, orderStateId);
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -2152,11 +2147,13 @@ public class ShopOrderReturnServiceImpl extends BaseServiceImpl<ShopOrderReturnM
|
||||
|
||||
// 检查是否超过退货期限
|
||||
if (orderDealTime != null && withdrawTime.compareTo(orderDealTime) > 0) {
|
||||
log.debug("[是否禁止退货] 订单已超过退货期限,不允许退货,order_id: {}", orderId);
|
||||
log.debug("[是否禁止退货] 订单已超过退货期限,禁止退货,order_id: {}, orderDealTime: {}, withdrawTime: {}",
|
||||
orderId, orderDealTime, withdrawTime);
|
||||
return true;
|
||||
}
|
||||
} catch (Exception e) {
|
||||
log.error("[是否禁止退货] 检查订单退货期限时发生异常,不允许退货,order_id: {}", orderId, e);
|
||||
log.error("[是否禁止退货] 检查订单退货期限时发生异常,禁止退货,order_id: {}", orderId, e);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
@ -2165,32 +2162,40 @@ public class ShopOrderReturnServiceImpl extends BaseServiceImpl<ShopOrderReturnM
|
||||
if (lklOrderSeparateService != null && lklOrderDrawService != null) {
|
||||
boolean isSeparated = lklOrderSeparateService.isOrderSeparated(orderId);
|
||||
boolean isDrawn = lklOrderDrawService.isOrderDrawed(orderId);
|
||||
boolean isLklProcessed = isSeparated && isDrawn;
|
||||
|
||||
if (isSeparated && isDrawn) {
|
||||
log.debug("[是否禁止退货] 拉卡拉分账订单已提现,不允许退货,order_id: {}", orderId);
|
||||
if (isLklProcessed) {
|
||||
log.debug("[是否禁止退货] 拉卡拉分账订单已提现,禁止退货,order_id: {}, separated: {}, drawed: {}",
|
||||
orderId, isSeparated, isDrawn);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
log.error("[是否禁止退货] 检查拉卡拉分账状态时发生异常,不允许退货,order_id: {}", orderId, e);
|
||||
log.error("[是否禁止退货] 检查拉卡拉分账状态时发生异常,禁止退货,order_id: {}", orderId, e);
|
||||
return true;
|
||||
}
|
||||
|
||||
Long productId = shopOrderItem.getProduct_id();
|
||||
if (CheckUtil.isEmpty(productId)) {
|
||||
log.debug("[是否禁止退货] 商品ID为空,不允许退货");
|
||||
return true;
|
||||
// 如果没有商品相关信息,则只检查订单级别
|
||||
if (shopOrderItem == null && shopProductIndex == null) {
|
||||
log.debug("[是否禁止退货] 无商品信息,仅检查订单级别,允许退货,order_id: {}", orderId);
|
||||
return false;
|
||||
}
|
||||
|
||||
Long productId = null;
|
||||
if (shopOrderItem != null) {
|
||||
productId = shopOrderItem.getProduct_id();
|
||||
}
|
||||
|
||||
// 3. 再判断具体商品是否可以退货(商品级别检查)
|
||||
// 获取商品索引信息
|
||||
ShopProductIndex productIndex = shopProductIndex;
|
||||
if (productIndex == null) {
|
||||
if (productIndex == null && productId != null) {
|
||||
productIndex = shopProductIndexService.get(productId);
|
||||
}
|
||||
|
||||
if (productIndex == null) {
|
||||
log.debug("[是否禁止退货] 商品索引信息不存在,不允许退货,product_id: {}", productId);
|
||||
return true;
|
||||
log.debug("[是否禁止退货] 商品索引信息不存在,允许退货,order_id: {}", orderId);
|
||||
return false;
|
||||
}
|
||||
|
||||
// 3.1 检查商品是否设置了禁止退货标识
|
||||
@ -2199,17 +2204,17 @@ public class ShopOrderReturnServiceImpl extends BaseServiceImpl<ShopOrderReturnM
|
||||
try {
|
||||
List<Integer> contractTypeIds = Convert.toList(Integer.class, contractTypeIdsStr);
|
||||
if (contractTypeIds != null && contractTypeIds.contains(StateCode.CONTRACT_TYPE_DENY_RETURN)) {
|
||||
log.debug("[是否禁止退货] 商品设置了禁止退货标识,不允许退货,order_id: {}, product_id: {}", orderId, productId);
|
||||
log.debug("[是否禁止退货] 商品设置了禁止退货标识,禁止退货,order_id: {}, product_id: {}", orderId, productIndex.getProduct_id());
|
||||
return true;
|
||||
}
|
||||
} catch (Exception e) {
|
||||
log.error("[是否禁止退货] 解析商品保障类型失败,不允许退货,order_id: {}, product_id: {}", orderId, productId, e);
|
||||
return true;
|
||||
log.error("[是否禁止退货] 解析商品保障类型失败,允许退货,order_id: {}, product_id: {}", orderId, productIndex.getProduct_id(), e);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// 默认允许退货
|
||||
log.debug("[是否禁止退货] 允许退货}");
|
||||
log.debug("[是否禁止退货] 商品允许退货,order_id: {}, product_id: {}", orderId, productIndex.getProduct_id());
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -2226,7 +2231,7 @@ public class ShopOrderReturnServiceImpl extends BaseServiceImpl<ShopOrderReturnM
|
||||
* @param productId 商品ID
|
||||
* @return boolean true表示禁止退货,false表示允许退货
|
||||
*/
|
||||
public boolean ifOrderItemDenyReturn(String orderId, Long productId) {
|
||||
public boolean isOrderItemDenyReturn(String orderId, Long productId) {
|
||||
// 复用已有的方法逻辑,避免重复代码
|
||||
return ifDenyReturn(
|
||||
shopOrderInfoService.get(orderId),
|
||||
@ -2235,7 +2240,6 @@ public class ShopOrderReturnServiceImpl extends BaseServiceImpl<ShopOrderReturnM
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 判断订单是否禁止退货
|
||||
*
|
||||
@ -2246,7 +2250,7 @@ public class ShopOrderReturnServiceImpl extends BaseServiceImpl<ShopOrderReturnM
|
||||
public boolean isOrderDenyReturn(String orderId) {
|
||||
// 参数校验
|
||||
if (StrUtil.isBlank(orderId)) {
|
||||
log.warn("[订单是否禁止退货] 订单ID为空,不允许退货,无法判断退货状态");
|
||||
log.debug("[订单是否禁止退货] 订单ID为空,禁止退货,orderId: {}", orderId);
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -2254,20 +2258,20 @@ public class ShopOrderReturnServiceImpl extends BaseServiceImpl<ShopOrderReturnM
|
||||
// 获取订单信息
|
||||
ShopOrderInfo shopOrderInfo = shopOrderInfoService.get(orderId);
|
||||
if (shopOrderInfo == null) {
|
||||
log.error("[订单是否禁止退货] 订单信息不存在,不允许退货,订单ID: {}", orderId);
|
||||
log.debug("[订单是否禁止退货] 订单信息不存在,禁止退货,orderId: {}", orderId);
|
||||
return true;
|
||||
}
|
||||
|
||||
// 检查订单状态是否已收货或已完成
|
||||
Integer orderStateId = shopOrderInfo.getOrder_state_id();
|
||||
if (CheckUtil.isEmpty(orderStateId)) {
|
||||
log.warn("[订单是否禁止退货] 订单状态为空,不允许退货");
|
||||
log.debug("[订单是否禁止退货] 订单状态为空,禁止退货,orderId: {}", orderId);
|
||||
return true;
|
||||
}
|
||||
|
||||
if (orderStateId.intValue() == StateCode.ORDER_STATE_CANCEL ||
|
||||
orderStateId.intValue() == StateCode.ORDER_STATE_WAIT_PAY) {
|
||||
log.debug("[是否禁止退货] 订单已取消或未支付,不允许退货, order_id: {}", orderId);
|
||||
log.debug("[订单是否禁止退货] 订单状态为已取消或未支付,禁止退货,orderId: {}, orderStateId: {}", orderId, orderStateId);
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -2277,27 +2281,32 @@ public class ShopOrderReturnServiceImpl extends BaseServiceImpl<ShopOrderReturnM
|
||||
// 获取可提现时间戳
|
||||
Long withdrawTime = shopOrderBaseService.getWithdrawTime();
|
||||
Long orderDealTime = shopOrderInfo.getOrder_deal_time();
|
||||
log.debug("[订单是否禁止退货] 订单:{} 可提现时间戳: {},确认收货时间:{}", orderId, withdrawTime, orderDealTime);
|
||||
|
||||
// 如果订单成交时间早于可提现时间,说明已过退货期
|
||||
if (orderDealTime != null && withdrawTime.compareTo(orderDealTime) > 0) {
|
||||
log.debug("[订单是否禁止退货] 订单:{} 已过退货期,不允许退货", orderId);
|
||||
log.debug("[订单是否禁止退货] 订单已超过退货期限,禁止退货,orderId: {}, orderDealTime: {}, withdrawTime: {}",
|
||||
orderId, orderDealTime, withdrawTime);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
// 检查拉卡拉分账和提现状态
|
||||
if (lklOrderSeparateService.isOrderSeparated(orderId) &&
|
||||
lklOrderDrawService.isOrderDrawed(orderId)) {
|
||||
log.debug("[订单是否禁止退货] 订单[{}]已提现,不允许退货", orderId);
|
||||
boolean isLklSeparated = lklOrderSeparateService.isOrderSeparated(orderId);
|
||||
boolean isLklDrawed = lklOrderDrawService.isOrderDrawed(orderId);
|
||||
boolean isLklProcessed = isLklSeparated && isLklDrawed;
|
||||
|
||||
if (isLklProcessed) {
|
||||
log.debug("[订单是否禁止退货] 拉卡拉分账订单已提现,禁止退货,orderId: {}, separated: {}, drawed: {}",
|
||||
orderId, isLklSeparated, isLklDrawed);
|
||||
return true;
|
||||
}
|
||||
|
||||
// 默认允许退货
|
||||
// 允许退货
|
||||
log.debug("[订单是否禁止退货] 订单允许退货,orderId: {}", orderId);
|
||||
return false;
|
||||
|
||||
} catch (Exception e) {
|
||||
log.error("[订单是否禁止退货] 查询订单{}退货状态异常,不允许退货", orderId, e);
|
||||
log.error("[订单是否禁止退货] 查询订单退货状态异常,禁止退货,orderId: {}", orderId, e);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
@ -31,16 +31,16 @@ public interface SFExpressApiService {
|
||||
*
|
||||
* @param mchId 商家入驻编号
|
||||
* @param storeId 商家门店ID
|
||||
* @param shopName 店名
|
||||
* @param cityName 城市
|
||||
* @param shopAddress 店铺详细地址
|
||||
* // * @param shopName 店名
|
||||
* // * @param cityName 城市
|
||||
* // * @param shopAddress 店铺详细地址
|
||||
* @param contactName 店铺联系人
|
||||
* @param contactPhone 店铺电话
|
||||
* @param longitude 经度
|
||||
* @param latitude 纬度
|
||||
* @return
|
||||
*/
|
||||
Pair<Boolean, String> createSfExpressShop(Long mchId, Integer storeId, String shopName, String cityName, String shopAddress, String contactName, String contactPhone, String longitude, String latitude);
|
||||
Pair<Boolean, String> createSfExpressShop(Long mchId, Integer storeId, String contactName, String contactPhone, String longitude, String latitude);
|
||||
|
||||
|
||||
/**
|
||||
|
||||
@ -185,42 +185,42 @@ public class SFExpressApiServiceImpl implements SFExpressApiService {
|
||||
return Pair.of(false, "联系人手机号不能为空");
|
||||
}
|
||||
|
||||
AddressParseResultTO addressParseResultTO = AddressUtil.parseAddress(shopMchEntry.getStore_address());
|
||||
// 解析城市名称
|
||||
String cityName = "桂平市"; // 默认城市
|
||||
|
||||
// 去掉省市区的详细地址
|
||||
String storeAddress = addressParseResultTO.getDetailAddress();
|
||||
|
||||
if (StrUtil.isNotBlank(shopMchEntry.getStore_area())) {
|
||||
String[] areaNames = shopMchEntry.getStore_area().split("/");
|
||||
if (areaNames.length >= 3) {
|
||||
cityName = areaNames[areaNames.length - 1];
|
||||
} else {
|
||||
cityName = shopMchEntry.getStore_area().replace("/", "");
|
||||
}
|
||||
} else {
|
||||
cityName = addressParseResultTO.getCity();
|
||||
}
|
||||
|
||||
// 如果解析后城市名为空,使用默认值
|
||||
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());
|
||||
// AddressParseResultTO addressParseResultTO = AddressUtil.parseAddress(shopMchEntry.getStore_address());
|
||||
// // 解析城市名称
|
||||
// String cityName = "桂平市"; // 默认城市
|
||||
//
|
||||
// // 去掉省市区的详细地址
|
||||
// String storeAddress = addressParseResultTO.getDetailAddress();
|
||||
//
|
||||
// if (StrUtil.isNotBlank(shopMchEntry.getStore_area())) {
|
||||
// String[] areaNames = shopMchEntry.getStore_area().split("/");
|
||||
// if (areaNames.length >= 3) {
|
||||
// cityName = areaNames[areaNames.length - 1];
|
||||
// } else {
|
||||
// cityName = shopMchEntry.getStore_area().replace("/", "");
|
||||
// }
|
||||
// } else {
|
||||
// cityName = addressParseResultTO.getCity();
|
||||
// }
|
||||
//
|
||||
// // 如果解析后城市名为空,使用默认值
|
||||
// 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<Boolean, String> result = createSfExpressShop(
|
||||
mchId,
|
||||
Convert.toInt(shopMchEntry.getStore_id()),
|
||||
shopStoreName,
|
||||
cityName,
|
||||
storeAddress,
|
||||
// shopStoreName,
|
||||
// cityName,
|
||||
// storeAddress,
|
||||
shopMchEntry.getContact_name(),
|
||||
contactMobile,
|
||||
shopMchEntry.getStore_longitude(),
|
||||
@ -237,9 +237,6 @@ public class SFExpressApiServiceImpl implements SFExpressApiService {
|
||||
*
|
||||
* @param mchId 商家入驻编号
|
||||
* @param storeId 商家门店ID
|
||||
* @param shopName 店名
|
||||
* @param cityName 城市
|
||||
* @param shopAddress 店铺详细地址
|
||||
* @param contactName 店铺联系人
|
||||
* @param contactPhone 店铺电话
|
||||
* @param longitude 经度
|
||||
@ -247,17 +244,16 @@ public class SFExpressApiServiceImpl implements SFExpressApiService {
|
||||
* @return Pair<Boolean, String> 第一个元素表示是否成功,第二个元素表示结果信息或错误信息
|
||||
*/
|
||||
@Override
|
||||
public Pair<Boolean, String> createSfExpressShop(Long mchId, Integer storeId, String shopName, String cityName,
|
||||
String shopAddress, String contactName, String contactPhone,
|
||||
public Pair<Boolean, String> createSfExpressShop(Long mchId, Integer storeId, String contactName, String contactPhone,
|
||||
String longitude, String latitude) {
|
||||
logger.info("开始创建顺丰同城店铺, storeId: {}", storeId);
|
||||
|
||||
try {
|
||||
// 1. 验证必要参数
|
||||
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);
|
||||
StringUtils.isAnyBlank(contactName, contactPhone)) {
|
||||
logger.error("创建顺丰店铺,缺少必要参数!mchId:{}, storeId:{},contactName:{},contactPhone:{}",
|
||||
mchId, storeId, contactName, contactPhone);
|
||||
return Pair.of(false, "创建顺丰店铺,缺少必要参数!");
|
||||
}
|
||||
|
||||
@ -280,6 +276,29 @@ public class SFExpressApiServiceImpl implements SFExpressApiService {
|
||||
}
|
||||
}
|
||||
|
||||
AddressParseResultTO addressParseResultTO = AddressUtil.parseAddress(shopMchEntry.getStore_address());
|
||||
String cityName = "桂平市";
|
||||
String shopAddress = addressParseResultTO != null ? addressParseResultTO.getDetailAddress() : "";
|
||||
|
||||
if (StrUtil.isNotBlank(shopMchEntry.getStore_area())) {
|
||||
String[] areaNames = shopMchEntry.getStore_area().split("/");
|
||||
cityName = areaNames.length >= 3 ? areaNames[2] :
|
||||
areaNames.length > 0 ? areaNames[areaNames.length - 1] : cityName;
|
||||
} else if (addressParseResultTO != null && StrUtil.isNotBlank(addressParseResultTO.getCity())) {
|
||||
cityName = addressParseResultTO.getCity();
|
||||
}
|
||||
|
||||
if (StrUtil.isBlank(cityName)) {
|
||||
cityName = "桂平市";
|
||||
logger.warn("[顺丰] 城市名为空,使用默认城市: {}", cityName);
|
||||
} else {
|
||||
logger.debug("[顺丰] 解析得到城市名: {}", cityName);
|
||||
}
|
||||
|
||||
// 为了其他顺丰店同名,店铺名称加上[门店ID]; 如:xxxx[xxxx] 聚万家生鲜超市[69]
|
||||
String shopName = String.format("%s[%s]", shopMchEntry.getStore_name(), shopMchEntry.getStore_id());
|
||||
|
||||
|
||||
// 3. 获取或初始化商家配送信息
|
||||
ShopStoreSameCityTransportBase transportBase = shopStoreSameCityTransportBaseService
|
||||
.getShopStoreSameCityTransportBaseById(Long.valueOf(storeId));
|
||||
|
||||
@ -79,5 +79,18 @@ public class ShopStoreInfoController extends BaseControllerImpl {
|
||||
return CommonResult.success(shopStoreInfoService.remove(store_id));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 获取店铺的内部运费 shopping_fee_inner (远程调用用途)
|
||||
*
|
||||
* @param store_id
|
||||
* @return
|
||||
*/
|
||||
@ApiOperation(value = "获取店铺的内部运费 shopping_fee_inner", notes = "获取店铺的内部运费 shopping_fee_inner (远程调用用途)")
|
||||
@RequestMapping(value = "/shopping-fee-inner", method = RequestMethod.POST)
|
||||
public Integer storeShoppingFeeInner(@RequestParam(name = "store_id") Integer store_id) {
|
||||
return shopStoreInfoService.getStoreShippingFeeInner(store_id);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
@ -10,6 +10,7 @@ import com.suisung.mall.core.web.service.IBaseService;
|
||||
import com.suisung.mall.shop.product.pojo.vo.ProductVo;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
@ -57,7 +58,16 @@ public interface ShopStoreActivityBaseService extends IBaseService<ShopStoreActi
|
||||
|
||||
List<Long> getActivityAllItemIds(Map activity_row);
|
||||
|
||||
boolean verifyActivity(Map activity_row);
|
||||
boolean isActivityTimeValid(Map activity_row);
|
||||
|
||||
/**
|
||||
* 验证活动时间是否有效
|
||||
*
|
||||
* @param starTime 活动开始时间
|
||||
* @param endTime 活动结束时间
|
||||
* @return 时间是否有效
|
||||
*/
|
||||
boolean isActivityTimeValid(Date starTime, Date endTime);
|
||||
|
||||
Map listsMarketing();
|
||||
|
||||
@ -169,4 +179,14 @@ public interface ShopStoreActivityBaseService extends IBaseService<ShopStoreActi
|
||||
* @return
|
||||
*/
|
||||
Map getGiftbag(Integer activity_id);
|
||||
|
||||
/**
|
||||
* 判断是否是砍价活动
|
||||
*
|
||||
* @param activity_id
|
||||
* @return
|
||||
*/
|
||||
Boolean isCutPriceActivity(Integer activity_id);
|
||||
|
||||
|
||||
}
|
||||
|
||||
@ -38,4 +38,13 @@ public interface ShopStoreInfoService extends IBaseService<ShopStoreInfo> {
|
||||
*/
|
||||
List<String> getStoreKeeperMobile(Integer storeId);
|
||||
|
||||
/**
|
||||
* 获取店铺的内部运费 shopping_fee_inner
|
||||
* <p>
|
||||
* 店铺内部运费,单位(分)0-使用平台的内部运费;>0 使用店铺的内部运费
|
||||
*
|
||||
* @param storeId
|
||||
* @return
|
||||
*/
|
||||
Integer getStoreShippingFeeInner(Integer storeId);
|
||||
}
|
||||
|
||||
@ -646,27 +646,7 @@ public class ShopMchEntryServiceImpl extends BaseServiceImpl<ShopMchEntryMapper,
|
||||
return;
|
||||
}
|
||||
|
||||
// 这是E签宝的逻辑
|
||||
// if (CommonConstant.MCH_APPR_STA_PASS.equals(record.getApproval_status())
|
||||
// && (StrUtil.isBlank(record.getContract_download_url()) || !CommonConstant.CONTRACT_SIGN_STA_FINISH.equals(record.getSigned_status()))) {
|
||||
// // 审核通过的,但是没有合同文件的情况,要进一步同步状态和合同文件
|
||||
// Pair<Integer, String> contractInfo = esignContractService.checkSignFlowStatus(record.getLogin_mobile());
|
||||
// if (contractInfo != null) {
|
||||
// record.setSigned_status(contractInfo.getFirst());
|
||||
// record.setContract_download_url(contractInfo.getSecond());
|
||||
//
|
||||
// // 更改同步合同审核状态和合同下载地址
|
||||
// taskService.executeTask(() -> {
|
||||
// log.debug("###更改同步合同审核状态和下载地址###");
|
||||
// if (!updateMerchEntrySignedStatusAndContractDownloadUrl(record.getLogin_mobile(), record.getSigned_status(), record.getContract_download_url())) {
|
||||
// log.error("###更改同步合同审核状态和下载地址失败###");
|
||||
// }
|
||||
// });
|
||||
// }
|
||||
// }
|
||||
|
||||
// === 拉卡拉签约逻辑 ===
|
||||
|
||||
Long mchId = record.getId();
|
||||
if (CommonConstant.Enable.equals(record.getHas_ec_signed())) {
|
||||
LklLedgerEc ec = lklLedgerEcService.getByMchId(
|
||||
@ -830,7 +810,7 @@ public class ShopMchEntryServiceImpl extends BaseServiceImpl<ShopMchEntryMapper,
|
||||
&& CommonConstant.Enable.equals(shopMchEntry.getHas_bind_receiver());
|
||||
|
||||
if (!isValidStatus) {
|
||||
log.debug("入驻记录状态未全部通过审核,不能创建店铺,入驻ID: {}", mchId);
|
||||
log.error("入驻记录状态未全部通过审核,不能创建店铺,入驻ID: {}", mchId);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@ -36,7 +36,10 @@ import com.suisung.mall.common.modules.product.ShopProductItem;
|
||||
import com.suisung.mall.common.modules.store.ShopStoreActivityBase;
|
||||
import com.suisung.mall.common.modules.store.ShopStoreActivityItem;
|
||||
import com.suisung.mall.common.modules.store.ShopStoreBase;
|
||||
import com.suisung.mall.common.utils.*;
|
||||
import com.suisung.mall.common.utils.CheckUtil;
|
||||
import com.suisung.mall.common.utils.I18nUtil;
|
||||
import com.suisung.mall.common.utils.StringUtils;
|
||||
import com.suisung.mall.common.utils.UserInfoService;
|
||||
import com.suisung.mall.core.web.service.RedisService;
|
||||
import com.suisung.mall.core.web.service.impl.BaseServiceImpl;
|
||||
import com.suisung.mall.shop.activity.service.*;
|
||||
@ -2046,13 +2049,51 @@ public class ShopStoreActivityBaseServiceImpl extends BaseServiceImpl<ShopStoreA
|
||||
return item_id_row;
|
||||
}
|
||||
|
||||
public boolean verifyActivity(Map activity_row) {
|
||||
if (CollUtil.isNotEmpty(activity_row)) {
|
||||
Date beginMillisecond = Convert.toDate(activity_row.get("activity_starttime"));
|
||||
Date endMillisecond = Convert.toDate(activity_row.get("activity_endtime"));
|
||||
return RegexUtil.isWithinTimeRange(beginMillisecond, endMillisecond);
|
||||
/**
|
||||
* 验证活动时间是否有效
|
||||
*
|
||||
* @param activityRow 活动数据
|
||||
* @return 时间是否有效
|
||||
*/
|
||||
@Override
|
||||
public boolean isActivityTimeValid(Map activityRow) {
|
||||
if (CollUtil.isEmpty(activityRow)) {
|
||||
return false;
|
||||
}
|
||||
return false;
|
||||
|
||||
Object startTimeObj = activityRow.get("activity_starttime");
|
||||
Object endTimeObj = activityRow.get("activity_endtime");
|
||||
|
||||
if (startTimeObj == null || endTimeObj == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
Date startTime = Convert.toDate(startTimeObj);
|
||||
Date endTime = Convert.toDate(endTimeObj);
|
||||
|
||||
if (startTime == null || endTime == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
Date now = new Date();
|
||||
return !now.before(startTime) && !now.after(endTime);
|
||||
}
|
||||
|
||||
/**
|
||||
* 验证活动时间是否有效
|
||||
*
|
||||
* @param starTime 活动开始时间
|
||||
* @param endTime 活动结束时间
|
||||
* @return 时间是否有效
|
||||
*/
|
||||
@Override
|
||||
public boolean isActivityTimeValid(Date starTime, Date endTime) {
|
||||
if (starTime == null || endTime == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
Date now = new Date();
|
||||
return !now.before(starTime) && !now.after(endTime);
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -2534,9 +2575,9 @@ public class ShopStoreActivityBaseServiceImpl extends BaseServiceImpl<ShopStoreA
|
||||
|
||||
|
||||
ShopStoreActivityBase one = shopStoreActivityBaseService.get(activity_id);
|
||||
Map activity_row = Convert.toMap(Object.class, Object.class, one);
|
||||
/* Map activity_row = Convert.toMap(Object.class, Object.class, one);
|
||||
|
||||
/*if (!verifyActivity(activity_row)) {
|
||||
if (!verifyActivity(activity_row)) {
|
||||
Map data = new HashMap();
|
||||
data.put("msg", I18nUtil._("该砍价活动不存在"));
|
||||
return data;
|
||||
@ -3960,43 +4001,68 @@ public class ShopStoreActivityBaseServiceImpl extends BaseServiceImpl<ShopStoreA
|
||||
return item_row;
|
||||
}
|
||||
|
||||
/**
|
||||
* 计算砍价活动中每次砍价的价格
|
||||
*
|
||||
* @param activity_row 活动基础信息
|
||||
* @param ac_row 砍价活动记录
|
||||
* @return 砍价金额
|
||||
*/
|
||||
@Override
|
||||
public BigDecimal getCutDownPrice(ShopStoreActivityBase activity_row, ShopActivityCutprice ac_row) {
|
||||
// 1. 参数校验
|
||||
if (activity_row == null || ac_row == null) {
|
||||
throw new ApiException(I18nUtil._("活动不存在!"));
|
||||
}
|
||||
|
||||
// 2. 活动类型校验
|
||||
Integer activity_type_id = activity_row.getActivity_type_id();
|
||||
if (ObjectUtil.notEqual(StateCode.ACTIVITY_TYPE_CUTPRICE, activity_type_id)) {
|
||||
throw new ApiException(I18nUtil._("活动不存在!"));
|
||||
}
|
||||
|
||||
BigDecimal price = BigDecimal.ZERO;
|
||||
BigDecimal price;
|
||||
|
||||
// 3. 解析活动规则
|
||||
String str_activity_rule = activity_row.getActivity_rule();
|
||||
JSONObject activity_rule = JSONObject.parseObject(str_activity_rule);
|
||||
Integer cut_down_type = activity_rule.getObject("cut_down_type", Integer.class);
|
||||
BigDecimal ac_sale_price = ac_row.getAc_sale_price();
|
||||
BigDecimal ac_mix_limit_price = ac_row.getAc_mix_limit_price();
|
||||
|
||||
// 4. 根据砍价类型计算砍价金额
|
||||
switch (cut_down_type) {
|
||||
case 1:
|
||||
// 固定金额砍价
|
||||
price = activity_rule.getObject("cut_down_fixed_price", BigDecimal.class);
|
||||
break;
|
||||
case 2:
|
||||
// 随机金额砍价
|
||||
BigDecimal cut_down_min_limit_price = activity_rule.getObject("cut_down_min_limit_price", BigDecimal.class);
|
||||
Integer cut_down_user_num = activity_rule.getObject("cut_down_user_num", Integer.class);
|
||||
Integer ac_num = ac_row.getAc_num();
|
||||
List<Integer> arr = randMoney(NumberUtil.sub(ac_sale_price, cut_down_min_limit_price), cut_down_user_num - ac_num);
|
||||
|
||||
Integer randPrice = arr.size() == 1 ? arr.get(0) : arr.get(RandomUtil.randomInt(0, arr.size() - 1));
|
||||
// 计算剩余可砍价金额和剩余次数
|
||||
List<Integer> arr = randMoney(
|
||||
NumberUtil.sub(ac_sale_price, cut_down_min_limit_price),
|
||||
cut_down_user_num - ac_num
|
||||
);
|
||||
|
||||
// 随机选择一个砍价金额
|
||||
Integer randPrice = arr.size() == 1 ? arr.get(0) : arr.get(RandomUtil.randomInt(0, arr.size()));
|
||||
price = NumberUtil.div(BigDecimal.valueOf(randPrice), 100, 2);
|
||||
break;
|
||||
default:
|
||||
// 未知砍价类型,返回0
|
||||
price = BigDecimal.ZERO;
|
||||
break;
|
||||
}
|
||||
|
||||
// 5. 返回砍价金额,不超过可砍价的上限
|
||||
return NumberUtil.min(NumberUtil.sub(ac_sale_price, ac_mix_limit_price), price);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public List<ShopStoreActivityBase> getCouponsList(Integer activity_type_id) {
|
||||
QueryWrapper<ShopStoreActivityBase> wrapper = new QueryWrapper<>();
|
||||
@ -4310,6 +4376,33 @@ public class ShopStoreActivityBaseServiceImpl extends BaseServiceImpl<ShopStoreA
|
||||
return data;
|
||||
}
|
||||
|
||||
/**
|
||||
* 判断是否是砍价活动
|
||||
*
|
||||
* @param activity_id 活动ID
|
||||
* @return 是否为砍价活动
|
||||
*/
|
||||
@Override
|
||||
public Boolean isCutPriceActivity(Integer activity_id) {
|
||||
// 参数校验
|
||||
if (activity_id == null || activity_id <= 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
try {
|
||||
// 使用exists查询优化性能,只判断是否存在而不加载数据
|
||||
QueryWrapper<ShopStoreActivityBase> queryWrapper = new QueryWrapper<>();
|
||||
queryWrapper.eq("activity_id", activity_id);
|
||||
queryWrapper.eq("activity_type_id", StateCode.ACTIVITY_TYPE_CUTPRICE);
|
||||
return shopStoreActivityBaseMapper.selectCount(queryWrapper) > 0;
|
||||
} catch (Exception e) {
|
||||
// 异常处理,防止影响主流程
|
||||
logger.error("判断是否为砍价活动时发生异常,activity_id={}", activity_id, e);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Transactional
|
||||
public boolean removeActivityBase(Integer activity_id, ShopStoreActivityBase activity_row) {
|
||||
|
||||
|
||||
@ -3430,15 +3430,14 @@ public class ShopStoreBaseServiceImpl extends BaseServiceImpl<ShopStoreBaseMappe
|
||||
shopMchEntryService.updateMerchEntryStoreStatus(shopMchEntry.getId(), storeId);
|
||||
}
|
||||
|
||||
// 创建顺丰店铺(修复经纬度参数错误)
|
||||
if (storeArea != null) {
|
||||
String[] areaNames = storeArea.split("/");
|
||||
String cityName = areaNames.length > 0 ? areaNames[areaNames.length - 1] : storeArea.replace("/", "");
|
||||
// 创建顺丰店铺
|
||||
// if (storeArea != null) {
|
||||
// String[] areaNames = storeArea.split("/");
|
||||
// String cityName = areaNames.length > 0 ? areaNames[areaNames.length - 1] : storeArea.replace("/", "");
|
||||
|
||||
sfExpressApiService.createSfExpressShop(mchId, storeId, shopMchEntry.getStore_name(),
|
||||
cityName, shopMchEntry.getStore_address(), shopMchEntry.getContact_name(),
|
||||
contact_mobile, shopMchEntry.getStore_longitude(), shopMchEntry.getStore_latitude());
|
||||
}
|
||||
sfExpressApiService.createSfExpressShop(mchId, storeId, shopMchEntry.getContact_name(),
|
||||
contact_mobile, shopMchEntry.getStore_longitude(), shopMchEntry.getStore_latitude());
|
||||
// }
|
||||
|
||||
return Pair.of(storeId, "新增成功");
|
||||
} catch (Exception e) {
|
||||
|
||||
@ -8,19 +8,18 @@ import com.suisung.mall.common.feignService.AccountService;
|
||||
import com.suisung.mall.common.modules.account.AccountUserBase;
|
||||
import com.suisung.mall.common.modules.store.ShopStoreAnalytics;
|
||||
import com.suisung.mall.common.modules.store.ShopStoreInfo;
|
||||
import com.suisung.mall.common.utils.CheckUtil;
|
||||
import com.suisung.mall.core.web.service.impl.BaseServiceImpl;
|
||||
import com.suisung.mall.shop.store.mapper.ShopStoreInfoMapper;
|
||||
import com.suisung.mall.shop.store.service.ShopStoreAnalyticsService;
|
||||
import com.suisung.mall.shop.store.service.ShopStoreBaseService;
|
||||
import com.suisung.mall.shop.store.service.ShopStoreInfoService;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.context.annotation.Lazy;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
|
||||
@ -32,6 +31,7 @@ import java.util.stream.Collectors;
|
||||
* @author Xinze
|
||||
* @since 2021-06-16
|
||||
*/
|
||||
@Slf4j
|
||||
@Service
|
||||
public class ShopStoreInfoServiceImpl extends BaseServiceImpl<ShopStoreInfoMapper, ShopStoreInfo> implements ShopStoreInfoService {
|
||||
|
||||
@ -101,15 +101,64 @@ public class ShopStoreInfoServiceImpl extends BaseServiceImpl<ShopStoreInfoMappe
|
||||
/**
|
||||
* 获取店长的手机号码
|
||||
*
|
||||
* @param storeId
|
||||
* @return
|
||||
* @param storeId 店铺ID
|
||||
* @return 手机号码列表,如果未找到则返回null
|
||||
*/
|
||||
@Override
|
||||
public List<String> getStoreKeeperMobile(Integer storeId) {
|
||||
// 参数校验
|
||||
if (storeId == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
QueryWrapper<ShopStoreInfo> queryWrapper = new QueryWrapper<>();
|
||||
queryWrapper.eq("store_id", storeId).select("store_tel");
|
||||
return null;
|
||||
List<ShopStoreInfo> list = find(queryWrapper);
|
||||
|
||||
// 空值检查优化
|
||||
if (list == null || list.isEmpty()) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// 使用方法引用简化代码
|
||||
return list.stream()
|
||||
.map(ShopStoreInfo::getStore_tel)
|
||||
.filter(Objects::nonNull) // 过滤掉null值
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 获取店铺的内部运费 shopping_fee_inner
|
||||
* <p>
|
||||
* 店铺内部运费,单位(分)0-使用平台的内部运费;>0 使用店铺的内部运费
|
||||
*
|
||||
* @param storeId 店铺ID
|
||||
* @return 内部运费,单位分
|
||||
*/
|
||||
@Override
|
||||
public Integer getStoreShippingFeeInner(Integer storeId) {
|
||||
// 参数校验
|
||||
if (storeId == null) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
try {
|
||||
QueryWrapper<ShopStoreInfo> queryWrapper = new QueryWrapper<>();
|
||||
queryWrapper.eq("store_id", storeId).select("shopping_fee_inner");
|
||||
ShopStoreInfo shopStoreInfo = getOne(queryWrapper);
|
||||
|
||||
if (shopStoreInfo == null || CheckUtil.isEmpty(shopStoreInfo.getShopping_fee_inner())) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return shopStoreInfo.getShopping_fee_inner();
|
||||
} catch (Exception e) {
|
||||
// 记录日志或打印错误信息
|
||||
log.error("获取店铺内部运费失败,storeId: {}", storeId, e);
|
||||
// 返回默认值,避免影响主流程
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -39,7 +39,7 @@ public interface ShopUserVoucherService extends IBaseService<ShopUserVoucher> {
|
||||
|
||||
Map getLists(QueryWrapper<ShopUserVoucher> voucherQueryWrapper, int page, int rows);
|
||||
|
||||
boolean useNeedNotPin(Integer user_id, String order_id);
|
||||
boolean tryUseFreeGroupVoucher(Integer user_id, String order_id);
|
||||
|
||||
// 线下优惠券核销
|
||||
boolean exitWriteoffUserVoucher(ShopUserVoucher shopUserVoucher);
|
||||
|
||||
@ -2670,7 +2670,7 @@ public class ShopUserCartServiceImpl extends BaseServiceImpl<ShopUserCartMapper,
|
||||
}
|
||||
|
||||
// RMK 平台最低配送费,单位(分)add:2025-09-26
|
||||
Integer innerMinDeliverFee = accountBaseConfigService.getInnerMinDeliveryFee();
|
||||
Integer innerMinDeliverFee = accountBaseConfigService.getInnerMinDeliveryFee(Convert.toInt(storeId));
|
||||
if (canThrow
|
||||
&& CheckUtil.isNotEmpty(innerMinDeliverFee)
|
||||
&& CheckUtil.isNotEmpty(orderSelMoneyAmount)
|
||||
|
||||
@ -65,7 +65,7 @@ public class ShopUserVoucherServiceImpl extends BaseServiceImpl<ShopUserVoucherM
|
||||
@Lazy
|
||||
@Autowired
|
||||
private ShopStoreActivityBaseService storeActivityBaseService;
|
||||
|
||||
|
||||
@Lazy
|
||||
@Autowired
|
||||
private ShopStoreBaseService shopStoreBaseService;
|
||||
@ -331,17 +331,20 @@ public class ShopUserVoucherServiceImpl extends BaseServiceImpl<ShopUserVoucherM
|
||||
}
|
||||
|
||||
/**
|
||||
* 用户使用免拼券
|
||||
* 用户是否使用了免拼券
|
||||
*
|
||||
* @param user_id
|
||||
* @param order_id
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public boolean useNeedNotPin(Integer user_id, String order_id) {
|
||||
public boolean tryUseFreeGroupVoucher(Integer user_id, String order_id) {
|
||||
Date date = new Date();
|
||||
QueryWrapper<ShopUserVoucher> queryWrapper = new QueryWrapper<>();
|
||||
queryWrapper.eq("voucher_type", 1).eq("user_id", user_id).eq("voucher_state_id", StateCode.VOUCHER_STATE_UNUSED).ge("voucher_end_date", date);
|
||||
queryWrapper.eq("voucher_type", 1)
|
||||
.eq("user_id", user_id)
|
||||
.eq("voucher_state_id", StateCode.VOUCHER_STATE_UNUSED)
|
||||
.ge("voucher_end_date", date);
|
||||
ShopUserVoucher user_voucher_row = findOne(queryWrapper);
|
||||
|
||||
if (user_voucher_row != null) {
|
||||
|
||||
@ -20686,7 +20686,7 @@
|
||||
14 == t[_x41903[4420]] && t[_x41903[124]] == a && publicFun[_x41903[4586]]($(n[_x41903[476]])[_x41903[217]](_x41903[124]), function(e) {
|
||||
250 == e[_x41903[686]] && $[_x41903[2030]][_x41903[4089]](e[_x41903[4587]] || __(_x41903[4592])),
|
||||
t[_x41903[4594]][_x41903[4593]] = e[_x41903[473]][_x41903[688]],
|
||||
c(), s = r = o = 100;
|
||||
c(), s = r = o = 10240;
|
||||
}, s, o, r);
|
||||
}) : 5 == e && $[_x41903[39]](l[_x41903[820]], function(e, t) {
|
||||
15 == t[_x41903[4420]] && t[_x41903[124]] == a && publicFun[_x41903[4586]]($(n[_x41903[476]])[_x41903[217]](_x41903[124]), function(e) {
|
||||
@ -20700,39 +20700,39 @@
|
||||
if (i[_x41903[124]] == $(n[_x41903[476]])[_x41903[217]](_x41903[4584])) {
|
||||
switch (parseInt(i[_x41903[4488]][_x41903[4596]])) {
|
||||
case 1:
|
||||
r = o = 750, s = 300;
|
||||
r = o = 750, s = 10240;
|
||||
break;
|
||||
|
||||
case 2:
|
||||
o = 750, r = 375, s = 300;
|
||||
o = 750, r = 375, s = 10240;
|
||||
break;
|
||||
|
||||
case 3:
|
||||
o = 375, r = 750, s = 300;
|
||||
o = 375, r = 750, s = 10240;
|
||||
break;
|
||||
|
||||
case 4:
|
||||
o = 750, r = 188, s = 300;
|
||||
o = 750, r = 188, s = 10240;
|
||||
break;
|
||||
|
||||
case 5:
|
||||
r = o = 375, s = 300;
|
||||
r = o = 375, s = 10240;
|
||||
break;
|
||||
|
||||
case 6:
|
||||
o = 375, r = 188, s = 300;
|
||||
o = 375, r = 188, s = 10240;
|
||||
break;
|
||||
|
||||
case 7:
|
||||
o = 188, r = 375, s = 300;
|
||||
o = 188, r = 375, s = 10240;
|
||||
break;
|
||||
|
||||
case 8:
|
||||
r = o = 188, s = 300;
|
||||
r = o = 188, s = 10240;
|
||||
break;
|
||||
|
||||
case 9:
|
||||
o = 750, r = 500, s = 300;
|
||||
o = 750, r = 500, s = 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[4597])),
|
||||
@ -20750,19 +20750,19 @@
|
||||
if (t[_x41903[124]] == $(n[_x41903[476]])[_x41903[217]](_x41903[4584])) {
|
||||
switch (parseInt(i[_x41903[4600]][_x41903[4601]])) {
|
||||
case 1:
|
||||
r = o = 350, s = 200;
|
||||
r = o = 350, s = 10240;
|
||||
break;
|
||||
|
||||
case 2:
|
||||
r = o = 180, s = 200;
|
||||
r = o = 180, s = 10240;
|
||||
break;
|
||||
|
||||
case 3:
|
||||
o = 355, r = 166, s = 200;
|
||||
o = 355, r = 166, s = 10240;
|
||||
break;
|
||||
|
||||
case 4:
|
||||
r = o = 140, s = 150;
|
||||
r = o = 140, s = 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[4602])),
|
||||
@ -20791,13 +20791,13 @@
|
||||
i[_x41903[4612]][_x41903[4611]] = e[_x41903[473]][_x41903[688]],
|
||||
c();
|
||||
}, 1e3, 700, 700) : 14 == i[_x41903[4420]] ? $[_x41903[39]](i[_x41903[4594]][_x41903[473]], function(e, t) {
|
||||
t[_x41903[124]] == $(n[_x41903[476]])[_x41903[217]](_x41903[4584]) && (s = r = o = 100,
|
||||
t[_x41903[124]] == $(n[_x41903[476]])[_x41903[217]](_x41903[4584]) && (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[4613])),
|
||||
t[_x41903[2345]] = e[_x41903[473]][_x41903[688]],
|
||||
c();
|
||||
}, s, o, r));
|
||||
}) : 15 == i[_x41903[4420]] ? i[_x41903[4478]][_x41903[473]][_x41903[124]] == a && (s = r = o = 100,
|
||||
}) : 15 == i[_x41903[4420]] ? i[_x41903[4478]][_x41903[473]][_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[4614])),
|
||||
i[_x41903[4478]][_x41903[473]][_x41903[2345]] = e[_x41903[473]][_x41903[688]],
|
||||
@ -20820,11 +20820,11 @@
|
||||
250 == e[_x41903[686]] && $[_x41903[2030]][_x41903[4089]](e[_x41903[4587]] || __(_x41903[4619])),
|
||||
t[_x41903[4555]] = e[_x41903[473]][_x41903[688]],
|
||||
c();
|
||||
}, 40) : e + 12 == $(n[_x41903[476]])[_x41903[217]](_x41903[4584]) && publicFun[_x41903[4586]]($(n[_x41903[476]])[_x41903[217]](_x41903[124]), function(e) {
|
||||
}, 10240) : e + 12 == $(n[_x41903[476]])[_x41903[217]](_x41903[4584]) && publicFun[_x41903[4586]]($(n[_x41903[476]])[_x41903[217]](_x41903[124]), function(e) {
|
||||
250 == e[_x41903[686]] && $[_x41903[2030]][_x41903[4089]](e[_x41903[4587]] || __(_x41903[4620])),
|
||||
t[_x41903[4556]] = e[_x41903[473]][_x41903[688]],
|
||||
c();
|
||||
}, 40);
|
||||
}, 10240);
|
||||
}), _x41903[4621] == $(n[_x41903[476]])[_x41903[217]](_x41903[4584]) && publicFun[_x41903[4586]]($(n[_x41903[476]])[_x41903[217]](_x41903[4584]), function(e) {
|
||||
250 == e[_x41903[686]] && $[_x41903[2030]][_x41903[4089]](e[_x41903[4587]] || __(_x41903[4622])),
|
||||
l[_x41903[4458]][_x41903[4623]][_x41903[2345]] = e[_x41903[473]][_x41903[688]],
|
||||
|
||||
File diff suppressed because one or more lines are too long
@ -20,16 +20,16 @@
|
||||
<L>可口可乐CocaC</L> <L><BOLD> x110 </BOLD></L><L> 8100.45</L><BR>
|
||||
<L>ola经典美味汽水1.2</L><BR>
|
||||
<L>5L/瓶</L><BR>
|
||||
<BOLD>6970448170051</BOLD><BR>
|
||||
<BOLD>6970448170051</BOLD><BR><BR>
|
||||
<L>排骨约350g(默 </L><L><BOLD> 1 </BOLD></L><L> 150.13 </L><BR>
|
||||
<L>认砍小块)</L><BR>
|
||||
<BOLD>6970448170053</BOLD><BR>
|
||||
<BOLD>6970448170053</BOLD><BR><BR>
|
||||
<L>新鲜虫草花1包约2 </L><L><BOLD> x11 </BOLD></L><L> 4.01 </L><BR>
|
||||
<L>00g 韭菜1000g 鸡蛋</L><BR>
|
||||
<L>2003克</L><BR>
|
||||
<BOLD>6970448170054</BOLD><BR>
|
||||
<BOLD>6970448170054</BOLD><BR><BR>
|
||||
<L>冰红茶风味饮料 <L><BOLD> 1 </BOLD></L><L> 13.24 </L></L><BR>
|
||||
<BOLD>6970448170055</BOLD><BR>
|
||||
<BOLD>6970448170055</BOLD><BR><BR>
|
||||
--------------------------------<BR>
|
||||
商品总件数:<BOLD>3</BOLD><BR>
|
||||
商品总额:<BOLD>¥18.7</BOLD><BR>
|
||||
@ -61,4 +61,4 @@
|
||||
<CB>${store_name}</CB><BR>--------------------------------<BR><CB>#${order_pickup_num_str}</CB><BR><L>买家备注:${order_message!'-'}</L><BR><BOLD>配送时间:${payment_time?string('MM-dd HH:mm')}~${delivery_time?string('HH:mm')}</BOLD><BR>--------------------------------<BR>订单编号:${order_id}<BR>订单来源:微信小程序<BR>支付方式:微信支付<BR>配送来源:顺丰同城<BR>付款时间:${payment_time?string('yyyy-MM-dd HH:mm:ss')}<BR>--------------------------------<BR><L>商品名称 数量 金额</L><BR>--------------------------------<BR><#list order_items as item><L>${item.s_name}</L><L><BOLD>${item.s_quantity}</BOLD></L><L>${item.s_amount}</L><BR><#if item.s_name_segs??><#list item.s_name_segs as seg><L>${seg}</L><BR></#list></#if><BOLD><#if item.product_sn?default("")?trim?length gt 1>${item.product_sn}</BOLD><BR></#if></#list>--------------------------------<BR>商品总件数:<BOLD>${order_items_count!0}</BOLD><BR>商品总额:<BOLD>¥${order_product_amount?string('0.00')}</BOLD><BR>运费:<BOLD>¥${order_shipping_fee?string('0.00')}</BOLD><BR><#if packing_fee?? && (packing_fee > 0)>打包费:<BOLD>¥${packing_fee?string('0.00')}</BOLD><BR></#if>优惠金额:<BOLD>-¥${(quanyi!0)?string('0.00')}</BOLD><BR>实付金额:<BOLD>¥${order_payment_amount?string('0.00')}</BOLD><BR><#if seller_message?default("")?trim?length gt 1>--------------------------------<BR><BOLD>商家备注:${seller_message!'-'}</BOLD><BR></#if>--------------------------------<BR><BOLD>收货人:${buyer_user_name!''}</BOLD><BR><BOLD>收货人手机:${da_mobile!'-'}</BOLD><BR><BOLD>收货地址:${da_province!'-'}${da_city!'-'}${da_address!'-'}</BOLD><BR>--------------------------------<BR>门店:${store_name}<BR>门店电话:<BOLD>${store_tel!'-'}</BOLD><BR>收银员:${cashier!'店长'}<BR>
|
||||
|
||||
第三版带变量的模版(有预约订单)
|
||||
<CB>${store_name}</CB><BR><#if is_booking_order><CB><B>预约订单</B></CB><BR></#if>--------------------------------<BR><CB>#${order_pickup_num_str}</CB><BR><L>买家备注:${order_message!'-'}</L><BR><BOLD>配送时间:${payment_time?string('MM-dd HH:mm')}~${delivery_time?string('HH:mm')}</BOLD><BR>--------------------------------<BR>订单编号:${order_id}<BR>订单来源:微信小程序<BR>支付方式:微信支付<BR>配送来源:顺丰同城<BR>付款时间:${payment_time?string('yyyy-MM-dd HH:mm:ss')}<BR>--------------------------------<BR><L>商品名称 数量 金额</L><BR>--------------------------------<BR><#list order_items as item><L>${item.s_name}</L><L><BOLD>${item.s_quantity}</BOLD></L><L>${item.s_amount}</L><BR><#if item.s_name_segs??><#list item.s_name_segs as seg><L>${seg}</L><BR></#list></#if><BOLD><#if item.product_sn?default("")?trim?length gt 1>${item.product_sn}</BOLD><BR></#if></#list>--------------------------------<BR>商品总件数:<BOLD>${order_items_count!0}</BOLD><BR>商品总额:<BOLD>¥${order_product_amount?string('0.00')}</BOLD><BR>运费:<BOLD>¥${order_shipping_fee?string('0.00')}</BOLD><BR><#if packing_fee?? && (packing_fee > 0)>打包费:<BOLD>¥${packing_fee?string('0.00')}</BOLD><BR></#if>优惠金额:<BOLD>-¥${(quanyi!0)?string('0.00')}</BOLD><BR>实付金额:<BOLD>¥${order_payment_amount?string('0.00')}</BOLD><BR><#if seller_message?default("")?trim?length gt 1>--------------------------------<BR><BOLD>商家备注:${seller_message!'-'}</BOLD><BR></#if>--------------------------------<BR><BOLD>收货人:${buyer_user_name!''}</BOLD><BR><BOLD>收货人手机:${da_mobile!'-'}</BOLD><BR><BOLD>收货地址:${da_province!'-'}${da_city!'-'}${da_address!'-'}</BOLD><BR>--------------------------------<BR>门店:${store_name}<BR>门店电话:<BOLD>${store_tel!'-'}</BOLD><BR>收银员:${cashier!'店长'}<BR>
|
||||
<#if is_booking_order><CB><B>【预约订单】<BR></B></CB></#if><CB>${store_name}</CB><BR>--------------------------------<BR><CB>#${order_pickup_num_str}</CB><BR><L>买家备注:${order_message!'-'}</L><BR><BOLD>配送时间:${payment_time?string('MM-dd HH:mm')}~${delivery_time?string('HH:mm')}</BOLD><BR>--------------------------------<BR>订单编号:${order_id}<BR>订单来源:微信小程序<BR>支付方式:微信支付<BR>配送来源:顺丰同城<BR>付款时间:${payment_time?string('yyyy-MM-dd HH:mm:ss')}<BR>--------------------------------<BR><L>商品名称 数量 金额</L><BR>--------------------------------<BR><#list order_items as item><L>${item.s_name}</L><L><BOLD>${item.s_quantity}</BOLD></L><L>${item.s_amount}</L><BR><#if item.s_name_segs??><#list item.s_name_segs as seg><L>${seg}</L><BR></#list></#if><BOLD><#if item.product_sn?default("")?trim?length gt 1>${item.product_sn}</BOLD><BR></#if><BR></#list>--------------------------------<BR>商品总件数:<BOLD>${order_items_count!0}</BOLD><BR>商品总额:<BOLD>¥${order_product_amount?string('0.00')}</BOLD><BR>运费:<BOLD>¥${order_shipping_fee?string('0.00')}</BOLD><BR><#if packing_fee?? && (packing_fee > 0)>打包费:<BOLD>¥${packing_fee?string('0.00')}</BOLD><BR></#if>优惠金额:<BOLD>-¥${(quanyi!0)?string('0.00')}</BOLD><BR>实付金额:<BOLD>¥${order_payment_amount?string('0.00')}</BOLD><BR><#if seller_message?default("")?trim?length gt 1>--------------------------------<BR><BOLD>商家备注:${seller_message!'-'}</BOLD><BR></#if>--------------------------------<BR><BOLD>收货人:${buyer_user_name!''}</BOLD><BR><BOLD>收货人手机:${da_mobile!'-'}</BOLD><BR><BOLD>收货地址:${da_province!'-'}${da_city!'-'}${da_address!'-'}</BOLD><BR>--------------------------------<BR>门店:${store_name}<BR>门店电话:<BOLD>${store_tel!'-'}</BOLD><BR>收银员:${cashier!'店长'}<BR>
|
||||
24
pom.xml
24
pom.xml
@ -306,6 +306,7 @@
|
||||
<spring.profile>local</spring.profile>
|
||||
<!-- Docker 远程管理地址全局-->
|
||||
<docker.host>https://114.132.210.208:2375</docker.host>
|
||||
<docker.registry>10.1.8.3:5000</docker.registry>
|
||||
<docker.ca>/Users/panjunjie/code/docker_registry_ca_dev</docker.ca>
|
||||
<!-- nacos配置 -->
|
||||
<nacos.server.address>114.132.210.208:8848</nacos.server.address>
|
||||
@ -363,6 +364,7 @@
|
||||
<spring.profile>dev</spring.profile>
|
||||
<!-- Docker 远程管理地址全局-->
|
||||
<docker.host>https://114.132.210.208:2375</docker.host>
|
||||
<docker.registry>10.1.8.3:5000</docker.registry>
|
||||
<docker.ca>/Users/panjunjie/code/docker_registry_ca_dev</docker.ca>
|
||||
<!-- nacos配置 -->
|
||||
<nacos.server.address>114.132.210.208:8848</nacos.server.address>
|
||||
@ -414,6 +416,7 @@
|
||||
<spring.profile>test</spring.profile>
|
||||
<!-- Docker 远程管理地址全局-->
|
||||
<docker.host>https://114.132.210.208:2375</docker.host>
|
||||
<docker.registry>10.1.8.3:5000</docker.registry>
|
||||
<docker.ca>/Users/panjunjie/code/docker_registry_ca_dev</docker.ca>
|
||||
<!-- nacos配置 -->
|
||||
<nacos.server.address>10.1.8.3:8848</nacos.server.address>
|
||||
@ -465,6 +468,7 @@
|
||||
<spring.profile>prod</spring.profile>
|
||||
<!-- Docker 远程管理地址全局-->
|
||||
<docker.host>https://159.75.249.163:2275</docker.host>
|
||||
<docker.registry>172.16.0.11:5000</docker.registry>
|
||||
<docker.ca>/Users/panjunjie/code/docker_registry_ca_prod</docker.ca>
|
||||
<!-- nacos配置 -->
|
||||
<nacos.server.address>172.16.0.11:8848</nacos.server.address>
|
||||
@ -552,20 +556,30 @@
|
||||
</executions>
|
||||
<configuration>
|
||||
<!--定义镜像名称-->
|
||||
<imageName>mall/${project.artifactId}:${project.version}</imageName>
|
||||
<!-- <imageName>mall/${project.artifactId}:${project.version}</imageName>-->
|
||||
<!-- <!– Docker 远程管理地址–>-->
|
||||
<!-- <dockerHost>${docker.host}</dockerHost>-->
|
||||
|
||||
<imageName>${docker.registry}/mall/${project.artifactId}:${project.version}</imageName>
|
||||
<!-- Docker 远程管理地址-->
|
||||
<dockerHost>${docker.host}</dockerHost>
|
||||
|
||||
<!--推送镜像仓库校验安全证书,无安全证书无法推送-->
|
||||
<dockerCertPath>${docker.ca}</dockerCertPath>
|
||||
<!-- 打包镜像到 docker registry 中心添加认证配置(账号密码在 maven 配置) -->
|
||||
<pushImage>true</pushImage>
|
||||
|
||||
<!--定义基础镜像-->
|
||||
<!-- <baseImage>java:8</baseImage>-->
|
||||
<!-- <baseImage>java:8</baseImage>-->
|
||||
<baseImage>openjdk:8-jre</baseImage>
|
||||
|
||||
<!-- 打包镜像到 docker registry 中心添加认证配置(账号密码在 maven 配置) -->
|
||||
<serverId>docker-registry</serverId>
|
||||
|
||||
<!--定义容器启动命令,注意不能换行-->
|
||||
<entryPoint>["sh", "-c", "mkdir -p /tmp /app/temp /root/nacos/naming/public && chmod -R 777 /tmp /app/temp /root/nacos && java -Djava.io.tmpdir=/app/temp -Dnacos.naming.cache.dir=/root/nacos/naming -jar -Xms256m -Xmx512m -XX:MetaspaceSize=256m -XX:MaxMetaspaceSize=256m -XX:+UseContainerSupport -XX:MaxRAMPercentage=60.0 -XX:+UseSerialGC -XX:MinHeapFreeRatio=40 -XX:MaxHeapFreeRatio=60 -XX:+PrintGCDetails -XX:+PrintGCDateStamps -Xloggc:./gc.log -XX:+UseGCLogFileRotation -XX:NumberOfGCLogFiles=5 -XX:GCLogFileSize=10M -Dspring.profiles.active=${spring.profile} -Duser.timezone=Asia/Shanghai /${project.build.finalName}.jar"]
|
||||
</entryPoint>
|
||||
|
||||
<!--推送镜像仓库校验安全证书,无安全证书无法推送-->
|
||||
<dockerCertPath>${docker.ca}</dockerCertPath>
|
||||
|
||||
<!-- 添加额外的Dockerfile指令来清理不必要的文件 -->
|
||||
<runs>
|
||||
<run>rm -rf /root/.m2 && rm -rf /tmp/* && rm -rf /var/cache/*</run>
|
||||
|
||||
Loading…
Reference in New Issue
Block a user