修复跨区间租赁数据统计问题

-优化了 SltAgreementInfoMapper.xml 中的时间范围过滤逻辑,增加了对跨区间租赁的处理
- 更新了 SltAgreementInfoServiceImpl 中的数据过滤方法,与 SQL逻辑保持一致
- 通过多种情况判断,准确筛选出与查询区间有交集的租赁记录
This commit is contained in:
syruan 2025-09-05 15:52:18 +08:00
parent fdd2df4576
commit d8dc3a5ad5
2 changed files with 80 additions and 23 deletions

View File

@ -1145,19 +1145,19 @@ public class SltAgreementInfoServiceImpl implements ISltAgreementInfoService {
queryDto.setSltManageType(settlementType); queryDto.setSltManageType(settlementType);
} }
// 从数据库查询基础数据 // 从数据库查询基础数据
List<PeriodCostResultVo> rawResults = sltAgreementInfoMapper.selectLeasePeriodCostList(queryDto); List<PeriodCostResultVo> rawResults = sltAgreementInfoMapper.selectLeasePeriodCostList(queryDto);
// 从数据库查询冲账数据,冲账查询的时候直接过滤了协议和限制具体日期所以不需要再进行范围过滤 // 从数据库查询冲账数据,冲账查询的时候直接过滤了协议和限制具体日期所以不需要再进行范围过滤
List<PeriodCostResultVo> markResults = sltAgreementInfoMapper.selectPeriodCostListForCharge(queryDto); List<PeriodCostResultVo> markResults = sltAgreementInfoMapper.selectPeriodCostListForCharge(queryDto);
// 先过滤掉不在查询范围内的数据 // 先过滤掉基础数据不在查询范围内的数据
List<PeriodCostResultVo> filteredResults = filterDataInRange(rawResults, queryDto.getStartDate(), queryDto.getEndDate()); List<PeriodCostResultVo> filteredResults = filterDataInRange(rawResults, queryDto.getStartDate(), queryDto.getEndDate());
// 进行时间及费用计算统计 // 进行时间及费用计算统计
List<PeriodCostResultVo> periodCostResultVos = calculatePeriodCosts(filteredResults, queryDto.getStartDate(), queryDto.getEndDate()); List<PeriodCostResultVo> periodCostResultVos = calculatePeriodCosts(filteredResults, queryDto.getStartDate(), queryDto.getEndDate());
// 添加冲账数据 // 冲账数据不进行计算直接计入结果
periodCostResultVos.addAll(markResults); periodCostResultVos.addAll(markResults);
// 返回结果 // 返回结果
@ -1175,8 +1175,7 @@ public class SltAgreementInfoServiceImpl implements ISltAgreementInfoService {
* @param inputEndDate 前端输入的结束日期 * @param inputEndDate 前端输入的结束日期
* @return 过滤后的结果列表 * @return 过滤后的结果列表
*/ */
private List<PeriodCostResultVo> filterDataInRange(List<PeriodCostResultVo> rawResults, private List<PeriodCostResultVo> filterDataInRange(List<PeriodCostResultVo> rawResults, Date inputStartDate, Date inputEndDate) {
Date inputStartDate, Date inputEndDate) {
List<PeriodCostResultVo> filteredResults = new ArrayList<>(); List<PeriodCostResultVo> filteredResults = new ArrayList<>();
for (PeriodCostResultVo result : rawResults) { for (PeriodCostResultVo result : rawResults) {
@ -1189,7 +1188,7 @@ public class SltAgreementInfoServiceImpl implements ISltAgreementInfoService {
} }
/** /**
* 判断数据是否在查询范围内 * 判断数据是否在查询范围内与SQL逻辑保持一致
* *
* @param result 数据记录 * @param result 数据记录
* @param inputStartDate 前端输入的开始日期 * @param inputStartDate 前端输入的开始日期
@ -1200,19 +1199,59 @@ public class SltAgreementInfoServiceImpl implements ISltAgreementInfoService {
Date leaseStartTime = result.getStartTime(); // 领料时间 Date leaseStartTime = result.getStartTime(); // 领料时间
Date returnTime = result.getEndTime(); // 退料时间 Date returnTime = result.getEndTime(); // 退料时间
Date settlementTime = result.getSettlementTime(); // 结算时间 Date settlementTime = result.getSettlementTime(); // 结算时间
String status = result.getStatus(); // 状态 String status = result.getStatus(); // 设备状态
// 如果是已结算协议 // 如果是已结算协议
boolean leaseInRange = isDateInRange(leaseStartTime, inputStartDate, inputEndDate);
boolean returnInRange = isDateInRange(returnTime, inputStartDate, inputEndDate);
if ("1".equals(result.getIsSettled())) { if ("1".equals(result.getIsSettled())) {
// 检查领料时间退料时间结算时间是否有任何一个在查询范围内 // 情况1领料时间在查询区间内
boolean settlementInRange = isDateInRange(settlementTime, inputStartDate, inputEndDate); if (isDateInRange(leaseStartTime, inputStartDate, inputEndDate)) {
return leaseInRange || returnInRange || settlementInRange; return true;
}
// 情况2退料时间在查询区间内
if (isDateInRange(returnTime, inputStartDate, inputEndDate)) {
return true;
}
// 情况3结算时间在查询区间内
if (isDateInRange(settlementTime, inputStartDate, inputEndDate)) {
return true;
}
// 情况4跨区间租赁领料在区间前退料/结算在区间后
if (leaseStartTime != null && leaseStartTime.before(inputStartDate)) {
if ((returnTime != null && returnTime.after(inputEndDate)) ||
(settlementTime != null && settlementTime.after(inputEndDate))) {
return true;
}
}
return false;
} else { } else {
// 如果是未结算协议 // 如果是未结算协议
// 检查领料时间退料时间是否有任何一个在查询范围内或者是在用状态的设备未退还 // 情况1领料时间在查询区间内
return leaseInRange || returnInRange || ("0").equals(status); if (isDateInRange(leaseStartTime, inputStartDate, inputEndDate)) {
return true;
}
// 情况2退料时间在查询区间内
if (isDateInRange(returnTime, inputStartDate, inputEndDate)) {
return true;
}
// 情况3跨区间租赁领料在区间前退料在区间后或未退料
if (leaseStartTime != null && leaseStartTime.before(inputStartDate)) {
if (returnTime == null || returnTime.after(inputEndDate)) {
return true;
}
}
// 情况4设备状态为在用未退料且领料时间不晚于查询结束时间
if ("0".equals(status) && leaseStartTime != null && !leaseStartTime.after(inputEndDate)) {
return true;
}
return false;
} }
} }

View File

@ -1192,20 +1192,38 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<if test="companyId != null"> <if test="companyId != null">
AND bai.company_id = #{companyId} AND bai.company_id = #{companyId}
</if> </if>
<!-- 数据库层面的时间范围过滤 --> <!-- 数据库层面的时间范围过滤 - 修正跨区间租赁逻辑 -->
AND ( AND (
<!-- 已结算协议:领料时间、退料时间、结算时间中至少有一个在查询范围内 --> <!-- 已结算协议:租赁期间与查询区间有交集 -->
(bai.is_slt = 1 AND ( (bai.is_slt = 1 AND (
<!-- 情况1领料时间在查询区间内 -->
(sai.start_time IS NOT NULL AND sai.start_time BETWEEN #{startDate} AND #{endDate}) (sai.start_time IS NOT NULL AND sai.start_time BETWEEN #{startDate} AND #{endDate})
OR (sai.end_time IS NOT NULL AND sai.end_time BETWEEN #{startDate} AND #{endDate}) OR
OR (sai.slt_time IS NOT NULL AND sai.slt_time BETWEEN #{startDate} AND #{endDate}) <!-- 情况2退料时间在查询区间内 -->
(sai.end_time IS NOT NULL AND sai.end_time BETWEEN #{startDate} AND #{endDate})
OR
<!-- 情况3结算时间在查询区间内 -->
(sai.slt_time IS NOT NULL AND sai.slt_time BETWEEN #{startDate} AND #{endDate})
OR
<!-- 情况4跨区间租赁领料在区间前退料/结算在区间后) -->
(sai.start_time IS NOT NULL AND sai.start_time &lt; #{startDate} AND
((sai.end_time IS NOT NULL AND sai.end_time &gt; #{endDate}) OR
(sai.slt_time IS NOT NULL AND sai.slt_time &gt; #{endDate})))
)) ))
OR OR
<!-- 未结算协议:领料时间、退料时间中至少有一个在查询范围内 或者设备状态为在用--> <!-- 未结算协议:租赁期间与查询区间有交集 -->
((bai.is_slt = 0 or bai.is_slt IS NULL) AND ( ((bai.is_slt = 0 OR bai.is_slt IS NULL) AND (
<!-- 情况1领料时间在查询区间内 -->
(sai.start_time IS NOT NULL AND sai.start_time BETWEEN #{startDate} AND #{endDate}) (sai.start_time IS NOT NULL AND sai.start_time BETWEEN #{startDate} AND #{endDate})
OR (sai.end_time IS NOT NULL AND sai.end_time BETWEEN #{startDate} AND #{endDate}) OR
OR (sai.status = '0') <!-- 情况2退料时间在查询区间内 -->
(sai.end_time IS NOT NULL AND sai.end_time BETWEEN #{startDate} AND #{endDate})
OR
<!-- 情况3跨区间租赁领料在区间前退料在区间后或未退料 -->
(sai.start_time IS NOT NULL AND sai.start_time &lt; #{startDate} AND (sai.end_time IS NULL OR sai.end_time &gt; #{endDate}))
OR
<!-- 情况4设备状态为在用未退料且领料时间不晚于查询结束时间 -->
(sai.status = '0' AND sai.start_time IS NOT NULL AND sai.start_time &lt;= #{endDate})
)) ))
) )
</where> </where>