diff --git a/bonus-common-biz/src/main/java/com/bonus/common/biz/utils/RequestContext.java b/bonus-common-biz/src/main/java/com/bonus/common/biz/utils/RequestContext.java new file mode 100644 index 00000000..3294c1d2 --- /dev/null +++ b/bonus-common-biz/src/main/java/com/bonus/common/biz/utils/RequestContext.java @@ -0,0 +1,31 @@ +package com.bonus.common.biz.utils; + +import java.util.HashMap; +import java.util.Map; + +public class RequestContext { + + // 每个线程独立维护一个 Map + private static final ThreadLocal> context = ThreadLocal.withInitial(HashMap::new); + + // 设置值 + public static void set(String key, Object value) { + context.get().put(key, value); + } + + // 获取值 + public static Object get(String key) { + return context.get().get(key); + } + + // 删除单个值 + public static void remove(String key) { + context.get().remove(key); + } + + // 清空(请求完成后必须清理) + public static void clear() { + context.remove(); + } +} + diff --git a/bonus-modules/bonus-material/src/main/java/com/bonus/material/settlement/controller/SltAgreementInfoController.java b/bonus-modules/bonus-material/src/main/java/com/bonus/material/settlement/controller/SltAgreementInfoController.java index 0fcbdceb..6c8d197a 100644 --- a/bonus-modules/bonus-material/src/main/java/com/bonus/material/settlement/controller/SltAgreementInfoController.java +++ b/bonus-modules/bonus-material/src/main/java/com/bonus/material/settlement/controller/SltAgreementInfoController.java @@ -16,6 +16,7 @@ import cn.hutool.core.util.ObjectUtil; import com.alibaba.fastjson.JSONObject; import com.bonus.common.biz.config.ListPagingUtil; import com.bonus.common.biz.config.PoiOutPage; +import com.bonus.common.biz.utils.RequestContext; import com.bonus.common.core.utils.ServletUtils; import com.bonus.common.log.enums.OperaType; import com.bonus.common.log.enums.OperatorType; @@ -31,12 +32,14 @@ import com.bonus.material.settlement.mapper.SltAgreementInfoMapper; import com.bonus.material.settlement.mapper.SltAgreementReduceMapper; import com.bonus.material.task.domain.TmTask; import com.bonus.material.task.mapper.TmTaskMapper; +import com.google.common.math.BigDecimalMath; import io.swagger.annotations.Api; import io.swagger.annotations.ApiOperation; import lombok.extern.slf4j.Slf4j; import org.apache.commons.collections4.CollectionUtils; import org.apache.commons.lang3.StringUtils; import org.apache.poi.hssf.usermodel.*; +import org.apache.poi.ss.formula.functions.T; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.*; import com.bonus.common.log.annotation.SysLog; @@ -98,9 +101,35 @@ public class SltAgreementInfoController extends BaseController { Integer pageIndex = Convert.toInt(ServletUtils.getParameter("pageNum"), 1); Integer pageSize = Convert.toInt(ServletUtils.getParameter("pageSize"), 10); List list = sltAgreementInfoService.getSltAgreementInfo4Project(bean); + ListPagingUtil paginated = ListPagingUtil.paging(pageIndex, pageSize, list); + // 新增外层计算-- 计算当前分页数据的各条目费用 + if (CollectionUtils.isNotEmpty(paginated.getRows())) { + byte loginUserHasSettlementPermission = sltAgreementInfoService.checkLoginUserHasSettlementPermission(); + for (Object row : paginated.getRows()) { + if (row instanceof SltAgreementInfo) { + ((SltAgreementInfo) row).setSettlementType(loginUserHasSettlementPermission); + + } + SltInfoVo sltInfoVo = null; + if (row instanceof SltAgreementInfo) { + sltInfoVo = sltAgreementInfoService.getSltInfo((SltAgreementInfo) row); + } + if (sltInfoVo != null) { + list.get(list.indexOf(row)).setCosts(sltAgreementInfoService.sum(sltInfoVo.getLeaseCost(), sltInfoVo.getRepairCost(), sltInfoVo.getScrapCost(), sltInfoVo.getLoseCost())); + //((SltAgreementInfo) row).setCosts(sltAgreementInfoService.sum(sltInfoVo.getLeaseCost(), sltInfoVo.getRepairCost(), sltInfoVo.getScrapCost(), sltInfoVo.getLoseCost())); + } + } + //ListPagingUtil resultPaging = ListPagingUtil.paging(pageIndex, pageSize, paginated.getRows()); + ListPagingUtil resultPaging = ListPagingUtil.paging(pageIndex, pageSize, list); + resultPaging.setTotal(list.size()); + return AjaxResult.success(resultPaging); + } + return AjaxResult.success(ListPagingUtil.paging(pageIndex, pageSize, list)); } + + @ApiOperation(value = "工程下拉选") @PostMapping("getProjectListByUnitIds") public AjaxResult getProjectListByUnitIds(@RequestBody BmProject bmProject) { @@ -1491,43 +1520,84 @@ public class SltAgreementInfoController extends BaseController { @ApiOperation(value = "未结算报表list查询") @GetMapping("/getSltReportList") public TableDataInfo getSltReportList(SltAgreementInfo query) { + long startTime = System.currentTimeMillis(); try { + // 参数预处理和校验 + if (query == null) { + query = new SltAgreementInfo(); + } startPage(); + // ----------- 查询未结算的全部协议 --------------- List list = sltAgreementInfoService.getSltReportList(query); + // 如果没有数据,直接返回空结果 + if (CollectionUtils.isEmpty(list)) { + return getDataTable(new ArrayList<>()); + } + + log.info("查询到未结算协议数量: {}", list.size()); + // ----------- 给查询出来的协议设置权限控制(例如只查询工器具) --------------- Byte settlementType = sltAgreementInfoService.checkLoginUserHasSettlementPermission(); - list.forEach(info -> info.setSettlementType(settlementType)); + + // --------- 拿到list中所有的agreementId存成集合,给每个info赋值 ------------------ + List agreementIdsArray = list.stream() + .map(SltAgreementInfo::getAgreementId) + .filter(Objects::nonNull) + .collect(Collectors.toList()); + + if (agreementIdsArray.isEmpty()) { + return getDataTable(new ArrayList<>()); + } // --------- 定义返回集合 ------------------ - List dataList = new ArrayList<>(); - // --------- 拿到list中所有的agreementId存成集合,给每个info赋值 ------------------ - List AgreementIdsArray = list.stream().map(SltAgreementInfo::getAgreementId).collect(Collectors.toList()); + List dataList = new ArrayList<>(list.size()); - // 把每个对象的agreementId设置成集合,避免重复查询 + // 批量处理,减少单个查询 list.forEach(info -> { - info.setAgreementIds(AgreementIdsArray); - // 查询每个协议的各项费用明细📉 - SltInfoVo vo = sltAgreementInfoService.getSltInfoReportBatch(info); - if (vo != null && !ObjectUtil.isEmpty(vo)) { - vo.setAgreementId(info.getAgreementId()); - vo.setAgreementCode(info.getAgreementCode()); - dataList.add(vo); + try { + info.setSettlementType(settlementType); + info.setAgreementIds(agreementIdsArray); + + // 查询每个协议的各项费用明细 + SltInfoVo vo = sltAgreementInfoService.getSltInfoReportBatch(info); + if (vo != null && !ObjectUtil.isEmpty(vo)) { + vo.setAgreementId(info.getAgreementId()); + vo.setAgreementCode(info.getAgreementCode()); + dataList.add(vo); + } + } catch (Exception e) { + log.error("处理协议 {} 时出错: {}", info.getAgreementCode(), e.getMessage()); } }); // 移除领、修、丢、废4项都没有明细的结算信息 - dataList.removeIf(vo -> CollectionUtils.isEmpty(vo.getLeaseList()) - && CollectionUtils.isEmpty(vo.getRepairList()) - && CollectionUtils.isEmpty(vo.getScrapList()) - && CollectionUtils.isEmpty(vo.getLoseList()) - ); +// dataList.removeIf(vo -> CollectionUtils.isEmpty(vo.getLeaseList()) +// && CollectionUtils.isEmpty(vo.getRepairList()) +// && CollectionUtils.isEmpty(vo.getScrapList()) +// && CollectionUtils.isEmpty(vo.getLoseList()) +// ); - return getDataTable(dataList); + long endTime = System.currentTimeMillis(); + log.info("未结算报表查询完成,耗时: {}ms,返回数据: {}条", (endTime - startTime), dataList.size()); + + TableDataInfo resultTableData = getDataTable(dataList); + if (RequestContext.get("unSltAgreementListCount") != null) { + if (RequestContext.get("unSltAgreementListCount") instanceof Long) { + resultTableData.setTotal(((long) RequestContext.get("unSltAgreementListCount"))); + } + if (RequestContext.get("unSltAgreementListCount") instanceof Integer) { + resultTableData.setTotal(((Integer) RequestContext.get("unSltAgreementListCount"))); + } + } + + return resultTableData; } catch (Exception e) { - throw new RuntimeException(e); + log.error("查询未结算报表失败", e); + return getDataTable(new ArrayList<>()); } finally { + RequestContext.clear(); sltAgreementInfoService.clearCache(); } } diff --git a/bonus-modules/bonus-material/src/main/java/com/bonus/material/settlement/mapper/SltAgreementInfoMapper.java b/bonus-modules/bonus-material/src/main/java/com/bonus/material/settlement/mapper/SltAgreementInfoMapper.java index 5b308bcc..5e34f11d 100644 --- a/bonus-modules/bonus-material/src/main/java/com/bonus/material/settlement/mapper/SltAgreementInfoMapper.java +++ b/bonus-modules/bonus-material/src/main/java/com/bonus/material/settlement/mapper/SltAgreementInfoMapper.java @@ -221,6 +221,11 @@ public interface SltAgreementInfoMapper { */ List getSltReportList(SltAgreementInfo bean); + /** + * 未结算报表查询条数 + */ + int getSltReportListCount(SltAgreementInfo bean); + /** * 对驳回的结算信息进行重新设置为未结算 * diff --git a/bonus-modules/bonus-material/src/main/java/com/bonus/material/settlement/service/ISltAgreementInfoService.java b/bonus-modules/bonus-material/src/main/java/com/bonus/material/settlement/service/ISltAgreementInfoService.java index 2da2cdba..7288a04e 100644 --- a/bonus-modules/bonus-material/src/main/java/com/bonus/material/settlement/service/ISltAgreementInfoService.java +++ b/bonus-modules/bonus-material/src/main/java/com/bonus/material/settlement/service/ISltAgreementInfoService.java @@ -1,5 +1,6 @@ package com.bonus.material.settlement.service; +import java.math.BigDecimal; import java.util.List; import com.bonus.common.core.web.domain.AjaxResult; @@ -37,6 +38,8 @@ public interface ISltAgreementInfoService { public List getSltAgreementInfo4Project(SltAgreementInfo bean); + public BigDecimal sum(BigDecimal... values); + public SltInfoVo getSltInfo(SltAgreementInfo info); /** diff --git a/bonus-modules/bonus-material/src/main/java/com/bonus/material/settlement/service/impl/SltAgreementInfoServiceImpl.java b/bonus-modules/bonus-material/src/main/java/com/bonus/material/settlement/service/impl/SltAgreementInfoServiceImpl.java index 757246b9..855c7753 100644 --- a/bonus-modules/bonus-material/src/main/java/com/bonus/material/settlement/service/impl/SltAgreementInfoServiceImpl.java +++ b/bonus-modules/bonus-material/src/main/java/com/bonus/material/settlement/service/impl/SltAgreementInfoServiceImpl.java @@ -9,8 +9,10 @@ import java.util.stream.Collectors; import com.bonus.common.biz.constant.GlobalConstants; import com.bonus.common.biz.domain.ProjectTreeBuild; import com.bonus.common.biz.domain.ProjectTreeNode; +import com.bonus.common.biz.utils.RequestContext; import com.bonus.common.core.exception.ServiceException; import com.bonus.common.core.utils.DateUtils; +import com.bonus.common.core.utils.StringUtils; import com.bonus.common.core.web.domain.AjaxResult; import com.bonus.common.security.utils.SecurityUtils; import com.bonus.material.basic.domain.BmAgreementInfo; @@ -125,6 +127,17 @@ public class SltAgreementInfoServiceImpl implements ISltAgreementInfoService { return sltAgreementInfoMapper.selectSltAgreementInfoList(sltAgreementInfo); } + @Override + public BigDecimal sum(BigDecimal... values) { + BigDecimal total = BigDecimal.ZERO; + for (BigDecimal v : values) { + if (v != null) { + total = total.add(v); + } + } + return total; + } + @Override public List getSltAgreementInfo4Project(SltAgreementInfo bean) { Long userId = SecurityUtils.getLoginUser().getUserid(); @@ -254,12 +267,12 @@ public class SltAgreementInfoServiceImpl implements ISltAgreementInfoService { List reductionList = getReductionListBatch(info); // 删除掉各项费用都为空的数据 - if (CollectionUtils.isEmpty(leaseList) && CollectionUtils.isEmpty(repairList) - && CollectionUtils.isEmpty(scrapList) && CollectionUtils.isEmpty(loseList) - && CollectionUtils.isEmpty(reductionList)) - { - return null; - } +// if (CollectionUtils.isEmpty(leaseList) && CollectionUtils.isEmpty(repairList) +// && CollectionUtils.isEmpty(scrapList) && CollectionUtils.isEmpty(loseList) +// && CollectionUtils.isEmpty(reductionList)) +// { +// return null; +// } sltInfoVo.setLeaseList(leaseList); sltInfoVo.setRepairList(repairList); @@ -808,16 +821,55 @@ public class SltAgreementInfoServiceImpl implements ISltAgreementInfoService { */ @Override public List getSltReportList(SltAgreementInfo bean) { - Long userId = SecurityUtils.getLoginUser().getUserid(); - List list = sltAgreementInfoMapper.getSltReportList(bean); - // 删除 null 对象 - list.removeIf(Objects::isNull); - // 遍历列表,设置默认值 - list.forEach(obj -> { - if (obj.getIsSlt() == null) { obj.setIsSlt("0");} - }); + try { + // 参数预处理,避免无效查询 + if (bean != null) { + // 清理空字符串参数,避免无效的LIKE查询 + if (StringUtils.isEmpty(bean.getAgreementCode())) { + bean.setAgreementCode(null); + } + if (StringUtils.isEmpty(bean.getUnitName())) { + bean.setUnitName(null); + } + if (StringUtils.isEmpty(bean.getProjectName())) { + bean.setProjectName(null); + } + } - return list; + // 执行查询 + List list = sltAgreementInfoMapper.getSltReportList(bean); + int listCount = sltAgreementInfoMapper.getSltReportListCount(bean); + RequestContext.set("unSltAgreementListCount", listCount); + + + // 优化后处理逻辑 + if (list != null && !list.isEmpty()) { + // 使用并行流处理大数据量(当数据量大于1000时) + if (list.size() > 1000) { + list.parallelStream() + .filter(Objects::nonNull) + .forEach(obj -> { + if (obj.getIsSlt() == null) { + obj.setIsSlt("0"); + } + }); + } else { + // 小数据量使用普通流 + list.removeIf(Objects::isNull); + list.forEach(obj -> { + if (obj.getIsSlt() == null) { + obj.setIsSlt("0"); + } + }); + } + } + + return list != null ? list : new ArrayList<>(); + + } catch (Exception e) { + System.err.println("查询未结算报表失败:" + e.getMessage()); + throw new ServiceException("查询未结算报表失败:" + e.getMessage()); + } } /** diff --git a/bonus-modules/bonus-material/src/main/resources/mapper/material/settlement/SltAgreementInfoMapper.xml b/bonus-modules/bonus-material/src/main/resources/mapper/material/settlement/SltAgreementInfoMapper.xml index 9169e0aa..fd6eeb20 100644 --- a/bonus-modules/bonus-material/src/main/resources/mapper/material/settlement/SltAgreementInfoMapper.xml +++ b/bonus-modules/bonus-material/src/main/resources/mapper/material/settlement/SltAgreementInfoMapper.xml @@ -240,20 +240,6 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" GROUP BY bai.agreement_id ORDER BY bai.create_time desc - - - - - - - - - - - - - - SELECT - bai.agreement_id, bai.agreement_code as agreementCode, bai.is_slt as isSlt, - bui.unit_id as unitId,bui.unit_name as unitName, bp.pro_id as projectId , bp.pro_name as projectName, - saa.remark,bai.protocol,saa.cost as costs, - case when (saa.id is null or saa.status = '0') then '0' when saa.status = '1' then '1' when saa.status = '2' then '2' when saa.status = '3' then '3' end as sltStatus - FROM - bm_agreement_info bai - LEFT JOIN bm_project bp ON bp.pro_id = bai.project_id - LEFT JOIN bm_unit bui ON bui.unit_id = bai.unit_id - LEFT JOIN slt_agreement_apply saa on saa.agreement_id = bai.agreement_id - WHERE - bai.status = '1' AND bui.type_id != '1731' - AND (bai.is_slt = '0' OR bai.is_slt is null) - AND (saa.status is null or saa.status != '2') - - and bui.unit_id in + bai.agreement_id, + bai.agreement_code as agreementCode, + bai.is_slt as isSlt, + bai.unit_id as unitId, + bui.unit_name as unitName, + bai.project_id as projectId, + bp.pro_name as projectName, + saa.remark, + bai.protocol, + saa.cost as costs, + CASE + WHEN saa.id IS NULL OR saa.status = '0' THEN '0' + WHEN saa.status = '1' THEN '1' + WHEN saa.status = '2' THEN '2' + WHEN saa.status = '3' THEN '3' + ELSE '0' + END as sltStatus + FROM bm_agreement_info bai + INNER JOIN bm_unit bui ON bui.unit_id = bai.unit_id AND bui.type_id != '1731' + LEFT JOIN bm_project bp ON bp.pro_id = bai.project_id + LEFT JOIN slt_agreement_apply saa ON saa.agreement_id = bai.agreement_id AND (saa.status IS NULL OR saa.status != '2') + WHERE bai.status = '1' + AND (bai.is_slt = '0' OR bai.is_slt IS NULL) + + AND bai.unit_id IN #{item} - - and bp.pro_id = #{projectId} + + AND bai.project_id = #{projectId} - - and bai.is_slt = #{sltStatus} + + AND bai.is_slt = #{sltStatus} - - and bai.agreement_code = #{agreementCode} + + AND bai.agreement_code LIKE CONCAT('%', #{agreementCode}, '%') - GROUP BY bai.agreement_id - ORDER BY bai.create_time desc + + AND bui.unit_name LIKE CONCAT('%', #{unitName}, '%') + + + AND bp.pro_name LIKE CONCAT('%', #{projectName}, '%') + + ORDER BY bai.create_time DESC + +