feat(订单): 新增借还动态查询功能

添加借还动态查询接口及相关DTO、Query类
在BorrowReturnRecordDTO中增加归还时间和审批时间字段
实现借出和归还记录的联合查询并按时间排序
This commit is contained in:
dzq 2025-11-29 09:06:06 +08:00
parent fb0ceaaecc
commit 5a826a7777
9 changed files with 281 additions and 0 deletions

View File

@ -11,8 +11,10 @@ import com.agileboot.domain.shop.order.OrderApplicationService;
import com.agileboot.domain.shop.order.db.ShopOrderEntity;
import com.agileboot.domain.shop.order.db.dto.OrderWithGoodsDTO;
import com.agileboot.domain.shop.order.dto.BorrowReturnRecordDTO;
import com.agileboot.domain.shop.order.dto.BorrowReturnDynamicDTO;
import com.agileboot.domain.shop.order.dto.ShopOrderExcelDTO;
import com.agileboot.domain.shop.order.query.SearchBorrowReturnRecordQuery;
import com.agileboot.domain.shop.order.query.SearchBorrowReturnDynamicQuery;
import com.agileboot.domain.shop.order.query.SearchShopOrderExcelQuery;
import com.agileboot.domain.shop.order.query.SearchShopOrderQuery;
import io.swagger.v3.oas.annotations.Operation;
@ -63,4 +65,12 @@ public class ShopOrderController extends BaseController {
PageDTO<BorrowReturnRecordDTO> page = orderApplicationService.getBorrowReturnRecordList(query);
return ResponseDTO.ok(page);
}
@Operation(summary = "借还动态分页列表")
@GetMapping("/borrow-return-dynamic")
public ResponseDTO<PageDTO<BorrowReturnDynamicDTO>> getBorrowReturnDynamicList(SearchBorrowReturnDynamicQuery<BorrowReturnDynamicDTO> query) {
log.info("借还动态查询参数:{}", JSONUtil.toJsonStr(query));
PageDTO<BorrowReturnDynamicDTO> page = orderApplicationService.getBorrowReturnDynamicList(query);
return ResponseDTO.ok(page);
}
}

View File

@ -2,6 +2,9 @@ package com.agileboot.api.controller;
import cn.hutool.json.JSONUtil;
import com.agileboot.common.config.WxshopConfig;
import com.agileboot.common.core.page.PageDTO;
import com.agileboot.domain.shop.order.dto.BorrowReturnDynamicDTO;
import com.agileboot.domain.shop.order.query.SearchBorrowReturnDynamicQuery;
import org.springframework.beans.factory.annotation.Autowired;
import com.agileboot.common.core.base.BaseController;
import com.agileboot.common.exception.ApiException;
@ -141,4 +144,15 @@ public class OrderController extends BaseController {
return ResponseDTO.fail(refundVO);
}
}
/**
* 借还动态分页列表
* @param query 借还动态查询参数
* @return 包含借还动态列表的响应
*/
@GetMapping("/borrow-return-dynamic")
public ResponseDTO<PageDTO<BorrowReturnDynamicDTO>> getBorrowReturnDynamicList(SearchBorrowReturnDynamicQuery<BorrowReturnDynamicDTO> query) {
PageDTO<BorrowReturnDynamicDTO> page = orderApplicationService.getBorrowReturnDynamicList(query);
return ResponseDTO.ok(page);
}
}

View File

