feat(智能柜): 添加归还期限功能并实现逾期订单处理
- 在smart_cabinet表添加return_deadline字段记录归还期限 - 在SmartCabinetEntity和SmartCabinetDTO中添加对应字段 - 新增DeadlineOrderJob定时任务处理逾期订单 - 修改订单商品状态枚举和SQL查询逻辑 - 调整订单商品状态查询条件为不等于2
This commit is contained in:
parent
4b055dac24
commit
9f04fe0ce3
|
@ -0,0 +1,155 @@
|
|||
package com.agileboot.admin.customize.service.job;
|
||||
|
||||
import cn.hutool.core.date.DateUtil;
|
||||
import com.agileboot.domain.cabinet.cell.db.CabinetCellEntity;
|
||||
import com.agileboot.domain.cabinet.cell.db.CabinetCellService;
|
||||
import com.agileboot.domain.cabinet.smartCabinet.db.SmartCabinetEntity;
|
||||
import com.agileboot.domain.cabinet.smartCabinet.db.SmartCabinetService;
|
||||
import com.agileboot.domain.qywx.authCorpInfo.db.QyAuthCorpInfoEntity;
|
||||
import com.agileboot.domain.shop.order.db.ShopOrderEntity;
|
||||
import com.agileboot.domain.shop.order.db.ShopOrderGoodsEntity;
|
||||
import com.agileboot.domain.shop.order.db.ShopOrderGoodsService;
|
||||
import com.agileboot.domain.shop.order.db.ShopOrderService;
|
||||
import com.agileboot.domain.shop.paymentOperationLog.PaymentOperationLogApplicationService;
|
||||
import com.agileboot.domain.shop.paymentOperationLog.command.AddPaymentOperationLogCommand;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.commons.collections4.CollectionUtils;
|
||||
import org.springframework.scheduling.annotation.Scheduled;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
|
||||
@RequiredArgsConstructor
|
||||
@Component
|
||||
@Slf4j
|
||||
public class DeadlineOrderJob {
|
||||
private final ShopOrderService shopOrderService;
|
||||
private final ShopOrderGoodsService shopOrderGoodsService;
|
||||
private final CabinetCellService cabinetCellService;
|
||||
private final SmartCabinetService smartCabinetService;
|
||||
private final PaymentOperationLogApplicationService paymentOperationLogApplicationService;
|
||||
|
||||
/**
|
||||
* 定时任务:处理超过归还期限的订单商品
|
||||
* 每天凌晨3点执行,检查所有处于“借出中”状态的订单商品是否逾期并进行处理。
|
||||
*/
|
||||
@Scheduled(cron = "0 50 * * * *") // 每小时第50分钟执行
|
||||
@Transactional // 确保任务的原子性,如果处理过程中出现异常,数据不会被部分更新
|
||||
public void markOverdueOrdersAndRemoveFromCabinet() {
|
||||
log.info("开始执行逾期订单处理及商品下架任务...");
|
||||
|
||||
try {
|
||||
// 1. 查询所有处于“正常/借出中”状态且关联了格口ID的订单商品
|
||||
// 假设 ShopOrderGoodsEntity.STATUS_NORMAL_BORROWED = 1
|
||||
// 并且,只处理借还模式(ShopOrderEntity.mode = 2)的订单商品
|
||||
// 仅选择 payStatus 为 2 (已支付) 的订单商品进行处理,因为未支付的订单不应该算作借出。
|
||||
LambdaQueryWrapper<ShopOrderGoodsEntity> queryWrapper = new LambdaQueryWrapper<>();
|
||||
queryWrapper.eq(ShopOrderGoodsEntity::getStatus, ShopOrderGoodsEntity.STATUS_NORMAL_BORROWED); // Assuming 1 means "borrowed"
|
||||
queryWrapper.isNotNull(ShopOrderGoodsEntity::getCellId); // 必须在格口中
|
||||
|
||||
List<ShopOrderGoodsEntity> borrowedGoodsList = shopOrderGoodsService.list(queryWrapper);
|
||||
|
||||
if (CollectionUtils.isEmpty(borrowedGoodsList)) {
|
||||
log.info("未找到需要检查的借出中商品记录.");
|
||||
return;
|
||||
}
|
||||
|
||||
log.info("查找到 {} 条需检查的借出中商品记录.", borrowedGoodsList.size());
|
||||
|
||||
for (ShopOrderGoodsEntity orderGoods : borrowedGoodsList) {
|
||||
// 获取关联的订单信息
|
||||
ShopOrderEntity order = shopOrderService.getById(orderGoods.getOrderId());
|
||||
if (order == null) {
|
||||
log.warn("订单商品[{}]关联的订单[{}]不存在,跳过处理.", orderGoods.getOrderGoodsId(), orderGoods.getOrderId());
|
||||
continue;
|
||||
}
|
||||
|
||||
// 确保是借还模式
|
||||
if (order.getMode() != 0) { // 0-支付模式
|
||||
continue;
|
||||
}
|
||||
|
||||
// 确保订单已支付
|
||||
if (order.getPayStatus() != 2) { // 2-已支付
|
||||
log.debug("订单[{}]未支付,订单商品[{}]跳过处理.", order.getOrderId(), orderGoods.getOrderGoodsId());
|
||||
continue;
|
||||
}
|
||||
|
||||
// 获取关联的格口信息
|
||||
CabinetCellEntity cabinetCell = cabinetCellService.getById(orderGoods.getCellId());
|
||||
if (cabinetCell == null) {
|
||||
log.warn("订单商品[{}]关联的格口[{}]不存在,跳过处理.", orderGoods.getOrderGoodsId(), orderGoods.getCellId());
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!cabinetCell.getStock().equals(0)) {
|
||||
log.warn("订单商品[{}]关联的格口[{}]库存不为0,跳过处理.", orderGoods.getOrderGoodsId(), cabinetCell.getCellId());
|
||||
continue;
|
||||
}
|
||||
|
||||
// 获取关联的智能柜信息,以获取归还期限
|
||||
SmartCabinetEntity smartCabinet = smartCabinetService.getById(cabinetCell.getCabinetId());
|
||||
if (smartCabinet == null) {
|
||||
log.warn("格口[{}]关联的智能柜[{}]不存在,跳过处理.", cabinetCell.getCellId(), cabinetCell.getCabinetId());
|
||||
continue;
|
||||
}
|
||||
|
||||
Integer returnDeadlineDays = smartCabinet.getReturnDeadline();
|
||||
|
||||
// 检查归还期限是否有效(大于0天)
|
||||
if (returnDeadlineDays == null || returnDeadlineDays <= 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
Date orderCreateTime = order.getCreateTime();
|
||||
if (orderCreateTime == null) {
|
||||
log.warn("订单[{}]的创建时间为空,无法计算归还期限,订单商品[{}]跳过处理.", order.getOrderId(), orderGoods.getOrderGoodsId());
|
||||
continue;
|
||||
}
|
||||
|
||||
// 计算归还截止日期
|
||||
Date deadlineDate = DateUtil.offsetDay(orderCreateTime, returnDeadlineDays);
|
||||
Date now = new Date(); // 当前时间
|
||||
|
||||
// 如果当前时间晚于归还截止日期,则商品已逾期
|
||||
if (now.after(deadlineDate)) {
|
||||
log.info("发现逾期订单商品:订单号[{}], 商品ID[{}], 名称[{}]。创建时间[{}], 归还期限[{}天], 截止日期[{}].",
|
||||
order.getOrderId(), orderGoods.getOrderGoodsId(), orderGoods.getGoodsName(),
|
||||
DateUtil.formatDateTime(orderCreateTime), returnDeadlineDays, DateUtil.formatDateTime(deadlineDate));
|
||||
|
||||
// 1. 更新订单商品状态为“已逾期”
|
||||
orderGoods.setStatus(ShopOrderGoodsEntity.STATUS_OVERDUE); // STATUS_OVERDUE = 7
|
||||
// shopOrderGoodsService.updateById(orderGoods); // 更新数据库
|
||||
|
||||
// 2. 将商品从智能柜格口下架
|
||||
cabinetCell.setGoodsId(null); // 清除关联商品ID
|
||||
cabinetCell.setUsageStatus(1); // 使用状态改为1-空闲
|
||||
// cabinetCellService.updateById(cabinetCell); // 更新数据库
|
||||
|
||||
log.info("成功处理逾期商品:订单商品ID[{}]状态更新为已逾期,并从格口ID[{}]下架。", orderGoods.getOrderGoodsId(), cabinetCell.getCellId());
|
||||
|
||||
try {
|
||||
AddPaymentOperationLogCommand paymentOperationLogCommand = new AddPaymentOperationLogCommand();
|
||||
paymentOperationLogCommand.setOperationType("DeadlineOrder");
|
||||
paymentOperationLogCommand.setStatus(1);
|
||||
paymentOperationLogCommand.setRemark(
|
||||
String.format("逾期订单商品:订单号[%s], 商品ID[%s], 名称[%s]。创建时间[%s], 归还期限[%s天], 截止日期[%s].",
|
||||
order.getOrderId(), orderGoods.getOrderGoodsId(), orderGoods.getGoodsName(), DateUtil.formatDateTime(orderCreateTime), returnDeadlineDays, DateUtil.formatDateTime(deadlineDate)));
|
||||
paymentOperationLogCommand.initBaseEntity();
|
||||
paymentOperationLogApplicationService.addPaymentOperationLog(paymentOperationLogCommand);
|
||||
} catch (Exception e) {
|
||||
log.error("处理逾期订单商品[{}]时创建退款操作日志失败.", orderGoods.getOrderGoodsId(), e);
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (Exception globalException) {
|
||||
// 记录整个定时任务的全局错误
|
||||
log.error("执行逾期订单处理及商品下架任务时发生全局错误:", globalException);
|
||||
}
|
||||
log.info("逾期订单处理及商品下架任务执行完毕.");
|
||||
}
|
||||
}
|
|
@ -79,6 +79,10 @@ public class SmartCabinetEntity extends BaseEntity<SmartCabinetEntity> {
|
|||
@TableField("location")
|
||||
private Integer location;
|
||||
|
||||
@ApiModelProperty("归还期限(天),0表示不限制")
|
||||
@TableField("return_deadline")
|
||||
private Integer returnDeadline;
|
||||
|
||||
@ApiModelProperty("已用格口数")
|
||||
@TableField(exist = false)
|
||||
private Integer usedCells;
|
||||
|
|
|
@ -62,6 +62,9 @@ public class SmartCabinetDTO {
|
|||
@ExcelColumn(name = "柜机位置")
|
||||
private Integer location;
|
||||
|
||||
@ExcelColumn(name = "归还期限(天),0表示不限制")
|
||||
private Integer returnDeadline;
|
||||
|
||||
@ExcelColumn(name = "已用格口数")
|
||||
private Integer usedCells;
|
||||
|
||||
|
|
|
@ -449,7 +449,7 @@ public class OrderApplicationService {
|
|||
if (Integer.valueOf(1).equals(hasReturn)) {
|
||||
orderGoodsQueryWrapper.eq("status", 2);
|
||||
} else if (Integer.valueOf(0).equals(hasReturn)) {
|
||||
orderGoodsQueryWrapper.eq("status", 1);
|
||||
orderGoodsQueryWrapper.ne("status", 2);
|
||||
}
|
||||
// 根据查询条件获取订单商品列表
|
||||
List<ShopOrderGoodsEntity> orderGoods = orderGoodsService.list(orderGoodsQueryWrapper);
|
||||
|
@ -524,7 +524,7 @@ public class OrderApplicationService {
|
|||
if (Integer.valueOf(1).equals(hasReturn)) {
|
||||
orderGoodsQueryWrapper.eq("status", 2);
|
||||
} else if (Integer.valueOf(0).equals(hasReturn)) {
|
||||
orderGoodsQueryWrapper.eq("status", 1);
|
||||
orderGoodsQueryWrapper.ne("status", 2);
|
||||
}
|
||||
List<ShopOrderGoodsEntity> orderGoods = orderGoodsService.list(orderGoodsQueryWrapper);
|
||||
|
||||
|
|
|
@ -26,6 +26,14 @@ import lombok.Setter;
|
|||
@ApiModel(value = "ShopOrderGoodsEntity对象", description = "订单商品明细表")
|
||||
public class ShopOrderGoodsEntity extends BaseEntity<ShopOrderGoodsEntity> {
|
||||
|
||||
public static final Integer STATUS_NORMAL_BORROWED = 1;
|
||||
public static final Integer STATUS_RETURNED = 2;
|
||||
public static final Integer STATUS_EXCHANGED = 3;
|
||||
public static final Integer STATUS_COMPLETED = 4;
|
||||
public static final Integer STATUS_UNDER_REVIEW = 5;
|
||||
public static final Integer STATUS_RETURN_REJECTED = 6;
|
||||
public static final Integer STATUS_OVERDUE = 7;
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
@ApiModelProperty("订单商品唯一ID")
|
||||
|
@ -68,7 +76,7 @@ public class ShopOrderGoodsEntity extends BaseEntity<ShopOrderGoodsEntity> {
|
|||
@TableField("cover_img")
|
||||
private String coverImg;
|
||||
|
||||
@ApiModelProperty("商品状态(1正常 2已退货 3已换货 4已完成 5审核中 6退货未通过)")
|
||||
@ApiModelProperty("商品状态(1正常/借出中 2已退货 3已换货 4已完成 5审核中 6退货未通过 7已逾期)")
|
||||
@TableField("status")
|
||||
private Integer status;
|
||||
|
||||
|
|
|
@ -23,7 +23,7 @@ public interface ShopOrderMapper extends BaseMapper<ShopOrderEntity> {
|
|||
@Select("SELECT o.*, " +
|
||||
"GROUP_CONCAT(DISTINCT og.goods_name) AS goodsNames, " +
|
||||
"GROUP_CONCAT(DISTINCT og.cover_img) AS coverImgs, " +
|
||||
"CASE WHEN o.status = 2 AND MAX(CASE WHEN og.status = 1 THEN 1 ELSE 0 END) = 1 THEN 0 ELSE 1 END AS returnStatus " +
|
||||
"CASE WHEN o.status = 2 AND MAX(CASE WHEN og.status = 2 THEN 0 ELSE 1 END) = 1 THEN 0 ELSE 1 END AS returnStatus " +
|
||||
"FROM shop_order o " +
|
||||
"LEFT JOIN shop_order_goods og ON o.order_id = og.order_id AND og.deleted = 0 " +
|
||||
"LEFT JOIN cabinet_cell cc ON cc.cell_id = og.cell_id " +
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
ALTER TABLE `smart_cabinet` ADD COLUMN `return_deadline` INT NOT NULL DEFAULT 0 COMMENT '归还期限(天),0表示不限制';
|
Loading…
Reference in New Issue