refactor(crm): 优化订单明细查询逻辑,移除内存排序并迁移到SQL层
1. 新增联表分页查询方法,在数据库层完成排序和分页 2. 移除前端页面冗余的合同信息缓存和内存排序逻辑 3. 新增钢卷导入组件,支持调拨单钢批量化导入 4. 补充订单明细VO类的联表查询字段
This commit is contained in:
@@ -181,6 +181,59 @@ public class CrmOrderItemVo {
|
||||
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
|
||||
private Date createTime;
|
||||
|
||||
/**
|
||||
* 创建人
|
||||
*/
|
||||
private String createBy;
|
||||
|
||||
/**
|
||||
* 更新时间
|
||||
*/
|
||||
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
|
||||
private Date updateTime;
|
||||
|
||||
/**
|
||||
* 更新人
|
||||
*/
|
||||
private String updateBy;
|
||||
|
||||
/**
|
||||
* 删除标志
|
||||
*/
|
||||
private Long delFlag;
|
||||
|
||||
/**
|
||||
* 合同号(联表查询直接映射)
|
||||
*/
|
||||
@ExcelProperty(value = "合同号")
|
||||
private String contractCode;
|
||||
|
||||
/**
|
||||
* 供方(联表查询直接映射)
|
||||
*/
|
||||
@ExcelProperty(value = "供方")
|
||||
private String supplier;
|
||||
|
||||
/**
|
||||
* 需方(联表查询直接映射)
|
||||
*/
|
||||
@ExcelProperty(value = "需方")
|
||||
private String customer;
|
||||
|
||||
/**
|
||||
* 签订时间(联表查询直接映射)
|
||||
*/
|
||||
@JsonFormat(pattern = "yyyy-MM-dd")
|
||||
@ExcelProperty(value = "签订时间")
|
||||
private Date signTime;
|
||||
|
||||
/**
|
||||
* 交货日期(联表查询直接映射)
|
||||
*/
|
||||
@JsonFormat(pattern = "yyyy-MM-dd")
|
||||
@ExcelProperty(value = "交货日期")
|
||||
private Date deliveryDate;
|
||||
|
||||
/**
|
||||
* 订单信息
|
||||
*/
|
||||
|
||||
@@ -1,8 +1,10 @@
|
||||
package com.klp.crm.mapper;
|
||||
|
||||
import com.klp.crm.domain.CrmOrderItem;
|
||||
import com.klp.crm.domain.bo.CrmOrderItemBo;
|
||||
import com.klp.crm.domain.vo.CrmOrderItemVo;
|
||||
import com.klp.common.core.mapper.BaseMapperPlus;
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import org.apache.ibatis.annotations.Param;
|
||||
|
||||
import java.util.List;
|
||||
@@ -22,4 +24,14 @@ public interface CrmOrderItemMapper extends BaseMapperPlus<CrmOrderItemMapper, C
|
||||
* @return 订单明细列表
|
||||
*/
|
||||
List<CrmOrderItem> selectOrderItemsByOrderIds(@Param("orderIds") List<Long> orderIds);
|
||||
|
||||
/**
|
||||
* 联表查询订单明细(支持排序和分页)
|
||||
* 排序规则:deliveryDate DESC -> orderId ASC -> createTime DESC
|
||||
*
|
||||
* @param page 分页对象
|
||||
* @param bo 查询条件
|
||||
* @return 分页结果
|
||||
*/
|
||||
Page<CrmOrderItemVo> selectVoListWithOrder(Page<CrmOrderItemVo> page, @Param("bo") CrmOrderItemBo bo);
|
||||
}
|
||||
|
||||
@@ -69,51 +69,19 @@ public class CrmOrderItemServiceImpl implements ICrmOrderItemService {
|
||||
|
||||
/**
|
||||
* 查询正式订单明细列表
|
||||
* 实现逻辑:查出全部匹配记录 → Java内存排序(交货日期倒序→订单ID升序→创建时间倒序)→ 手动分页
|
||||
* 排序跨页生效,同一合同明细连续排列
|
||||
* 实现逻辑:SQL联表查询 → 数据库层排序(交货日期倒序→订单ID升序→创建时间倒序)→ 物理分页
|
||||
* 排序跨页生效,同一合同明细连续排列,避免内存排序大数据量问题
|
||||
*/
|
||||
@Override
|
||||
public TableDataInfo<CrmOrderItemVo> queryPageList(CrmOrderItemBo bo, PageQuery pageQuery) {
|
||||
List<Long> orderIdScope = resolveOrderIdScope(bo);
|
||||
if (orderIdScope != null && orderIdScope.isEmpty()) {
|
||||
Page<CrmOrderItemVo> emptyPage = new Page<>(ObjectUtil.defaultIfNull(pageQuery.getPageNum(), 1),
|
||||
ObjectUtil.defaultIfNull(pageQuery.getPageSize(), 10), 0);
|
||||
emptyPage.setRecords(Collections.emptyList());
|
||||
return TableDataInfo.build(emptyPage);
|
||||
}
|
||||
LambdaQueryWrapper<CrmOrderItem> lqw = buildQueryWrapper(bo);
|
||||
if (orderIdScope != null) {
|
||||
lqw.in(CrmOrderItem::getOrderId, orderIdScope);
|
||||
}
|
||||
// 1. 查出全部匹配记录
|
||||
List<CrmOrderItemVo> allItems = baseMapper.selectVoList(lqw);
|
||||
// 2. 填充订单信息(含 deliveryDate)
|
||||
fillOrderInfoOnItems(allItems);
|
||||
// 3. 三级排序:deliveryDate DESC → orderId ASC → createTime DESC
|
||||
allItems.sort((a, b) -> {
|
||||
// 同一合同组内:按创建时间倒序
|
||||
if (Objects.equals(a.getOrderId(), b.getOrderId())) {
|
||||
return compareDate(a.getCreateTime(), b.getCreateTime(), true);
|
||||
}
|
||||
// 不同合同组:按交货日期倒序
|
||||
Date dateA = a.getOrderInfo() != null ? a.getOrderInfo().getDeliveryDate() : null;
|
||||
Date dateB = b.getOrderInfo() != null ? b.getOrderInfo().getDeliveryDate() : null;
|
||||
int cmp = compareDate(dateA, dateB, true);
|
||||
if (cmp != 0) return cmp;
|
||||
// 交货日期相同:按订单ID升序,保证同一合同组连续
|
||||
return Long.compare(a.getOrderId(), b.getOrderId());
|
||||
});
|
||||
// 4. 手动分页
|
||||
int total = allItems.size();
|
||||
int pageNum = ObjectUtil.defaultIfNull(pageQuery.getPageNum(), 1);
|
||||
int pageSize = ObjectUtil.defaultIfNull(pageQuery.getPageSize(), 10);
|
||||
int from = (pageNum - 1) * pageSize;
|
||||
int to = Math.min(from + pageSize, total);
|
||||
List<CrmOrderItemVo> pageItems = from >= total ? Collections.emptyList() : allItems.subList(from, to);
|
||||
|
||||
Page<CrmOrderItemVo> page = new Page<>(pageNum, pageSize, total);
|
||||
page.setRecords(pageItems);
|
||||
return TableDataInfo.build(page);
|
||||
// 使用MyBatis-Plus分页插件,SQL层完成联表查询、排序和分页
|
||||
Page<CrmOrderItemVo> page = new Page<>(
|
||||
ObjectUtil.defaultIfNull(pageQuery.getPageNum(), 1),
|
||||
ObjectUtil.defaultIfNull(pageQuery.getPageSize(), 10)
|
||||
);
|
||||
// 联表查询:在SQL层完成排序,避免内存排序
|
||||
Page<CrmOrderItemVo> resultPage = baseMapper.selectVoListWithOrder(page, bo);
|
||||
return TableDataInfo.build(resultPage);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
<!DOCTYPE mapper
|
||||
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
||||
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
|
||||
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
||||
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
|
||||
<mapper namespace="com.klp.crm.mapper.CrmOrderItemMapper">
|
||||
|
||||
<resultMap type="com.klp.crm.domain.CrmOrderItem" id="CrmOrderItemResult">
|
||||
@@ -36,6 +36,46 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
||||
<result property="updateTime" column="update_time"/>
|
||||
<result property="delFlag" column="del_flag"/>
|
||||
</resultMap>
|
||||
<!-- 联表查询结果映射 -->
|
||||
<resultMap type="com.klp.crm.domain.vo.CrmOrderItemVo" id="CrmOrderItemVoResult">
|
||||
<result property="itemId" column="item_id"/>
|
||||
<result property="orderId" column="order_id"/>
|
||||
<result property="productType" column="product_type"/>
|
||||
<result property="rawMaterialSpec" column="raw_material_spec"/>
|
||||
<result property="productNum" column="product_num"/>
|
||||
<result property="specialRequire" column="special_require"/>
|
||||
<result property="itemAmount" column="item_amount"/>
|
||||
<result property="remark" column="remark"/>
|
||||
<result property="finishedProductSpec" column="finished_product_spec"/>
|
||||
<result property="material" column="material"/>
|
||||
<result property="grade" column="grade"/>
|
||||
<result property="weight" column="weight"/>
|
||||
<result property="widthTolerance" column="width_tolerance"/>
|
||||
<result property="thicknessTolerance" column="thickness_tolerance"/>
|
||||
<result property="contractPrice" column="contract_price"/>
|
||||
<result property="customizer" column="customizer"/>
|
||||
<result property="shipper" column="shipper"/>
|
||||
<result property="productionBatch" column="production_batch"/>
|
||||
<result property="surfaceTreatment" column="surface_treatment"/>
|
||||
<result property="surfaceQuality" column="surface_quality"/>
|
||||
<result property="edgeCuttingReq" column="edge_cutting_req"/>
|
||||
<result property="packagingReq" column="packaging_req"/>
|
||||
<result property="width" column="width"/>
|
||||
<result property="thickness" column="thickness"/>
|
||||
<result property="purpose" column="purpose"/>
|
||||
<result property="createBy" column="create_by"/>
|
||||
<result property="createTime" column="create_time"/>
|
||||
<result property="updateBy" column="update_by"/>
|
||||
<result property="updateTime" column="update_time"/>
|
||||
<result property="delFlag" column="del_flag"/>
|
||||
<!-- 合同信息字段 -->
|
||||
<result property="contractCode" column="contract_code"/>
|
||||
<result property="supplier" column="supplier"/>
|
||||
<result property="customer" column="customer"/>
|
||||
<result property="signTime" column="sign_time"/>
|
||||
<result property="deliveryDate" column="delivery_date"/>
|
||||
</resultMap>
|
||||
|
||||
<!-- 根据订单ID列表查询订单明细 -->
|
||||
<select id="selectOrderItemsByOrderIds" resultMap="CrmOrderItemResult">
|
||||
SELECT
|
||||
@@ -78,5 +118,132 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
||||
ORDER BY item_id ASC
|
||||
</select>
|
||||
|
||||
<!-- 联表查询订单明细(支持排序和分页) -->
|
||||
<select id="selectVoListWithOrder" resultMap="CrmOrderItemVoResult">
|
||||
SELECT
|
||||
i.item_id,
|
||||
i.order_id,
|
||||
i.product_type,
|
||||
i.raw_material_spec,
|
||||
i.product_num,
|
||||
i.special_require,
|
||||
i.item_amount,
|
||||
i.remark,
|
||||
i.finished_product_spec,
|
||||
i.material,
|
||||
i.grade,
|
||||
i.weight,
|
||||
i.width_tolerance,
|
||||
i.thickness_tolerance,
|
||||
i.contract_price,
|
||||
i.customizer,
|
||||
i.shipper,
|
||||
i.production_batch,
|
||||
i.surface_treatment,
|
||||
i.surface_quality,
|
||||
i.edge_cutting_req,
|
||||
i.packaging_req,
|
||||
i.width,
|
||||
i.thickness,
|
||||
i.purpose,
|
||||
i.create_by,
|
||||
i.create_time,
|
||||
i.update_by,
|
||||
i.update_time,
|
||||
i.del_flag,
|
||||
o.contract_code,
|
||||
o.supplier,
|
||||
o.customer,
|
||||
o.sign_time,
|
||||
o.delivery_date
|
||||
FROM crm_order_item i
|
||||
LEFT JOIN crm_order o ON i.order_id = o.order_id AND o.del_flag = 0
|
||||
<where>
|
||||
i.del_flag = 0
|
||||
<if test="bo.itemId != null">
|
||||
AND i.item_id = #{bo.itemId}
|
||||
</if>
|
||||
<if test="bo.orderId != null">
|
||||
AND i.order_id = #{bo.orderId}
|
||||
</if>
|
||||
<if test="bo.productType != null and bo.productType != ''">
|
||||
AND i.product_type = #{bo.productType}
|
||||
</if>
|
||||
<if test="bo.rawMaterialSpec != null and bo.rawMaterialSpec != ''">
|
||||
AND i.raw_material_spec = #{bo.rawMaterialSpec}
|
||||
</if>
|
||||
<if test="bo.productNum != null">
|
||||
AND i.product_num = #{bo.productNum}
|
||||
</if>
|
||||
<if test="bo.specialRequire != null and bo.specialRequire != ''">
|
||||
AND i.special_require = #{bo.specialRequire}
|
||||
</if>
|
||||
<if test="bo.finishedProductSpec != null and bo.finishedProductSpec != ''">
|
||||
AND i.finished_product_spec = #{bo.finishedProductSpec}
|
||||
</if>
|
||||
<if test="bo.material != null and bo.material != ''">
|
||||
AND i.material LIKE CONCAT('%', #{bo.material}, '%')
|
||||
</if>
|
||||
<if test="bo.grade != null and bo.grade != ''">
|
||||
AND i.grade = #{bo.grade}
|
||||
</if>
|
||||
<if test="bo.weight != null">
|
||||
AND i.weight = #{bo.weight}
|
||||
</if>
|
||||
<if test="bo.contractPrice != null">
|
||||
AND i.contract_price = #{bo.contractPrice}
|
||||
</if>
|
||||
<if test="bo.customizer != null and bo.customizer != ''">
|
||||
AND i.customizer = #{bo.customizer}
|
||||
</if>
|
||||
<if test="bo.shipper != null and bo.shipper != ''">
|
||||
AND i.shipper = #{bo.shipper}
|
||||
</if>
|
||||
<if test="bo.productionBatch != null and bo.productionBatch != ''">
|
||||
AND i.production_batch = #{bo.productionBatch}
|
||||
</if>
|
||||
<if test="bo.surfaceTreatment != null and bo.surfaceTreatment != ''">
|
||||
AND i.surface_treatment = #{bo.surfaceTreatment}
|
||||
</if>
|
||||
<if test="bo.surfaceQuality != null and bo.surfaceQuality != ''">
|
||||
AND i.surface_quality = #{bo.surfaceQuality}
|
||||
</if>
|
||||
<if test="bo.edgeCuttingReq != null and bo.edgeCuttingReq != ''">
|
||||
AND i.edge_cutting_req = #{bo.edgeCuttingReq}
|
||||
</if>
|
||||
<if test="bo.packagingReq != null and bo.packagingReq != ''">
|
||||
AND i.packaging_req = #{bo.packagingReq}
|
||||
</if>
|
||||
<if test="bo.width != null and bo.width != ''">
|
||||
AND i.width = #{bo.width}
|
||||
</if>
|
||||
<if test="bo.thickness != null and bo.thickness != ''">
|
||||
AND i.thickness = #{bo.thickness}
|
||||
</if>
|
||||
<if test="bo.purpose != null and bo.purpose != ''">
|
||||
AND i.purpose = #{bo.purpose}
|
||||
</if>
|
||||
<!-- 合同表筛选条件 -->
|
||||
<if test="bo.contractCode != null and bo.contractCode != ''">
|
||||
AND o.contract_code LIKE CONCAT('%', #{bo.contractCode}, '%')
|
||||
</if>
|
||||
<if test="bo.customer != null and bo.customer != ''">
|
||||
AND o.customer LIKE CONCAT('%', #{bo.customer}, '%')
|
||||
</if>
|
||||
<if test="bo.signDateStart != null">
|
||||
AND o.sign_time >= #{bo.signDateStart}
|
||||
</if>
|
||||
<if test="bo.signDateEnd != null">
|
||||
AND o.sign_time < DATE_ADD(#{bo.signDateEnd}, INTERVAL 1 DAY)
|
||||
</if>
|
||||
<if test="bo.deliveryDateStart != null">
|
||||
AND o.delivery_date >= #{bo.deliveryDateStart}
|
||||
</if>
|
||||
<if test="bo.deliveryDateEnd != null">
|
||||
AND o.delivery_date < DATE_ADD(#{bo.deliveryDateEnd}, INTERVAL 1 DAY)
|
||||
</if>
|
||||
</where>
|
||||
ORDER BY o.delivery_date DESC, i.order_id ASC, i.create_time DESC
|
||||
</select>
|
||||
|
||||
</mapper>
|
||||
|
||||
Reference in New Issue
Block a user