@ -48,7 +48,9 @@ import com.agileboot.domain.shop.order.command.SubmitOrderCommand;
import com.agileboot.domain.shop.order.db.*;
import com.agileboot.domain.shop.order.db.dto.OrderWithGoodsDTO;
import com.agileboot.domain.shop.order.dto.BorrowReturnRecordDTO;
import com.agileboot.domain.shop.order.dto.BorrowReturnDynamicDTO;
import com.agileboot.domain.shop.order.query.SearchBorrowReturnRecordQuery;
import com.agileboot.domain.shop.order.query.SearchBorrowReturnDynamicQuery;
import com.agileboot.domain.shop.order.dto.CreateOrderResult;
import com.agileboot.domain.shop.order.dto.GetOrdersByOpenIdDTO;
import com.agileboot.domain.shop.order.dto.TopGoodsDTO;
@ -124,6 +126,11 @@ public class OrderApplicationService {
return new PageDTO<>(page.getRecords(), page.getTotal());
}
public PageDTO<BorrowReturnDynamicDTO> getBorrowReturnDynamicList(SearchBorrowReturnDynamicQuery<BorrowReturnDynamicDTO> query) {
Page<BorrowReturnDynamicDTO> page = orderService.getBorrowReturnDynamicList(query);
return new PageDTO<>(page.getRecords(), page.getTotal());
}
public List<ShopOrderEntity> list(SearchShopOrderExcelQuery<ShopOrderEntity> query) {
return orderService.list(query.toQueryWrapper());
}

View File

