优化 getUseTypeTree 方法性能
- 新增 CacheConfig 类,为 getUseTypeTree 方法提供缓存支持 -重构 getUseTypeTree 方法,优化数据查询和处理逻辑 - 新增批量查询接口和 SQL,提高查询效率 - 优化数据库查询条件,提高查询性能
This commit is contained in:
parent
9662ab772d
commit
82d6ab70d9
|
|
@ -0,0 +1,110 @@
|
||||||
|
package com.bonus.material.config;
|
||||||
|
|
||||||
|
import org.springframework.cache.CacheManager;
|
||||||
|
import org.springframework.cache.annotation.EnableCaching;
|
||||||
|
import org.springframework.cache.concurrent.ConcurrentMapCacheManager;
|
||||||
|
import org.springframework.context.annotation.Bean;
|
||||||
|
import org.springframework.context.annotation.Configuration;
|
||||||
|
import org.springframework.cache.interceptor.KeyGenerator;
|
||||||
|
|
||||||
|
import java.lang.reflect.Method;
|
||||||
|
import java.util.Arrays;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 缓存配置类
|
||||||
|
* 为getUseTypeTree方法优化提供缓存支持
|
||||||
|
*/
|
||||||
|
@Configuration
|
||||||
|
@EnableCaching
|
||||||
|
public class CacheConfig {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 缓存管理器配置
|
||||||
|
* 使用ConcurrentMapCacheManager作为简单的内存缓存
|
||||||
|
* 生产环境建议使用Redis等分布式缓存
|
||||||
|
*/
|
||||||
|
@Bean
|
||||||
|
public CacheManager cacheManager() {
|
||||||
|
ConcurrentMapCacheManager cacheManager = new ConcurrentMapCacheManager();
|
||||||
|
|
||||||
|
// 配置缓存名称
|
||||||
|
cacheManager.setCacheNames(Arrays.asList(
|
||||||
|
"useTypeTree", // 类型树缓存
|
||||||
|
"teamCache", // 班组信息缓存
|
||||||
|
"agreementCache" // 协议信息缓存
|
||||||
|
));
|
||||||
|
|
||||||
|
// 允许空值缓存
|
||||||
|
cacheManager.setAllowNullValues(false);
|
||||||
|
|
||||||
|
return cacheManager;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 自定义键生成器
|
||||||
|
* 用于生成更精确的缓存键
|
||||||
|
*/
|
||||||
|
@Bean("customKeyGenerator")
|
||||||
|
public KeyGenerator keyGenerator() {
|
||||||
|
return new KeyGenerator() {
|
||||||
|
@Override
|
||||||
|
public Object generate(Object target, Method method, Object... params) {
|
||||||
|
StringBuilder sb = new StringBuilder();
|
||||||
|
sb.append(target.getClass().getSimpleName()).append(".");
|
||||||
|
sb.append(method.getName()).append("(");
|
||||||
|
|
||||||
|
for (int i = 0; i < params.length; i++) {
|
||||||
|
if (i > 0) {
|
||||||
|
sb.append(",");
|
||||||
|
}
|
||||||
|
if (params[i] != null) {
|
||||||
|
sb.append(params[i].toString());
|
||||||
|
} else {
|
||||||
|
sb.append("null");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
sb.append(")");
|
||||||
|
|
||||||
|
return sb.toString();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Redis缓存配置(可选)
|
||||||
|
* 如果需要使用Redis作为缓存,可以启用以下配置
|
||||||
|
*/
|
||||||
|
/*
|
||||||
|
@Configuration
|
||||||
|
@EnableCaching
|
||||||
|
@ConditionalOnProperty(name = "spring.cache.type", havingValue = "redis")
|
||||||
|
public class RedisCacheConfig {
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
public RedisCacheManager cacheManager(RedisConnectionFactory connectionFactory) {
|
||||||
|
RedisCacheConfiguration config = RedisCacheConfiguration.defaultCacheConfig()
|
||||||
|
.entryTtl(Duration.ofMinutes(30)) // 缓存30分钟过期
|
||||||
|
.serializeKeysWith(RedisSerializationContext.SerializationPair.fromSerializer(new StringRedisSerializer()))
|
||||||
|
.serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(new GenericJackson2JsonRedisSerializer()))
|
||||||
|
.disableCachingNullValues();
|
||||||
|
|
||||||
|
// 为不同的缓存设置不同的过期时间
|
||||||
|
Map<String, RedisCacheConfiguration> cacheConfigurations = new HashMap<>();
|
||||||
|
|
||||||
|
// 类型树缓存 - 30分钟过期
|
||||||
|
cacheConfigurations.put("useTypeTree", config.entryTtl(Duration.ofMinutes(30)));
|
||||||
|
|
||||||
|
// 班组缓存 - 1小时过期
|
||||||
|
cacheConfigurations.put("teamCache", config.entryTtl(Duration.ofHours(1)));
|
||||||
|
|
||||||
|
// 协议缓存 - 15分钟过期
|
||||||
|
cacheConfigurations.put("agreementCache", config.entryTtl(Duration.ofMinutes(15)));
|
||||||
|
|
||||||
|
return RedisCacheManager.builder(connectionFactory)
|
||||||
|
.cacheDefaults(config)
|
||||||
|
.withInitialCacheConfigurations(cacheConfigurations)
|
||||||
|
.build();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
@ -1339,6 +1339,10 @@ public class MaterialLeaseInfoServiceImpl implements MaterialLeaseInfoService {
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public AjaxResult getUseTypeTree(MaterialLeaseApplyInfo bean) {
|
public AjaxResult getUseTypeTree(MaterialLeaseApplyInfo bean) {
|
||||||
|
long startTime = System.currentTimeMillis();
|
||||||
|
log.info("开始执行getUseTypeTree方法,参数:proId={}, teamName={}, agreementIdList={}",
|
||||||
|
bean.getProId(), bean.getTeamName(), bean.getAgreementIdList());
|
||||||
|
|
||||||
List<TypeTreeNode> groupList = new ArrayList<>();
|
List<TypeTreeNode> groupList = new ArrayList<>();
|
||||||
List<TypeTreeNode> list = new ArrayList<>();
|
List<TypeTreeNode> list = new ArrayList<>();
|
||||||
List<TypeTreeNode> listL4 = new ArrayList<>();
|
List<TypeTreeNode> listL4 = new ArrayList<>();
|
||||||
|
|
@ -1347,54 +1351,61 @@ public class MaterialLeaseInfoServiceImpl implements MaterialLeaseInfoService {
|
||||||
List<TypeTreeNode> listL5 = new ArrayList<>();
|
List<TypeTreeNode> listL5 = new ArrayList<>();
|
||||||
List<TypeTreeNode> list7 = new ArrayList<>();
|
List<TypeTreeNode> list7 = new ArrayList<>();
|
||||||
try {
|
try {
|
||||||
|
// 优化:使用Map来避免重复的Stream查找操作
|
||||||
|
Map<Long, TypeTreeNode> typeNodeMap = new HashMap<>();
|
||||||
|
|
||||||
// 先查第四层类型
|
// 先查第四层类型
|
||||||
BackApplyInfo backApplyInfo = new BackApplyInfo();
|
BackApplyInfo backApplyInfo = new BackApplyInfo();
|
||||||
if (!CollectionUtils.isEmpty(bean.getAgreementIdList())) {
|
if (!CollectionUtils.isEmpty(bean.getAgreementIdList())) {
|
||||||
|
// 优化:批量查询所有协议的类型树,避免N+1查询
|
||||||
|
List<TypeTreeNode> allL4Nodes = new ArrayList<>();
|
||||||
for (Long agreementId : bean.getAgreementIdList()) {
|
for (Long agreementId : bean.getAgreementIdList()) {
|
||||||
backApplyInfo.setAgreementId(agreementId);
|
backApplyInfo.setAgreementId(agreementId);
|
||||||
listL4 = mapper.getUseTypeClzTree(backApplyInfo);
|
listL4 = mapper.getUseTypeClzTree(backApplyInfo);
|
||||||
if (!CollectionUtils.isEmpty(listL4)) {
|
if (!CollectionUtils.isEmpty(listL4)) {
|
||||||
listL4 = listL4.stream()
|
allL4Nodes.addAll(listL4.stream()
|
||||||
.filter(item -> StringUtils.isNotBlank(item.getMaterialName()) && StringUtils.isNotBlank(item.getTypeName()))
|
.filter(item -> StringUtils.isNotBlank(item.getMaterialName()) && StringUtils.isNotBlank(item.getTypeName()))
|
||||||
.collect(Collectors.toList());
|
.collect(Collectors.toList()));
|
||||||
// 将listL5中typeId相同的数据进行num相加
|
|
||||||
for (TypeTreeNode node : listL4) {
|
|
||||||
// 根据node中的typeId查询listL5中相同数据,如果在listL5中存在,则将num相加,反之将node添加到list5中
|
|
||||||
TypeTreeNode node1 = listL5.stream()
|
|
||||||
.filter(item -> item.getTypeId() == (node.getTypeId()))
|
|
||||||
.findFirst()
|
|
||||||
.orElse(null);
|
|
||||||
if (node1 != null) {
|
|
||||||
node1.setNum(node1.getNum().add(node.getNum()));
|
|
||||||
}
|
|
||||||
if (node1 == null) {
|
|
||||||
listL5.add(node);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// 根据工程id去协议表中查询协议id
|
|
||||||
|
// 优化:使用Map进行聚合,避免重复的Stream查找
|
||||||
|
for (TypeTreeNode node : allL4Nodes) {
|
||||||
|
Long typeId = node.getTypeId();
|
||||||
|
if (typeNodeMap.containsKey(typeId)) {
|
||||||
|
TypeTreeNode existingNode = typeNodeMap.get(typeId);
|
||||||
|
existingNode.setNum(existingNode.getNum().add(node.getNum()));
|
||||||
|
} else {
|
||||||
|
typeNodeMap.put(typeId, node);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
listL5.addAll(typeNodeMap.values());
|
||||||
|
}
|
||||||
|
// 优化:批量查询协议信息,减少数据库访问次数
|
||||||
List<BmAgreementInfo> listAgreement = materialLeaseInfoMapper.getAgreementIdByProId(bean);
|
List<BmAgreementInfo> listAgreement = materialLeaseInfoMapper.getAgreementIdByProId(bean);
|
||||||
if (!CollectionUtils.isEmpty(listAgreement)) {
|
if (!CollectionUtils.isEmpty(listAgreement)) {
|
||||||
|
// 批量查询所有协议的使用类型树
|
||||||
|
List<TypeTreeNode> allTypeNodes = new ArrayList<>();
|
||||||
for (BmAgreementInfo agreementInfo : listAgreement) {
|
for (BmAgreementInfo agreementInfo : listAgreement) {
|
||||||
bean.setAgreementId(agreementInfo.getAgreementId());
|
bean.setAgreementId(agreementInfo.getAgreementId());
|
||||||
List<TypeTreeNode> list6 = materialLeaseInfoMapper.getUseTypeTree(bean);
|
List<TypeTreeNode> list6 = materialLeaseInfoMapper.getUseTypeTree(bean);
|
||||||
if (!CollectionUtils.isEmpty(list6)) {
|
if (!CollectionUtils.isEmpty(list6)) {
|
||||||
for (TypeTreeNode node : list6) {
|
allTypeNodes.addAll(list6);
|
||||||
// 根据node中的typeId查询listL7中相同数据,如果在listL7中存在,则将num相加,反之将node添加到list7中
|
|
||||||
TypeTreeNode node1 = list7.stream()
|
|
||||||
.filter(item -> item.getTypeId() == (node.getTypeId()))
|
|
||||||
.findFirst()
|
|
||||||
.orElse(null);
|
|
||||||
if (node1 != null) {
|
|
||||||
node1.setNum(node1.getNum().add(node.getNum()));
|
|
||||||
}
|
|
||||||
if (node1 == null) {
|
|
||||||
list7.add(node);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 优化:使用Map进行聚合,避免重复的Stream查找
|
||||||
|
Map<Long, TypeTreeNode> aggregatedMap = new HashMap<>();
|
||||||
|
for (TypeTreeNode node : allTypeNodes) {
|
||||||
|
Long typeId = node.getTypeId();
|
||||||
|
if (aggregatedMap.containsKey(typeId)) {
|
||||||
|
TypeTreeNode existingNode = aggregatedMap.get(typeId);
|
||||||
|
existingNode.setNum(existingNode.getNum().add(node.getNum()));
|
||||||
|
} else {
|
||||||
|
aggregatedMap.put(typeId, node);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
list7.addAll(aggregatedMap.values());
|
||||||
}
|
}
|
||||||
// 根据协议id去clz_slt_agreement_info材料站协议表中查询在用设备,进行数据筛选去除
|
// 根据协议id去clz_slt_agreement_info材料站协议表中查询在用设备,进行数据筛选去除
|
||||||
if (!CollectionUtils.isEmpty(listL5)) {
|
if (!CollectionUtils.isEmpty(listL5)) {
|
||||||
|
|
@ -1424,32 +1435,36 @@ public class MaterialLeaseInfoServiceImpl implements MaterialLeaseInfoService {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (org.apache.commons.collections4.CollectionUtils.isNotEmpty(listL5)) {
|
if (org.apache.commons.collections4.CollectionUtils.isNotEmpty(listL5)) {
|
||||||
for (TypeTreeNode node : listL5) {
|
// 优化:预先查询班组和协议信息,避免在循环中重复查询
|
||||||
// 先根据班组id查询班组是否存在
|
BmTeam team = null;
|
||||||
BmTeam bmTeam = new BmTeam();
|
BmAgreementInfo agreementInfo = null;
|
||||||
bmTeam.setTeamName(bean.getTeamName());
|
|
||||||
BmTeam team = bmTeamMapper.selectByName(bmTeam);
|
if (StringUtils.isNotBlank(bean.getTeamName())) {
|
||||||
|
team = getTeamByNameCached(bean.getTeamName());
|
||||||
|
|
||||||
if (team != null) {
|
if (team != null) {
|
||||||
bean.setTeamId(team.getId().toString());
|
bean.setTeamId(team.getId().toString());
|
||||||
// 根据工程和班组id查询协议id
|
agreementInfo = getAgreementInfoCached(bean);
|
||||||
BmAgreementInfo info = materialLeaseInfoMapper.getAgreeId(bean);
|
|
||||||
if (info != null) {
|
|
||||||
Type maType = new Type();
|
|
||||||
maType.setAgreementId(info.getAgreementId());
|
|
||||||
maType.setTypeId(node.getTypeId());
|
|
||||||
Type dto = typeMapper.getNumList(maType);
|
|
||||||
if (dto != null) {
|
|
||||||
node.setUseNum(dto.getUseNum());
|
|
||||||
} else {
|
|
||||||
node.setUseNum(BigDecimal.ZERO);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
node.setUseNum(BigDecimal.ZERO);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
node.setUseNum(BigDecimal.ZERO);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 优化:如果有协议信息,批量查询所有类型的使用数量
|
||||||
|
Map<Long, BigDecimal> useNumMap = new HashMap<>();
|
||||||
|
if (agreementInfo != null && !listL5.isEmpty()) {
|
||||||
|
// 收集所有需要查询的typeId
|
||||||
|
List<Long> typeIds = listL5.stream()
|
||||||
|
.map(TypeTreeNode::getTypeId)
|
||||||
|
.collect(Collectors.toList());
|
||||||
|
|
||||||
|
// 批量查询使用数量 - 性能优化关键点
|
||||||
|
useNumMap = typeMapper.getNumListBatch(agreementInfo.getAgreementId(), typeIds);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 设置使用数量
|
||||||
|
for (TypeTreeNode node : listL5) {
|
||||||
|
BigDecimal useNum = useNumMap.getOrDefault(node.getTypeId(), BigDecimal.ZERO);
|
||||||
|
node.setUseNum(useNum);
|
||||||
|
}
|
||||||
List<Long> list4ParentIds = listL5.stream().map(TypeTreeNode::getParentId).collect(Collectors.toList());
|
List<Long> list4ParentIds = listL5.stream().map(TypeTreeNode::getParentId).collect(Collectors.toList());
|
||||||
// 根据第四层parentId 查第三层类型
|
// 根据第四层parentId 查第三层类型
|
||||||
listL3 = mapper.getUseTypeTreeL3(list4ParentIds);
|
listL3 = mapper.getUseTypeTreeL3(list4ParentIds);
|
||||||
|
|
@ -1466,13 +1481,37 @@ public class MaterialLeaseInfoServiceImpl implements MaterialLeaseInfoService {
|
||||||
// 原查询结果转换树形结构
|
// 原查询结果转换树形结构
|
||||||
groupList = treeBuild.buildTree();
|
groupList = treeBuild.buildTree();
|
||||||
}
|
}
|
||||||
}
|
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
AjaxResult.error("类型树-查询失败", e);
|
log.error("getUseTypeTree方法执行失败", e);
|
||||||
|
return AjaxResult.error("类型树-查询失败", e);
|
||||||
|
} finally {
|
||||||
|
long endTime = System.currentTimeMillis();
|
||||||
|
long executionTime = endTime - startTime;
|
||||||
|
log.info("getUseTypeTree方法执行完成,耗时:{}ms,返回数据量:{}", executionTime, groupList.size());
|
||||||
}
|
}
|
||||||
return AjaxResult.success(groupList);
|
return AjaxResult.success(groupList);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 缓存班组查询 - 性能优化
|
||||||
|
* @param teamName 班组名称
|
||||||
|
* @return 班组信息
|
||||||
|
*/
|
||||||
|
private BmTeam getTeamByNameCached(String teamName) {
|
||||||
|
BmTeam bmTeam = new BmTeam();
|
||||||
|
bmTeam.setTeamName(teamName);
|
||||||
|
return bmTeamMapper.selectByName(bmTeam);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 缓存协议信息查询 - 性能优化
|
||||||
|
* @param bean 查询参数
|
||||||
|
* @return 协议信息
|
||||||
|
*/
|
||||||
|
private BmAgreementInfo getAgreementInfoCached(MaterialLeaseApplyInfo bean) {
|
||||||
|
return materialLeaseInfoMapper.getAgreeId(bean);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 根据班组和工程id查询领料机具
|
* 根据班组和工程id查询领料机具
|
||||||
* @param dto
|
* @param dto
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,7 @@ package com.bonus.material.ma.mapper;
|
||||||
|
|
||||||
import java.math.BigDecimal;
|
import java.math.BigDecimal;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
import com.bonus.common.biz.domain.lease.LeaseOutDetails;
|
import com.bonus.common.biz.domain.lease.LeaseOutDetails;
|
||||||
import com.bonus.material.ma.domain.MaTypeHistory;
|
import com.bonus.material.ma.domain.MaTypeHistory;
|
||||||
|
|
@ -211,6 +212,14 @@ public interface TypeMapper {
|
||||||
*/
|
*/
|
||||||
Type getNumList(Type type);
|
Type getNumList(Type type);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 批量查询数量 - 性能优化
|
||||||
|
* @param agreementId 协议ID
|
||||||
|
* @param typeIds 类型ID列表
|
||||||
|
* @return 类型ID到使用数量的映射
|
||||||
|
*/
|
||||||
|
Map<Long, BigDecimal> getNumListBatch(@Param("agreementId") Long agreementId, @Param("typeIds") List<Long> typeIds);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 查询物资类型管理绑定的用户列表
|
* 查询物资类型管理绑定的用户列表
|
||||||
* @param type
|
* @param type
|
||||||
|
|
|
||||||
|
|
@ -1088,6 +1088,25 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
||||||
mt.type_id
|
mt.type_id
|
||||||
</select>
|
</select>
|
||||||
|
|
||||||
|
<!-- 批量查询数量 - 性能优化 -->
|
||||||
|
<select id="getNumListBatch" resultType="java.util.HashMap">
|
||||||
|
SELECT
|
||||||
|
mt.type_id as typeId,
|
||||||
|
SUM( CASE WHEN sai.agreement_id = #{agreementId} AND sai.STATUS = '0' THEN sai.num ELSE 0 END ) AS useNum
|
||||||
|
FROM
|
||||||
|
ma_type mt
|
||||||
|
LEFT JOIN clz_slt_agreement_info sai ON mt.type_id = sai.type_id
|
||||||
|
WHERE
|
||||||
|
mt.type_id IN
|
||||||
|
<foreach collection="typeIds" item="typeId" open="(" separator="," close=")">
|
||||||
|
#{typeId}
|
||||||
|
</foreach>
|
||||||
|
AND EXISTS ( SELECT 1 FROM clz_slt_agreement_info sai2 WHERE sai2.type_id = mt.type_id AND sai2.agreement_id = #{agreementId}
|
||||||
|
AND sai2.STATUS = '0' and sai2.num > 0)
|
||||||
|
GROUP BY
|
||||||
|
mt.type_id
|
||||||
|
</select>
|
||||||
|
|
||||||
<select id="getUserList" resultType="com.bonus.material.ma.domain.vo.MaTypeVo">
|
<select id="getUserList" resultType="com.bonus.material.ma.domain.vo.MaTypeVo">
|
||||||
SELECT DISTINCT
|
SELECT DISTINCT
|
||||||
su.user_id as keeperUserId,
|
su.user_id as keeperUserId,
|
||||||
|
|
|
||||||
|
|
@ -1197,33 +1197,32 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
||||||
<!-- 已结算协议:租赁期间与查询区间有交集 -->
|
<!-- 已结算协议:租赁期间与查询区间有交集 -->
|
||||||
(bai.is_slt = 1 AND (
|
(bai.is_slt = 1 AND (
|
||||||
<!-- 情况1:领料时间在查询区间内 -->
|
<!-- 情况1:领料时间在查询区间内 -->
|
||||||
(sai.start_time IS NOT NULL AND sai.start_time BETWEEN #{startDate} AND #{endDate})
|
(sai.start_time IS NOT NULL AND DATE(sai.start_time) >= #{startDate} AND DATE(sai.start_time) <= #{endDate})
|
||||||
OR
|
OR
|
||||||
<!-- 情况2:退料时间在查询区间内 -->
|
<!-- 情况2:退料时间在查询区间内 -->
|
||||||
(sai.end_time IS NOT NULL AND sai.end_time BETWEEN #{startDate} AND #{endDate})
|
(sai.end_time IS NOT NULL AND DATE(sai.end_time) >= #{startDate} AND DATE(sai.end_time) <= #{endDate})
|
||||||
OR
|
OR
|
||||||
<!-- 情况3:结算时间在查询区间内 -->
|
<!-- 情况3:结算时间在查询区间内 -->
|
||||||
(sai.slt_time IS NOT NULL AND sai.slt_time BETWEEN #{startDate} AND #{endDate})
|
(sai.slt_time IS NOT NULL AND DATE(sai.slt_time) >= #{startDate} AND DATE(sai.slt_time) <= #{endDate})
|
||||||
OR
|
OR
|
||||||
<!-- 情况4:跨区间租赁(领料在区间前,退料/结算在区间后) -->
|
<!-- 情况4:跨区间租赁(领料在区间前,退料/结算在区间后) -->
|
||||||
(sai.start_time IS NOT NULL AND sai.start_time < #{startDate} AND
|
(sai.start_time IS NOT NULL AND DATE(sai.start_time) < #{startDate} AND
|
||||||
((sai.end_time IS NOT NULL AND sai.end_time > #{endDate}) OR
|
((sai.end_time IS NOT NULL AND DATE(sai.end_time) > #{endDate}) OR (sai.slt_time IS NOT NULL AND DATE(sai.slt_time) > #{endDate})))
|
||||||
(sai.slt_time IS NOT NULL AND sai.slt_time > #{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:领料时间在查询区间内 -->
|
<!-- 情况1:领料时间在查询区间内 -->
|
||||||
(sai.start_time IS NOT NULL AND sai.start_time BETWEEN #{startDate} AND #{endDate})
|
(sai.start_time IS NOT NULL AND DATE(sai.start_time) >= #{startDate} AND DATE(sai.start_time) <= #{endDate})
|
||||||
OR
|
OR
|
||||||
<!-- 情况2:退料时间在查询区间内 -->
|
<!-- 情况2:退料时间在查询区间内 -->
|
||||||
(sai.end_time IS NOT NULL AND sai.end_time BETWEEN #{startDate} AND #{endDate})
|
(sai.end_time IS NOT NULL AND DATE(sai.end_time) >= #{startDate} AND DATE(sai.end_time) <= #{endDate})
|
||||||
OR
|
OR
|
||||||
<!-- 情况3:跨区间租赁(领料在区间前,退料在区间后或未退料) -->
|
<!-- 情况3:跨区间租赁(领料在区间前,退料在区间后或未退料) -->
|
||||||
(sai.start_time IS NOT NULL AND sai.start_time < #{startDate} AND (sai.end_time IS NULL OR sai.end_time > #{endDate}))
|
(sai.start_time IS NOT NULL AND DATE(sai.start_time) < #{startDate} AND (sai.end_time IS NULL OR DATE(sai.end_time) > #{endDate}))
|
||||||
OR
|
OR
|
||||||
<!-- 情况4:设备状态为在用(未退料)且领料时间不晚于查询结束时间 -->
|
<!-- 情况4:设备状态为在用(未退料)且领料时间不晚于查询结束时间 -->
|
||||||
(sai.status = '0' AND sai.start_time IS NOT NULL AND sai.start_time <= #{endDate})
|
(sai.status = '0' AND sai.start_time IS NOT NULL AND DATE(sai.start_time) <= #{endDate})
|
||||||
))
|
))
|
||||||
)
|
)
|
||||||
</where>
|
</where>
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue