Merge remote-tracking branch 'origin/master'

This commit is contained in:
mashuai 2025-09-02 01:58:46 +08:00
commit 6e32f84495
6 changed files with 266 additions and 71 deletions

View File

@ -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<Map<String, Object>> 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();
}
}

View File

@ -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<SltAgreementInfo> 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<SltAgreementInfo> 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<Long> agreementIdsArray = list.stream()
.map(SltAgreementInfo::getAgreementId)
.filter(Objects::nonNull)
.collect(Collectors.toList());
if (agreementIdsArray.isEmpty()) {
return getDataTable(new ArrayList<>());
}
// --------- 定义返回集合 ------------------
List<SltInfoVo> dataList = new ArrayList<>();
// --------- 拿到list中所有的agreementId存成集合给每个info赋值 ------------------
List<Long> AgreementIdsArray = list.stream().map(SltAgreementInfo::getAgreementId).collect(Collectors.toList());
List<SltInfoVo> 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();
}
}

View File

@ -221,6 +221,11 @@ public interface SltAgreementInfoMapper {
*/
List<SltAgreementInfo> getSltReportList(SltAgreementInfo bean);
/**
* 未结算报表查询条数
*/
int getSltReportListCount(SltAgreementInfo bean);
/**
* 对驳回的结算信息进行重新设置为未结算
*

View File

@ -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<SltAgreementInfo> getSltAgreementInfo4Project(SltAgreementInfo bean);
public BigDecimal sum(BigDecimal... values);
public SltInfoVo getSltInfo(SltAgreementInfo info);
/**

View File

@ -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<SltAgreementInfo> getSltAgreementInfo4Project(SltAgreementInfo bean) {
Long userId = SecurityUtils.getLoginUser().getUserid();
@ -254,12 +267,12 @@ public class SltAgreementInfoServiceImpl implements ISltAgreementInfoService {
List<SltAgreementReduce> 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<SltAgreementInfo> getSltReportList(SltAgreementInfo bean) {
Long userId = SecurityUtils.getLoginUser().getUserid();
List<SltAgreementInfo> 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<SltAgreementInfo> 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());
}
}
/**

View File

@ -240,20 +240,6 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
</if>
GROUP BY bai.agreement_id
ORDER BY bai.create_time desc
<!-- <choose>-->
<!-- <when test="sltStatus == '0'.toString()">-->
<!-- and saa.id is null-->
<!-- </when>-->
<!-- <when test="sltStatus == '1'.toString()">-->
<!-- and saa.status = '1'-->
<!-- </when>-->
<!-- <when test="sltStatus == '2'.toString()">-->
<!-- and saa.status = '2'-->
<!-- </when>-->
<!-- <when test="sltStatus == '3'.toString()">-->
<!-- and saa.status = '3'-->
<!-- </when>-->
<!-- </choose>-->
</select>
<select id="getSltExam" resultType="com.bonus.material.settlement.domain.SltAgreementApply">
@ -875,36 +861,51 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<select id="getSltReportList" resultMap="SltAgreementInfoResult">
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')
<if test="unitIds != null">
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)
<if test="unitIds != null and unitIds.size() > 0">
AND bai.unit_id IN
<foreach item="item" index="index" collection="unitIds" open="(" separator="," close=")">
#{item}
</foreach>
</if>
<if test="projectId != null and projectId != ''">
and bp.pro_id = #{projectId}
<if test="projectId != null and projectId != ''">
AND bai.project_id = #{projectId}
</if>
<if test="sltStatus != null">
and bai.is_slt = #{sltStatus}
<if test="sltStatus != null and sltStatus != ''">
AND bai.is_slt = #{sltStatus}
</if>
<if test="agreementCode != null and agreementCode != ''">
and bai.agreement_code = #{agreementCode}
<if test="agreementCode != null and agreementCode != ''">
AND bai.agreement_code LIKE CONCAT('%', #{agreementCode}, '%')
</if>
GROUP BY bai.agreement_id
ORDER BY bai.create_time desc
<if test="unitName != null and unitName != ''">
AND bui.unit_name LIKE CONCAT('%', #{unitName}, '%')
</if>
<if test="projectName != null and projectName != ''">
AND bp.pro_name LIKE CONCAT('%', #{projectName}, '%')
</if>
ORDER BY bai.create_time DESC
</select>
<select id="getLeaseListBatch" resultType="com.bonus.material.settlement.domain.SltAgreementInfo">
@ -1210,4 +1211,37 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
</where>
ORDER BY bai.agreement_code, sai.type_id, sai.ma_id
</select>
<select id="getSltReportListCount" resultType="int">
SELECT
count(*)
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)
<if test="unitIds != null and unitIds.size() > 0">
AND bai.unit_id IN
<foreach item="item" index="index" collection="unitIds" open="(" separator="," close=")">
#{item}
</foreach>
</if>
<if test="projectId != null and projectId != ''">
AND bai.project_id = #{projectId}
</if>
<if test="sltStatus != null and sltStatus != ''">
AND bai.is_slt = #{sltStatus}
</if>
<if test="agreementCode != null and agreementCode != ''">
AND bai.agreement_code LIKE CONCAT('%', #{agreementCode}, '%')
</if>
<if test="unitName != null and unitName != ''">
AND bui.unit_name LIKE CONCAT('%', #{unitName}, '%')
</if>
<if test="projectName != null and projectName != ''">
AND bp.pro_name LIKE CONCAT('%', #{projectName}, '%')
</if>
ORDER BY bai.create_time DESC
</select>
</mapper>