@ -2,7 +2,9 @@ package com.agileboot.domain.shop.order.db;
import com.agileboot.domain.shop.order.db.dto.OrderWithGoodsDTO;
import com.agileboot.domain.shop.order.dto.BorrowReturnRecordDTO;
import com.agileboot.domain.shop.order.dto.BorrowReturnDynamicDTO;
import com.agileboot.domain.shop.order.query.SearchBorrowReturnRecordQuery;
import com.agileboot.domain.shop.order.query.SearchBorrowReturnDynamicQuery;
import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.core.toolkit.Constants;
@ -53,6 +55,8 @@ public interface ShopOrderMapper extends BaseMapper<ShopOrderEntity> {
"cc.cell_no as cellNo, " +
"sc.cabinet_id as cabinetId, " +
"sc.cabinet_name as cabinetName, " +
"ra.create_time as returnTime, " +
"ra.approval_time as auditTime, " +
"CASE " +
" WHEN ra.approval_id IS NULL THEN 0 " +
" WHEN ra.status IN (1, 4) THEN 1 " +
@ -72,6 +76,72 @@ public interface ShopOrderMapper extends BaseMapper<ShopOrderEntity> {
@Param(Constants.WRAPPER) Wrapper<BorrowReturnRecordDTO> queryWrapper
);
@Select("<script>" +
"SELECT " +
"sog.order_goods_id as orderGoodsId, " +
"0 as dynamicType, " +
"so.order_id as orderId, " +
"so.create_time as orderTime, " +
"sog.goods_id as goodsId, " +
"sog.goods_name as goodsName, " +
"sog.price as goodsPrice, " +
"sog.quantity as quantity, " +
"so.payment_method as paymentMethod, " +
"so.name as orderName, " +
"so.mobile as orderMobile, " +
"cc.cell_id as cellId, " +
"cc.cell_no as cellNo, " +
"sc.cabinet_id as cabinetId, " +
"sc.cabinet_name as cabinetName, " +
"so.create_time as operateTime, " +
"null as approvalId, " +
"0 as status, " +
"null as auditName, " +
"null as auditRemark, " +
"null as images, " +
"so.create_time as dynamic_time " +
"FROM shop_order so " +
"INNER JOIN shop_order_goods sog ON so.order_id = sog.order_id AND sog.deleted = 0 " +
"LEFT JOIN cabinet_cell cc ON sog.cell_id = cc.cell_id " +
"LEFT JOIN smart_cabinet sc ON cc.cabinet_id = sc.cabinet_id " +
"${ew.customSqlSegment} " +
"UNION ALL " +
"SELECT " +
"sog.order_goods_id as orderGoodsId, " +
"1 as dynamicType, " +
"so.order_id as orderId, " +
"so.create_time as orderTime, " +
"sog.goods_id as goodsId, " +
"sog.goods_name as goodsName, " +
"sog.price as goodsPrice, " +
"sog.quantity as quantity, " +
"so.payment_method as paymentMethod, " +
"so.name as orderName, " +
"so.mobile as orderMobile, " +
"cc.cell_id as cellId, " +
"cc.cell_no as cellNo, " +
"sc.cabinet_id as cabinetId, " +
"sc.cabinet_name as cabinetName, " +
"ra.approval_time as operateTime, " +
"ra.approval_id as approvalId, " +
"ra.status as status, " +
"ra.audit_name as auditName, " +
"ra.audit_remark as auditRemark, " +
"ra.return_images as images, " +
"COALESCE(ra.approval_time, ra.create_time) as dynamic_time " +
"FROM shop_order so " +
"INNER JOIN shop_order_goods sog ON so.order_id = sog.order_id AND sog.deleted = 0 " +
"LEFT JOIN return_approval ra ON sog.order_goods_id = ra.order_goods_id AND ra.deleted = 0 " +
"LEFT JOIN cabinet_cell cc ON sog.cell_id = cc.cell_id " +
"LEFT JOIN smart_cabinet sc ON cc.cabinet_id = sc.cabinet_id " +
"${ew.customSqlSegment} " +
"ORDER BY dynamic_time DESC " +
"</script>")
Page<BorrowReturnDynamicDTO> getBorrowReturnDynamicList(
Page<BorrowReturnDynamicDTO> page,
@Param(Constants.WRAPPER) Wrapper<BorrowReturnDynamicDTO> queryWrapper
);
@Select("SELECT COUNT(1) FROM shop_order WHERE deleted = 0")
Long countAllRecord();

View File

@ -2,7 +2,9 @@ package com.agileboot.domain.shop.order.db;
import com.agileboot.domain.shop.order.db.dto.OrderWithGoodsDTO;
import com.agileboot.domain.shop.order.dto.BorrowReturnRecordDTO;
import com.agileboot.domain.shop.order.dto.BorrowReturnDynamicDTO;
import com.agileboot.domain.shop.order.query.SearchBorrowReturnRecordQuery;
import com.agileboot.domain.shop.order.query.SearchBorrowReturnDynamicQuery;
import com.agileboot.domain.shop.order.query.SearchShopOrderQuery;
import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
@ -23,6 +25,8 @@ public interface ShopOrderService extends IService<ShopOrderEntity> {
Page<BorrowReturnRecordDTO> getBorrowReturnRecordList(SearchBorrowReturnRecordQuery<BorrowReturnRecordDTO> query);
Page<BorrowReturnDynamicDTO> getBorrowReturnDynamicList(SearchBorrowReturnDynamicQuery<BorrowReturnDynamicDTO> query);
Long countAllRecord();
BigDecimal sumTotalAmount();

View File

@ -3,9 +3,11 @@ package com.agileboot.domain.shop.order.db;
import cn.hutool.core.date.DateUtil;
import com.agileboot.domain.shop.order.db.dto.OrderWithGoodsDTO;
import com.agileboot.domain.shop.order.dto.BorrowReturnRecordDTO;
import com.agileboot.domain.shop.order.dto.BorrowReturnDynamicDTO;
import com.agileboot.domain.shop.order.model.OrderModel;
import com.agileboot.domain.shop.order.query.SearchShopOrderQuery;
import com.agileboot.domain.shop.order.query.SearchBorrowReturnRecordQuery;
import com.agileboot.domain.shop.order.query.SearchBorrowReturnDynamicQuery;
import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
@ -33,6 +35,11 @@ public class ShopOrderServiceImpl extends ServiceImpl<ShopOrderMapper, ShopOrder
return baseMapper.getBorrowReturnRecordList(query.toPage(), query.toQueryWrapper());
}
@Override
public Page<BorrowReturnDynamicDTO> getBorrowReturnDynamicList(SearchBorrowReturnDynamicQuery<BorrowReturnDynamicDTO> query) {
return baseMapper.getBorrowReturnDynamicList(query.toPage(), query.toQueryWrapper());
}
@Override
public Long countAllRecord() {
return baseMapper.countAllRecord();

View File

@ -0,0 +1,101 @@
package com.agileboot.domain.shop.order.dto;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import java.math.BigDecimal;
import java.util.Date;
@Data
public class BorrowReturnDynamicDTO {
@ApiModelProperty("订单商品ID")
private Long orderGoodsId;
@ApiModelProperty("动态类型0-借出 1-归还)")
private Integer dynamicType;
@ApiModelProperty("动态类型描述")
private String dynamicTypeStr;
@ApiModelProperty("订单ID")
private Long orderId;
@ApiModelProperty("订单创建时间/借出时间")
private Date orderTime;
@ApiModelProperty("商品ID")
private Long goodsId;
@ApiModelProperty("商品名称")
private String goodsName;
@ApiModelProperty("商品单价")
private BigDecimal goodsPrice;
@ApiModelProperty("数量")
private Integer quantity;
@ApiModelProperty("支付方式")
private String paymentMethod;
@ApiModelProperty("订单姓名")
private String orderName;
@ApiModelProperty("订单手机号")
private String orderMobile;
@ApiModelProperty("格口ID")
private Long cellId;
@ApiModelProperty("格口号")
private Integer cellNo;
@ApiModelProperty("柜机ID")
private Long cabinetId;
@ApiModelProperty("柜机名称")
private String cabinetName;
@ApiModelProperty("归还/审批时间(归还记录时有效)")
private Date operateTime;
@ApiModelProperty("审批ID归还记录时有效")
private Long approvalId;
@ApiModelProperty("审批状态归还记录时有效0-未退还 1-待审批 2-已通过 3-已驳回 4-开柜中)")
private Integer status;
@ApiModelProperty("状态描述")
private String statusStr;
@ApiModelProperty("审批人(归还记录时有效)")
private String auditName;
@ApiModelProperty("审核说明(归还记录时有效)")
private String auditRemark;
@ApiModelProperty("归还图片(归还记录时有效)")
private String images;
public String getDynamicTypeStr() {
if (dynamicType == null) return "-";
switch (dynamicType) {
case 0: return "借出";
case 1: return "归还";
default: return "未知";
}
}
public String getStatusStr() {
if (status == null) return "-";
switch (status) {
case 0: return "未退还";
case 1: return "待审批";
case 2: return "已通过";
case 3: return "已驳回";
case 4: return "开柜中";
default: return "未知状态";
}
}
}

View File

@ -63,6 +63,12 @@ public class BorrowReturnRecordDTO {
@ApiModelProperty("柜机名称")
private String cabinetName;
@ApiModelProperty("归还时间")
private Date returnTime;
@ApiModelProperty("审批时间")
private Date auditTime;
public String getStatusStr() {
if (status == null) return "-";
switch (status) {

View File

@ -0,0 +1,62 @@
package com.agileboot.domain.shop.order.query;
import cn.hutool.core.util.StrUtil;
import com.agileboot.common.core.page.AbstractPageQuery;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import lombok.Data;
import lombok.EqualsAndHashCode;
@EqualsAndHashCode(callSuper = true)
@Data
public class SearchBorrowReturnDynamicQuery<T> extends AbstractPageQuery<T> {
private Long goodsId;
private Integer status;
private Integer dynamicType; // 动态类型0-借出 1-归还
@Override
public QueryWrapper<T> addQueryCondition() {
QueryWrapper<T> queryWrapper = new QueryWrapper<>();
if (dynamicType != null) {
queryWrapper.eq("dynamic_type", dynamicType);
}
if (status == null && dynamicType != null && dynamicType == 1) {
// 如果查询归还记录且未指定状态默认查询待审批已通过已驳回
status = -1;
}
// 状态筛选只对归还记录有效
if (dynamicType == null || dynamicType == 1) {
if (status == null) {
status = -1;
}
if (status == 0) {
// 未退还已支付但没有审批记录的订单商品
queryWrapper.isNull("ra.approval_id");
} else if (status == 1) {
// 待审批有审批记录且状态为1待审核或4开柜中的订单
queryWrapper.and(wrapper -> wrapper.eq("ra.status", 1)
.or()
.eq("ra.status", 4));
} else if (status == 2) {
// 已通过状态为2已通过的审批记录
queryWrapper.eq("ra.status", 2);
} else if (status == 3) {
// 已驳回状态为3已驳回的审批记录
queryWrapper.eq("ra.status", 3);
}
}
if (goodsId != null) {
queryWrapper.eq("sog.goods_id", goodsId);
}
queryWrapper.eq("so.deleted", 0)
.eq("sog.deleted", 0)
.eq("so.pay_status", 2);
return queryWrapper;
}
}