package com.htsc.service;
import com.alibaba.dubbo.common.utils.CollectionUtils;
import com.htsc.commons.SystemUtil;
import com.htsc.jpa.po.FileStore;
import com.htsc.jpa.po.LiquidReportChart;
import com.htsc.jpa.po.ReportStatusManage;
import com.htsc.jpa.repository.*;
import com.htsc.view.vo.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.BeanPropertyRowMapper;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Service;
import java.math.BigDecimal;
import java.util.*;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
import java.util.stream.Collectors;
/**
* @Author K0171746
* @Date 2025/10/22 14:35
*/
@Service
public class DebtBusinessDayReportService {
private static final Logger logger = LoggerFactory.getLogger(DebtBusinessDayReportService.class);
// 日报名称
public static String debtBusinessDayReport = "AssetDebtDailyReport";
// 部门列表
private static final String[] departments = {"母公司汇总",
"证券投资部", "中央交易室", "金融创新部", "销售交易部",
"固定收益部", "报价融资部", "资金运营部", "融资融券部"
};
/**
* 部门业务映射关系
* @author K0171746
*/
private static final Map<String, List<String>> DEPT_TO_BUSINESS_MAPPING = new HashMap<>();
static {
DEPT_TO_BUSINESS_MAPPING.put("母公司汇总", Arrays.asList("证券投资部", "金融创新部", "固定收益部"));
DEPT_TO_BUSINESS_MAPPING.put("证券投资部", Arrays.asList("创新业务", "大数据业务", "宏观对冲"));
DEPT_TO_BUSINESS_MAPPING.put("中央交易室", Arrays.asList("北交所股票做市业务", "科创板股票做市业务", "基金做市业务"));
DEPT_TO_BUSINESS_MAPPING.put("金融创新部", Arrays.asList("场外衍生品业务", "期权做市业务", "场内自营业务"));
DEPT_TO_BUSINESS_MAPPING.put("销售交易部", Arrays.asList("场外衍生品", "资产合计", "衍生品合计"));
DEPT_TO_BUSINESS_MAPPING.put("固定收益部", Arrays.asList("传统固收业务", "固收衍生品业务", "债券销售交易业务"));
DEPT_TO_BUSINESS_MAPPING.put("报价融资部", Arrays.asList("资产合计", "负债合计"));
DEPT_TO_BUSINESS_MAPPING.put("资金运营部", Arrays.asList("资金部委托固收投资", "流动性储备", "资产合计"));
DEPT_TO_BUSINESS_MAPPING.put("融资融券部", Arrays.asList("两融部融券券源", "场外衍生品业务", "券源业务"));
}
@Autowired
private JdbcTemplate jdbcTemplate;
@Autowired
private LiquidReportChartRepository liquidReportChartRepository;
@Autowired
private ReportStatusRepository reportStatusRepository;
@Autowired
private MultiClientRepository multiClientRepository;
@Autowired
private WorkDayService workDayService;
// 生成日报
public void generateReport(String dateDt) {
int i = this.queryCount(dateDt);
if(i==0){
logger.info("#############{}没有数据,不生成报告", dateDt);
} else {
liquidReportChartRepository.deleteLiquidReportChartByDataDtAndReportCode(dateDt, debtBusinessDayReport);
List<DebtBusinessDayReportWholeAssetVO> wholeVO = this.queryAsset(dateDt);
this.generateChart1(wholeVO,dateDt);
this.generateChart2(wholeVO,dateDt);
this.generateParent(wholeVO,dateDt);
this.generateDpAsset(wholeVO,dateDt);
reportStatusRepository.deleteByReportConfirmDateAndReportName(SystemUtil.strToDate(dateDt), "资产负债业务日报");
ReportStatusManage reportStatusManage = new ReportStatusManage();
reportStatusManage.setReportStatus("Y");
reportStatusManage.setReportName("资产负债业务日报");
reportStatusManage.setReportConfirmDate(SystemUtil.strToDate(dateDt));
reportStatusRepository.save(reportStatusManage);
}
}
/**
* 查询指定日期范围内的资产数据
* @author K0171746
*/
private List<DebtBusinessDayReportWholeAssetVO> queryAsset (String dateDt) {
// 获取今年第一天
String bgnDt = workDayService.findYearFirstNaturalDay(dateDt);
// 获取去年最后一个工作日
// String lastYearFinalWorkDay = workDayService.findLastYearFinalWorkDayStr(dateDt);
String lastYearFinalWorkDay = "20250613";
// 获取两个日期之间的交易日
List<String> bgnDts = workDayService.findTransDts(bgnDt, dateDt);
String firstWorkDay = bgnDts.get(0);
if (Integer.parseInt(firstWorkDay) < 20250613){
firstWorkDay = "20250613";
}
StringBuffer sql = new StringBuffer();
sql.append("SELECT a.DEPT," +
"a.BUSI_BIGC_NAME," +
"a.BUSI_SMLC_NAME," +
"a.PAL," +
"a.PAL_MON," +
"a.PAL_YEAR," +
"a.COMPARE_YEAR," +
"a.PROJ_TYPE," +
"a.AMT," +
"a.COMPARE_DAY," +
"a.COMPARE_MON, " +
"a.AMT - b.AMT as COMPARE_BEGIN_YEAR, " +
"c.PAL_YEAR as compareLastYearWorkDay from T_LIQUID_BURDEN_DEPT a left join T_LIQUID_BURDEN_DEPT b on a.DEPT = b.DEPT" +
" AND a.LIQ_BIG_CLAS = b.LIQ_BIG_CLAS" +
" AND a.BUSI_BIGC_NAME = b.BUSI_BIGC_NAME" +
" AND a.BUSI_SMLC_NAME = b.BUSI_SMLC_NAME" +
" AND a.STRA = b.STRA" +
" AND a.PROJ_TYPE = b.PROJ_TYPE " +
" AND a.BS = b.BS AND a.REMARK = B.REMARK" +
" AND b.DATA_DT = '"+firstWorkDay+"' left join T_LIQUID_BURDEN_DEPT c on a.DEPT = c.DEPT" +
" AND a.BUSI_BIGC_NAME = c.BUSI_BIGC_NAME" +
" AND a.BUSI_SMLC_NAME = c.BUSI_SMLC_NAME" +
" AND a.STRA = c.STRA" +
" AND a.PROJ_TYPE = c.PROJ_TYPE " +
" AND a.BS = c.BS AND a.REMARK = c.REMARK" +
" and c.DATA_DT = '" + lastYearFinalWorkDay + "' where a.DATA_DT = '"+ dateDt +"'");
return jdbcTemplate.query(sql.toString(),new BeanPropertyRowMapper(DebtBusinessDayReportWholeAssetVO.class));
}
/**
* @Description 生成损益折线图
* @author K0171746
*/
private void generateChart1(List<DebtBusinessDayReportWholeAssetVO> wholeVO,String dateDt){
// 查询资负表,获取全部数据
List<LiquidReportChart> chartList = new ArrayList<>();
int rowNum = 1;
for (String dept : departments) {
List<String> bizTypes = DEPT_TO_BUSINESS_MAPPING.get(dept);
if (bizTypes == null || bizTypes.isEmpty()) {
logger.warn("部门 {} 没有关联的业务类型", dept);
continue;
}
// 截取前3个业务类型(如果少于3个,放入bizTypes)
List<String> top3BizTypes = bizTypes.size() <= 3 ?
new ArrayList<>(bizTypes) :
bizTypes.subList(0, 3);
Map<String, BigDecimal> result = CalculateChart1(wholeVO, dept, top3BizTypes);
// 今年总计
LiquidReportChart chartYear = new LiquidReportChart();
chartYear.setDataDt(dateDt);
chartYear.setReportCode(debtBusinessDayReport);
chartYear.setChartId("chart0010");
chartYear.setRowNum(rowNum++);
chartYear.setCellValue1("部门合计(今年)");
chartYear.setCellValue2(result.getOrDefault("部门合计(今年)",BigDecimal.ZERO).toString()); // 业务值
chartYear.setCellValue3("部门合计(去年)");
chartYear.setCellValue4(result.getOrDefault("部门合计(去年)",BigDecimal.ZERO).toString());
chartYear.setCellValue5(top3BizTypes.get(0));
chartYear.setCellValue6(result.getOrDefault(top3BizTypes.get(0), BigDecimal.ZERO).toString());
chartYear.setCellValue7(top3BizTypes.get(1));
chartYear.setCellValue8(result.getOrDefault(top3BizTypes.get(1), BigDecimal.ZERO).toString());
if (top3BizTypes.size() >= 3) {
chartYear.setCellValue9(top3BizTypes.get(2));
chartYear.setCellValue10(result.getOrDefault(top3BizTypes.get(2), BigDecimal.ZERO).toString());
}
chartYear.setChartName(dept);
chartList.add(chartYear);
}
if (!chartList.isEmpty()) {
liquidReportChartRepository.save(chartList);
logger.info("成功将 {} 条 chart1 ({}) 数据落库", chartList.size(), "chart0010");
} else {
logger.warn("没有有效数据生成 chart1");
}
}
/**
* @Description 计算损益折线图数据
* @author K0171746
*/
private Map<String,BigDecimal> CalculateChart1(List<DebtBusinessDayReportWholeAssetVO> wholeVO, String department, List<String> bizTypes) {
BigDecimal totalYear = BigDecimal.ZERO;
BigDecimal totalLastYear = BigDecimal.ZERO;
Map<String, BigDecimal> bizMap = new HashMap<>();
for (String biz : bizTypes) {
bizMap.put(biz, BigDecimal.ZERO);
}
for (DebtBusinessDayReportWholeAssetVO vo : wholeVO) {
if (!department.equals(vo.getDept())) continue;
if (vo.getProjType() != null && vo.getProjType().contains("合计")) continue;
totalYear = totalYear.add(Optional.ofNullable(vo.getPalYear()).orElse(BigDecimal.ZERO));
totalLastYear = totalLastYear.add(Optional.ofNullable(vo.getCompareLastYearWorkDay()).orElse(BigDecimal.ZERO));
String busiName = vo.getBusiBigcName();
if (busiName != null && bizTypes.contains(busiName)) {
BigDecimal palYear = Optional.ofNullable(vo.getPalYear()).orElse(BigDecimal.ZERO);
bizMap.put(busiName, bizMap.get(busiName).add(palYear));
}
}
Map<String, BigDecimal> result = new HashMap<>();
result.put("部门合计(今年)", totalYear);
result.put("部门合计(去年)", totalLastYear);
result.putAll(bizMap);
return result;
}
/**
* @Description 生成资负规模变化数据
* @author K0171746
*/
private void generateChart2(List<DebtBusinessDayReportWholeAssetVO> wholeVO,String dateDt){
List<LiquidReportChart> chartList = new ArrayList<>();
int rowNum = 1;
for (String dept : departments) {
// 获取该部门各业务类型的汇总金额
Map<String, BigDecimal> result = calculateChart2(wholeVO, dept);
// 动态遍历这个部门实际出现的所有业务类型
for (String bizType : result.keySet()) {
BigDecimal value = result.get(bizType);
if (value == null) {
value = BigDecimal.ZERO;
}
LiquidReportChart chart = new LiquidReportChart();
chart.setDataDt(dateDt);
chart.setReportCode(debtBusinessDayReport);
chart.setChartId("chart0020");
chart.setRowNum(rowNum++);
chart.setCellValue1(bizType);
chart.setCellValue2(value.stripTrailingZeros().toPlainString()); // 列头:业务类型
chart.setChartName(dept);
chartList.add(chart);
}
}
// 落库
try {
if (!chartList.isEmpty()) {
liquidReportChartRepository.save(chartList);
logger.info("成功将 {} 条 chart2 ({}, date={}) 数据落库",
chartList.size(), "chart0020", dateDt);
} else {
logger.warn("没有有效数据生成 chart2 (date={})", dateDt);
}
} catch (Exception e) {
logger.error("保存 chart2 数据时发生异常 (date={})", dateDt, e);
throw new RuntimeException("Failed to save chart2 data", e);
}
}
/**
* @Description 计算资负规模变化图数据
* @author K0171746
*/
private Map<String, BigDecimal> calculateChart2(List<DebtBusinessDayReportWholeAssetVO> wholeVO, String department){
Map<String, BigDecimal> result = new HashMap<>();
for (int i = 0; i < wholeVO.size(); i++) {
DebtBusinessDayReportWholeAssetVO vo = wholeVO.get(i);
String dept = vo.getDept();
// 跳过 null 或不匹配的部门
if (department == null || dept == null) {
continue;
}
if (!department.equals(dept)) {
continue;
}
// 获取业务类型(projType)
String projType = vo.getProjType();
if (projType == null) {
continue; // 类型为空则跳过
}
projType = projType.trim();
if (projType.isEmpty()) {
continue; // 空字符串也跳过
}
// 获取 pal 值,null 视为 0
BigDecimal pal = vo.getPal();
if (pal == null) {
pal = BigDecimal.ZERO;
}
// 判断此业务类型是否已存在
boolean found = false;
for (String existingType : result.keySet()) {
if (existingType.equals(projType)) {
// 找到了,取出原值并相加
BigDecimal oldSum = result.get(existingType);
BigDecimal newSum = oldSum.add(pal);
result.put(projType, newSum);
found = true;
break;
}
}
// 如果没找到(第一次出现),直接放入
if (!found) {
result.put(projType, pal);
}
}
return result;
}
/**
* 检查指定日期是否有数据记录
* @author K0171746
*/
public int queryCount(String dateDt) {
StringBuilder sql = new StringBuilder();
sql.append("SELECT ");
sql.append(" count(1) ");
sql.append("FROM ");
sql.append(" T_LIQUID_BURDEN_DEPT ");
sql.append("WHERE ");
sql.append(" DATA_DT = ? ");
logger.info("查询T_LIQUID_BURDEN_DEPT数据是否为空{}", sql.toString());
return jdbcTemplate.queryForObject(sql.toString(), Integer.class, dateDt);
}
/**
* 生成汇总数据图表 chart0030
* @author K0171746
*/
private void generateParent(List<DebtBusinessDayReportWholeAssetVO> wholeVO,String dateDt){
// 按部门分组数据
Map<String, List<DebtBusinessDayReportWholeAssetVO>> deptDataMap = new HashMap<>();
for (DebtBusinessDayReportWholeAssetVO vo : wholeVO) {
// 判空处理
String projType = vo.getProjType();
if (projType == null || !projType.contains("合计")){
continue;
}
String dept = vo.getDept();
if (!deptDataMap.containsKey(dept)) {
deptDataMap.put(dept, new ArrayList<>());
}
deptDataMap.get(dept).add(vo);
}
int rowNum = 1;
List<LiquidReportChart> chartList = new ArrayList<>();
// 为每个部门生成数据,确保不超过23行
for (Map.Entry<String, List<DebtBusinessDayReportWholeAssetVO>> entry : deptDataMap.entrySet()) {
String dept = entry.getKey();
List<DebtBusinessDayReportWholeAssetVO> deptData = entry.getValue();
// 如果部门数据超过23行,需要进行动态调整
if (deptData.size() > 23) {
// 获取所有项目类型
Set<String> projTypes = new HashSet<>();
for (DebtBusinessDayReportWholeAssetVO vo : deptData) {
if (vo.getProjType() != null) {
projTypes.add(vo.getProjType());
}
}
// 如果项目类型数量较多,则进行分组汇总
if (projTypes.size() > 6) {
// 按项目类型分组汇总数据
Map<String, DebtBusinessDayReportParentAssetVO> aggregatedData = new HashMap<>();
// 前5个项目
List<String> mainTypes = new ArrayList<>(projTypes).subList(0, 5);
for (String type : mainTypes) {
DebtBusinessDayReportParentAssetVO aggregatedVO = new DebtBusinessDayReportParentAssetVO();
aggregatedVO.setDept(dept);
aggregatedVO.setProjType(type);
for (DebtBusinessDayReportWholeAssetVO vo : deptData) {
if (type.equals(vo.getProjType())) {
// 累加各项指标
aggregatedVO.setPal(Optional.ofNullable(aggregatedVO.getPal()).orElse(BigDecimal.ZERO)
.add(Optional.ofNullable(vo.getPal()).orElse(BigDecimal.ZERO)));
aggregatedVO.setPalMon(Optional.ofNullable(aggregatedVO.getPalMon()).orElse(BigDecimal.ZERO)
.add(Optional.ofNullable(vo.getPalMon()).orElse(BigDecimal.ZERO)));
aggregatedVO.setPalYear(Optional.ofNullable(aggregatedVO.getPalYear()).orElse(BigDecimal.ZERO)
.add(Optional.ofNullable(vo.getPalYear()).orElse(BigDecimal.ZERO)));
aggregatedVO.setCompareYear(Optional.ofNullable(aggregatedVO.getCompareYear()).orElse(BigDecimal.ZERO)
.add(Optional.ofNullable(vo.getCompareYear()).orElse(BigDecimal.ZERO)));
aggregatedVO.setAmt(Optional.ofNullable(aggregatedVO.getAmt()).orElse(BigDecimal.ZERO)
.add(Optional.ofNullable(vo.getAmt()).orElse(BigDecimal.ZERO)));
aggregatedVO.setCompareDay(Optional.ofNullable(aggregatedVO.getCompareDay()).orElse(BigDecimal.ZERO)
.add(Optional.ofNullable(vo.getCompareDay()).orElse(BigDecimal.ZERO)));
aggregatedVO.setCompareMon(Optional.ofNullable(aggregatedVO.getCompareMon()).orElse(BigDecimal.ZERO)
.add(Optional.ofNullable(vo.getCompareMon()).orElse(BigDecimal.ZERO)));
aggregatedVO.setCompareBeginYear(Optional.ofNullable(aggregatedVO.getCompareBeginYear()).orElse(BigDecimal.ZERO)
.add(Optional.ofNullable(vo.getCompareBeginYear()).orElse(BigDecimal.ZERO)));
}
}
aggregatedData.put(type, aggregatedVO);
}
// 处理"其他"项目
DebtBusinessDayReportParentAssetVO otherVO = new DebtBusinessDayReportParentAssetVO();
otherVO.setDept(dept);
otherVO.setProjType("其他");
for (DebtBusinessDayReportWholeAssetVO vo : deptData) {
if (!mainTypes.contains(vo.getProjType())) {
// 累加各项指标
otherVO.setPal(Optional.ofNullable(otherVO.getPal()).orElse(BigDecimal.ZERO)
.add(Optional.ofNullable(vo.getPal()).orElse(BigDecimal.ZERO)));
otherVO.setPalMon(Optional.ofNullable(otherVO.getPalMon()).orElse(BigDecimal.ZERO)
.add(Optional.ofNullable(vo.getPalMon()).orElse(BigDecimal.ZERO)));
otherVO.setPalYear(Optional.ofNullable(otherVO.getPalYear()).orElse(BigDecimal.ZERO)
.add(Optional.ofNullable(vo.getPalYear()).orElse(BigDecimal.ZERO)));
otherVO.setCompareYear(Optional.ofNullable(otherVO.getCompareYear()).orElse(BigDecimal.ZERO)
.add(Optional.ofNullable(vo.getCompareYear()).orElse(BigDecimal.ZERO)));
otherVO.setAmt(Optional.ofNullable(otherVO.getAmt()).orElse(BigDecimal.ZERO)
.add(Optional.ofNullable(vo.getAmt()).orElse(BigDecimal.ZERO)));
otherVO.setCompareDay(Optional.ofNullable(otherVO.getCompareDay()).orElse(BigDecimal.ZERO)
.add(Optional.ofNullable(vo.getCompareDay()).orElse(BigDecimal.ZERO)));
otherVO.setCompareMon(Optional.ofNullable(otherVO.getCompareMon()).orElse(BigDecimal.ZERO)
.add(Optional.ofNullable(vo.getCompareMon()).orElse(BigDecimal.ZERO)));
otherVO.setCompareBeginYear(Optional.ofNullable(otherVO.getCompareBeginYear()).orElse(BigDecimal.ZERO)
.add(Optional.ofNullable(vo.getCompareBeginYear()).orElse(BigDecimal.ZERO)));
}
}
aggregatedData.put("其他", otherVO);
// 生成图表数据
for (DebtBusinessDayReportParentAssetVO vo : aggregatedData.values()) {
LiquidReportChart chart = new LiquidReportChart();
chart.setDataDt(dateDt);
chart.setReportCode(debtBusinessDayReport);
chart.setChartId("chart0030");
chart.setRowNum(rowNum++);
chart.setCellValue1(vo.getDept());
chart.setCellValue2(String.valueOf(vo.getPal()));
chart.setCellValue3(String.valueOf(vo.getPalMon()));
chart.setCellValue4(String.valueOf(vo.getPalYear()));
chart.setCellValue5(String.valueOf(vo.getCompareYear()));
chart.setCellValue6(vo.getProjType());
chart.setCellValue7(String.valueOf(vo.getAmt()));
chart.setCellValue8(String.valueOf(vo.getCompareDay()));
chart.setCellValue9(String.valueOf(vo.getCompareMon()));
chart.setCellValue10(String.valueOf(vo.getCompareBeginYear()));
chartList.add(chart);
}
} else {
// 按项目类型去重
Map<String, DebtBusinessDayReportParentAssetVO> uniqueData = new HashMap<>();
for (DebtBusinessDayReportWholeAssetVO vo : deptData) {
String projType = vo.getProjType();
if (!uniqueData.containsKey(projType)) {
DebtBusinessDayReportParentAssetVO parentVO = new DebtBusinessDayReportParentAssetVO();
parentVO.setDept(vo.getDept());
parentVO.setPal(Optional.ofNullable(vo.getPal()).orElse(BigDecimal.ZERO));
parentVO.setPalMon(Optional.ofNullable(vo.getPalMon()).orElse(BigDecimal.ZERO));
parentVO.setPalYear(Optional.ofNullable(vo.getPalYear()).orElse(BigDecimal.ZERO));
parentVO.setCompareYear(Optional.ofNullable(vo.getCompareYear()).orElse(BigDecimal.ZERO));
parentVO.setProjType(vo.getProjType());
parentVO.setAmt(Optional.ofNullable(vo.getAmt()).orElse(BigDecimal.ZERO));
parentVO.setCompareDay(Optional.ofNullable(vo.getCompareDay()).orElse(BigDecimal.ZERO));
parentVO.setCompareMon(Optional.ofNullable(vo.getCompareMon()).orElse(BigDecimal.ZERO));
parentVO.setCompareBeginYear(Optional.ofNullable(vo.getCompareBeginYear()).orElse(BigDecimal.ZERO));
uniqueData.put(projType, parentVO);
} else {
// 累加到已存在的记录
DebtBusinessDayReportParentAssetVO existing = uniqueData.get(projType);
existing.setPal(Optional.ofNullable(existing.getPal()).orElse(BigDecimal.ZERO)
.add(Optional.ofNullable(vo.getPal()).orElse(BigDecimal.ZERO)));
existing.setPalMon(Optional.ofNullable(existing.getPalMon()).orElse(BigDecimal.ZERO)
.add(Optional.ofNullable(vo.getPalMon()).orElse(BigDecimal.ZERO)));
existing.setPalYear(Optional.ofNullable(existing.getPalYear()).orElse(BigDecimal.ZERO)
.add(Optional.ofNullable(vo.getPalYear()).orElse(BigDecimal.ZERO)));
existing.setCompareYear(Optional.ofNullable(existing.getCompareYear()).orElse(BigDecimal.ZERO)
.add(Optional.ofNullable(vo.getCompareYear()).orElse(BigDecimal.ZERO)));
existing.setAmt(Optional.ofNullable(existing.getAmt()).orElse(BigDecimal.ZERO)
.add(Optional.ofNullable(vo.getAmt()).orElse(BigDecimal.ZERO)));
existing.setCompareDay(Optional.ofNullable(existing.getCompareDay()).orElse(BigDecimal.ZERO)
.add(Optional.ofNullable(vo.getCompareDay()).orElse(BigDecimal.ZERO)));
existing.setCompareMon(Optional.ofNullable(existing.getCompareMon()).orElse(BigDecimal.ZERO)
.add(Optional.ofNullable(vo.getCompareMon()).orElse(BigDecimal.ZERO)));
existing.setCompareBeginYear(Optional.ofNullable(existing.getCompareBeginYear()).orElse(BigDecimal.ZERO)
.add(Optional.ofNullable(vo.getCompareBeginYear()).orElse(BigDecimal.ZERO)));
}
}
// 生成图表数据
for (DebtBusinessDayReportParentAssetVO vo : uniqueData.values()) {
LiquidReportChart chart = new LiquidReportChart();
chart.setDataDt(dateDt);
chart.setReportCode(debtBusinessDayReport);
chart.setChartId("chart0030");
chart.setRowNum(rowNum++);
chart.setCellValue1(vo.getDept());
chart.setCellValue2(String.valueOf(vo.getPal()));
chart.setCellValue3(String.valueOf(vo.getPalMon()));
chart.setCellValue4(String.valueOf(vo.getPalYear()));
chart.setCellValue5(String.valueOf(vo.getCompareYear()));
chart.setCellValue6(vo.getProjType());
chart.setCellValue7(String.valueOf(vo.getAmt()));
chart.setCellValue8(String.valueOf(vo.getCompareDay()));
chart.setCellValue9(String.valueOf(vo.getCompareMon()));
chart.setCellValue10(String.valueOf(vo.getCompareBeginYear()));
chartList.add(chart);
}
}
} else {
// 数据行数不超过23,直接处理
for (DebtBusinessDayReportWholeAssetVO vo : deptData) {
DebtBusinessDayReportParentAssetVO parentVO = new DebtBusinessDayReportParentAssetVO();
parentVO.setDept(vo.getDept());
parentVO.setPal(Optional.ofNullable(vo.getPal()).orElse(BigDecimal.ZERO));
parentVO.setPalMon(Optional.ofNullable(vo.getPalMon()).orElse(BigDecimal.ZERO));
parentVO.setPalYear(Optional.ofNullable(vo.getPalYear()).orElse(BigDecimal.ZERO));
parentVO.setCompareYear(Optional.ofNullable(vo.getCompareYear()).orElse(BigDecimal.ZERO));
parentVO.setProjType(vo.getProjType());
parentVO.setAmt(Optional.ofNullable(vo.getAmt()).orElse(BigDecimal.ZERO));
parentVO.setCompareDay(Optional.ofNullable(vo.getCompareDay()).orElse(BigDecimal.ZERO));
parentVO.setCompareMon(Optional.ofNullable(vo.getCompareMon()).orElse(BigDecimal.ZERO));
parentVO.setCompareBeginYear(Optional.ofNullable(vo.getCompareBeginYear()).orElse(BigDecimal.ZERO));
LiquidReportChart chart = new LiquidReportChart();
chart.setDataDt(dateDt);
chart.setReportCode(debtBusinessDayReport);
chart.setChartId("chart0030");
chart.setRowNum(rowNum++);
chart.setCellValue1(parentVO.getDept());
chart.setCellValue2(String.valueOf(parentVO.getPal()));
chart.setCellValue3(String.valueOf(parentVO.getPalMon()));
chart.setCellValue4(String.valueOf(parentVO.getPalYear()));
chart.setCellValue5(String.valueOf(parentVO.getCompareYear()));
chart.setCellValue6(parentVO.getProjType());
chart.setCellValue7(String.valueOf(parentVO.getAmt()));
chart.setCellValue8(String.valueOf(parentVO.getCompareDay()));
chart.setCellValue9(String.valueOf(parentVO.getCompareMon()));
chart.setCellValue10(String.valueOf(parentVO.getCompareBeginYear()));
chartList.add(chart);
}
}
}
// 落地入库
try {
if (!chartList.isEmpty()) {
liquidReportChartRepository.save(chartList);
logger.info("成功将 {} 条 chart3 ({}, date={}) 数据落库",
chartList.size(), "chart0030", dateDt);
} else {
logger.warn("没有有效数据生成 chart3 (date={})", dateDt);
}
} catch (Exception e) {
logger.error("保存 chart3 数据时发生异常 (date={})", dateDt, e);
throw new RuntimeException("Failed to save chart3 data", e);
}
}
/**
* @Description 生成各部门数据表 chart0040
* @author K0171746
*/
private void generateDpAsset(List<DebtBusinessDayReportWholeAssetVO> wholeVO,String dateDt){
// 参数校验
if (CollectionUtils.isEmpty(wholeVO)) {
logger.warn("输入的 wholeVO 数据为空,跳过 generateDpAsset 处理");
return;
}
if (dateDt == null || dateDt.trim().isEmpty()) {
logger.error("日期 dateDt 不能为空");
throw new IllegalArgumentException("dateDt is required");
}
// 按部门分组数据
Map<String, List<DebtBusinessDayReportWholeAssetVO>> deptDataMap = new HashMap<>();
for (DebtBusinessDayReportWholeAssetVO vo : wholeVO) {
if (vo == null || vo.getDept() == null) {
continue;
}
String dept = vo.getDept();
if (!deptDataMap.containsKey(dept)) {
deptDataMap.put(dept, new ArrayList<>());
}
deptDataMap.get(dept).add(vo);
}
List<LiquidReportChart> chartList = new ArrayList<>();
int rowNum = 1;
// 为每个部门生成数据,确保不超过23行
for (Map.Entry<String, List<DebtBusinessDayReportWholeAssetVO>> entry : deptDataMap.entrySet()) {
String dept = entry.getKey();
List<DebtBusinessDayReportWholeAssetVO> deptData = entry.getValue();
// 如果部门数据超过23行,需要进行动态调整
if (deptData.size() > 23) {
// 获取所有业务大类和小类组合
Map<String, List<DebtBusinessDayReportWholeAssetVO>> businessTypeMap = new HashMap<>();
for (DebtBusinessDayReportWholeAssetVO vo : deptData) {
String businessType = (vo.getBusiBigcName() != null ? vo.getBusiBigcName() : "") +
"|" + (vo.getBusiSmlcName() != null ? vo.getBusiSmlcName() : "");
if (!businessTypeMap.containsKey(businessType)) {
businessTypeMap.put(businessType, new ArrayList<>());
}
businessTypeMap.get(businessType).add(vo);
}
// 如果业务类型数量较多,则进行分组汇总
if (businessTypeMap.size() > 6) {
// 按业务类型分组汇总数据
Map<String, DebtBusinessDayReportWholeAssetVO> aggregatedData = new HashMap<>();
// 前5个
List<String> mainTypes = new ArrayList<>(businessTypeMap.keySet()).subList(0, 5);
for (String type : mainTypes) {
List<DebtBusinessDayReportWholeAssetVO> typeData = businessTypeMap.get(type);
String[] parts = type.split("\\|");
String bigType = parts.length > 0 ? parts[0] : "";
String smallType = parts.length > 1 ? parts[1] : "";
// 创建汇总对象
DebtBusinessDayReportWholeAssetVO aggregatedVO = new DebtBusinessDayReportWholeAssetVO();
aggregatedVO.setDept(dept);
aggregatedVO.setBusiBigcName(bigType);
aggregatedVO.setBusiSmlcName(smallType);
// 累加各项指标
for (DebtBusinessDayReportWholeAssetVO vo : typeData) {
aggregatedVO.setPal(Optional.ofNullable(aggregatedVO.getPal()).orElse(BigDecimal.ZERO)
.add(Optional.ofNullable(vo.getPal()).orElse(BigDecimal.ZERO)));
aggregatedVO.setPalMon(Optional.ofNullable(aggregatedVO.getPalMon()).orElse(BigDecimal.ZERO)
.add(Optional.ofNullable(vo.getPalMon()).orElse(BigDecimal.ZERO)));
aggregatedVO.setPalYear(Optional.ofNullable(aggregatedVO.getPalYear()).orElse(BigDecimal.ZERO)
.add(Optional.ofNullable(vo.getPalYear()).orElse(BigDecimal.ZERO)));
aggregatedVO.setCompareYear(Optional.ofNullable(aggregatedVO.getCompareYear()).orElse(BigDecimal.ZERO)
.add(Optional.ofNullable(vo.getCompareYear()).orElse(BigDecimal.ZERO)));
aggregatedVO.setAmt(Optional.ofNullable(aggregatedVO.getAmt()).orElse(BigDecimal.ZERO)
.add(Optional.ofNullable(vo.getAmt()).orElse(BigDecimal.ZERO)));
aggregatedVO.setCompareDay(Optional.ofNullable(aggregatedVO.getCompareDay()).orElse(BigDecimal.ZERO)
.add(Optional.ofNullable(vo.getCompareDay()).orElse(BigDecimal.ZERO)));
aggregatedVO.setCompareMon(Optional.ofNullable(aggregatedVO.getCompareMon()).orElse(BigDecimal.ZERO)
.add(Optional.ofNullable(vo.getCompareMon()).orElse(BigDecimal.ZERO)));
aggregatedVO.setCompareBeginYear(Optional.ofNullable(aggregatedVO.getCompareBeginYear()).orElse(BigDecimal.ZERO)
.add(Optional.ofNullable(vo.getCompareBeginYear()).orElse(BigDecimal.ZERO)));
}
aggregatedData.put(type, aggregatedVO);
}
// 处理"其他"
DebtBusinessDayReportWholeAssetVO otherVO = new DebtBusinessDayReportWholeAssetVO();
otherVO.setDept(dept);
otherVO.setBusiBigcName("其他");
otherVO.setBusiSmlcName("");
otherVO.setProjType("其他");
for (Map.Entry<String, List<DebtBusinessDayReportWholeAssetVO>> typeEntry : businessTypeMap.entrySet()) {
if (!mainTypes.contains(typeEntry.getKey())) {
for (DebtBusinessDayReportWholeAssetVO vo : typeEntry.getValue()) {
// 累加各项指标
otherVO.setPal(Optional.ofNullable(otherVO.getPal()).orElse(BigDecimal.ZERO)
.add(Optional.ofNullable(vo.getPal()).orElse(BigDecimal.ZERO)));
otherVO.setPalMon(Optional.ofNullable(otherVO.getPalMon()).orElse(BigDecimal.ZERO)
.add(Optional.ofNullable(vo.getPalMon()).orElse(BigDecimal.ZERO)));
otherVO.setPalYear(Optional.ofNullable(otherVO.getPalYear()).orElse(BigDecimal.ZERO)
.add(Optional.ofNullable(vo.getPalYear()).orElse(BigDecimal.ZERO)));
otherVO.setCompareYear(Optional.ofNullable(otherVO.getCompareYear()).orElse(BigDecimal.ZERO)
.add(Optional.ofNullable(vo.getCompareYear()).orElse(BigDecimal.ZERO)));
otherVO.setAmt(Optional.ofNullable(otherVO.getAmt()).orElse(BigDecimal.ZERO)
.add(Optional.ofNullable(vo.getAmt()).orElse(BigDecimal.ZERO)));
otherVO.setCompareDay(Optional.ofNullable(otherVO.getCompareDay()).orElse(BigDecimal.ZERO)
.add(Optional.ofNullable(vo.getCompareDay()).orElse(BigDecimal.ZERO)));
otherVO.setCompareMon(Optional.ofNullable(otherVO.getCompareMon()).orElse(BigDecimal.ZERO)
.add(Optional.ofNullable(vo.getCompareMon()).orElse(BigDecimal.ZERO)));
otherVO.setCompareBeginYear(Optional.ofNullable(otherVO.getCompareBeginYear()).orElse(BigDecimal.ZERO)
.add(Optional.ofNullable(vo.getCompareBeginYear()).orElse(BigDecimal.ZERO)));
}
}
}
aggregatedData.put("其他|", otherVO);
// 生成图表数据
for (DebtBusinessDayReportWholeAssetVO vo : aggregatedData.values()) {
LiquidReportChart chart = new LiquidReportChart();
chart.setDataDt(dateDt);
chart.setReportCode(debtBusinessDayReport);
chart.setChartId("chart0040");
chart.setRowNum(rowNum++);
chart.setCellValue1(vo.getBusiBigcName());
chart.setCellValue2(vo.getBusiSmlcName());
chart.setCellValue3(String.valueOf(vo.getPal()));
chart.setCellValue4(String.valueOf(vo.getPalMon()));
chart.setCellValue5(String.valueOf(vo.getPalYear()));
chart.setCellValue6(vo.getProjType());
chart.setCellValue7(String.valueOf(vo.getAmt()));
chart.setCellValue8(String.valueOf(vo.getCompareDay()));
chart.setCellValue9(String.valueOf(vo.getCompareMon()));
chart.setCellValue10(String.valueOf(vo.getCompareBeginYear()));
chart.setChartName(vo.getDept());
chartList.add(chart);
}
} else {
// 按业务类型去重
Map<String, DebtBusinessDayReportWholeAssetVO> uniqueData = new HashMap<>();
for (DebtBusinessDayReportWholeAssetVO vo : deptData) {
String businessType = (vo.getBusiBigcName() != null ? vo.getBusiBigcName() : "") +
"|" + (vo.getBusiSmlcName() != null ? vo.getBusiSmlcName() : "");
if (!uniqueData.containsKey(businessType)) {
DebtBusinessDayReportWholeAssetVO uniqueVO = new DebtBusinessDayReportWholeAssetVO();
uniqueVO.setDept(vo.getDept());
uniqueVO.setBusiBigcName(vo.getBusiBigcName());
uniqueVO.setBusiSmlcName(vo.getBusiSmlcName());
uniqueVO.setPal(Optional.ofNullable(vo.getPal()).orElse(BigDecimal.ZERO));
uniqueVO.setPalMon(Optional.ofNullable(vo.getPalMon()).orElse(BigDecimal.ZERO));
uniqueVO.setPalYear(Optional.ofNullable(vo.getPalYear()).orElse(BigDecimal.ZERO));
uniqueVO.setCompareYear(Optional.ofNullable(vo.getCompareYear()).orElse(BigDecimal.ZERO));
uniqueVO.setProjType(vo.getProjType());
uniqueVO.setAmt(Optional.ofNullable(vo.getAmt()).orElse(BigDecimal.ZERO));
uniqueVO.setCompareDay(Optional.ofNullable(vo.getCompareDay()).orElse(BigDecimal.ZERO));
uniqueVO.setCompareMon(Optional.ofNullable(vo.getCompareMon()).orElse(BigDecimal.ZERO));
uniqueVO.setCompareBeginYear(Optional.ofNullable(vo.getCompareBeginYear()).orElse(BigDecimal.ZERO));
uniqueData.put(businessType, uniqueVO);
} else {
// 累加到已存在的记录
DebtBusinessDayReportWholeAssetVO existing = uniqueData.get(businessType);
existing.setPal(Optional.ofNullable(existing.getPal()).orElse(BigDecimal.ZERO)
.add(Optional.ofNullable(vo.getPal()).orElse(BigDecimal.ZERO)));
existing.setPalMon(Optional.ofNullable(existing.getPalMon()).orElse(BigDecimal.ZERO)
.add(Optional.ofNullable(vo.getPalMon()).orElse(BigDecimal.ZERO)));
existing.setPalYear(Optional.ofNullable(existing.getPalYear()).orElse(BigDecimal.ZERO)
.add(Optional.ofNullable(vo.getPalYear()).orElse(BigDecimal.ZERO)));
existing.setCompareYear(Optional.ofNullable(existing.getCompareYear()).orElse(BigDecimal.ZERO)
.add(Optional.ofNullable(vo.getCompareYear()).orElse(BigDecimal.ZERO)));
existing.setAmt(Optional.ofNullable(existing.getAmt()).orElse(BigDecimal.ZERO)
.add(Optional.ofNullable(vo.getAmt()).orElse(BigDecimal.ZERO)));
existing.setCompareDay(Optional.ofNullable(existing.getCompareDay()).orElse(BigDecimal.ZERO)
.add(Optional.ofNullable(vo.getCompareDay()).orElse(BigDecimal.ZERO)));
existing.setCompareMon(Optional.ofNullable(existing.getCompareMon()).orElse(BigDecimal.ZERO)
.add(Optional.ofNullable(vo.getCompareMon()).orElse(BigDecimal.ZERO)));
existing.setCompareBeginYear(Optional.ofNullable(existing.getCompareBeginYear()).orElse(BigDecimal.ZERO)
.add(Optional.ofNullable(vo.getCompareBeginYear()).orElse(BigDecimal.ZERO)));
}
}
// 生成图表数据
for (DebtBusinessDayReportWholeAssetVO vo : uniqueData.values()) {
LiquidReportChart chart = new LiquidReportChart();
chart.setDataDt(dateDt);
chart.setReportCode(debtBusinessDayReport);
chart.setChartId("chart0040");
chart.setRowNum(rowNum++);
chart.setCellValue1(vo.getBusiBigcName());
chart.setCellValue2(vo.getBusiSmlcName());
chart.setCellValue3(String.valueOf(vo.getPal()));
chart.setCellValue4(String.valueOf(vo.getPalMon()));
chart.setCellValue5(String.valueOf(vo.getPalYear()));
chart.setCellValue6(vo.getProjType());
chart.setCellValue7(String.valueOf(vo.getAmt()));
chart.setCellValue8(String.valueOf(vo.getCompareDay()));
chart.setCellValue9(String.valueOf(vo.getCompareMon()));
chart.setCellValue10(String.valueOf(vo.getCompareBeginYear()));
chart.setChartName(vo.getDept());
chartList.add(chart);
}
}
} else {
// 数据行数不超过23,直接处理
for (DebtBusinessDayReportWholeAssetVO vo : deptData) {
LiquidReportChart chart = new LiquidReportChart();
chart.setDataDt(dateDt);
chart.setReportCode(debtBusinessDayReport);
chart.setChartId("chart0040");
chart.setRowNum(rowNum++);
chart.setCellValue1(vo.getBusiBigcName());
chart.setCellValue2(vo.getBusiSmlcName());
chart.setCellValue3(String.valueOf(vo.getPal()));
chart.setCellValue4(String.valueOf(vo.getPalMon()));
chart.setCellValue5(String.valueOf(vo.getPalYear()));
chart.setCellValue6(vo.getProjType());
chart.setCellValue7(String.valueOf(vo.getAmt()));
chart.setCellValue8(String.valueOf(vo.getCompareDay()));
chart.setCellValue9(String.valueOf(vo.getCompareMon()));
chart.setCellValue10(String.valueOf(vo.getCompareBeginYear()));
chart.setChartName(vo.getDept());
chartList.add(chart);
}
}
}
// 落地入库
try {
if (!chartList.isEmpty()) {
liquidReportChartRepository.save(chartList);
logger.info("成功将 {} 条部门明细数据 ({}, date={}) 落库", chartList.size(), "chart0040", dateDt);
} else {
logger.warn("没有有效数据生成部门明细表 (date={})", dateDt);
}
} catch (Exception e) {
logger.error("保存部门明细数据时发生异常 (date={})", dateDt, e);
throw new RuntimeException("Failed to save department asset detail data", e);
}
}
/**
* @Description 查询日报,不传部门参数则为母公司数据
* @author K0171746
*/
public DebtBusinessDayReportResultVO getReport (String dataDt,String department){
DebtBusinessDayReportResultVO result = new DebtBusinessDayReportResultVO();
// 获取今年第一天
String bgnDt = workDayService.findYearFirstNaturalDay(dataDt);
// 测试用
if (Integer.parseInt(bgnDt)<20250613){
bgnDt = "20250613";
}
// 获取两个日期之间的交易日
List<String> bgnDts = workDayService.findTransDts(bgnDt, dataDt);
// 查询今年年初到指定日期的数据
List<LiquidReportChart> chartCells10 = liquidReportChartRepository.findByDataDtInAndReportCodeAndChartId(bgnDts, debtBusinessDayReport, "chart0010")
.stream()
.filter(chart -> department.equals(chart.getChartName()))
.collect(Collectors.toList());
// 处理chart0010数据,转换为VO列表
List<DebtBusinessDayReportChartVO> vos = chartCells10.stream()
.map(chart -> {
DebtBusinessDayReportChartVO vo = new DebtBusinessDayReportChartVO();
vo.setDataDt(chart.getDataDt());
vo.setReportCode(debtBusinessDayReport);
vo.setDepartment(chart.getChartName());
vo.setChartID(chart.getChartId());
// 提取所有有效的业务类型和值
List<Map<String, String>> values = new ArrayList<>();
// 提取cellValue1-cellValue10中的有效数据对
extractValuePairs(chart.getCellValue1(), chart.getCellValue2(), values);
extractValuePairs(chart.getCellValue3(), chart.getCellValue4(), values);
extractValuePairs(chart.getCellValue5(), chart.getCellValue6(), values);
extractValuePairs(chart.getCellValue7(), chart.getCellValue8(), values);
extractValuePairs(chart.getCellValue9(), chart.getCellValue10(), values);
vo.setValues(values);
return vo;
})
.collect(Collectors.toList());
// 查询chart0020数据
List<LiquidReportChart> chartCells2 = liquidReportChartRepository.findByDataDtInAndReportCodeAndChartId(bgnDts, debtBusinessDayReport, "chart0020");
// 处理chart0020数据
List<DebtBusinessDayReportChartVO> chart2Vos = chartCells2.stream()
.filter(chart -> department.equals(chart.getChartName()))
.collect(Collectors.groupingBy(LiquidReportChart::getDataDt))
.entrySet().stream()
.sorted(Map.Entry.comparingByKey())
.map(entry -> {
String dateDt = entry.getKey();
List<LiquidReportChart> chartsForDate = entry.getValue();
DebtBusinessDayReportChartVO chartVO = new DebtBusinessDayReportChartVO();
chartVO.setDataDt(dateDt);
chartVO.setReportCode(debtBusinessDayReport);
chartVO.setChartID("chart0020");
chartVO.setDepartment(department);
// 提取所有业务类型和金额
List<Map<String, String>> values = chartsForDate.stream()
.filter(chart -> chart.getCellValue1() != null && !chart.getCellValue1().trim().isEmpty() &&
chart.getCellValue2() != null && !chart.getCellValue2().trim().isEmpty())
.map(chart -> {
Map<String, String> item = new HashMap<>();
item.put("name", chart.getCellValue1().trim());
item.put("value", chart.getCellValue2().trim());
return item;
})
.collect(Collectors.toList());
chartVO.setValues(values);
return chartVO;
})
.collect(Collectors.toList());
// 母公司
List<LiquidReportChart> chartCells30 = liquidReportChartRepository.findLiquidReportChartByDataDtAndReportCodeAndChartId(dataDt, debtBusinessDayReport, "chart0030");
// 各部门
List<LiquidReportChart> chartCells40 = liquidReportChartRepository.findLiquidReportChartByDataDtAndReportCodeAndChartId(dataDt, debtBusinessDayReport, "chart0040");
List<LiquidReportChart> chartCells0030 = chartCells30.stream()
.filter(chart -> "母公司汇总".equals(department))
.collect(Collectors.toList());
List<LiquidReportChart> chartCells0040 = chartCells40.stream()
.filter(chart -> department.equals(chart.getChartName()))
.collect(Collectors.toList());
Map<String,Object> map=new HashMap<>();
map.put("chart0010",vos);
map.put("chart0020",chart2Vos);
if ("母公司汇总".equals(department)){
map.put("chart0030",chartCells0030);
}
if (!"母公司汇总".equals(department)){
map.put("chart0040",chartCells0040);
}
result.setCharts(map);
// 并行查询状态信息
Date date = SystemUtil.strToDate(dataDt, "yyyyMMdd");
String reportType = "资产负债业务日报";
CompletableFuture<ReportStatusManage> rsmFuture = CompletableFuture.supplyAsync(() ->
reportStatusRepository.findReportStatusManageByParam(date, reportType));
CompletableFuture<FileStore> fileStoreFuture = CompletableFuture.supplyAsync(() ->
multiClientRepository.findFileStoreByBusiType(reportType + "-" + dataDt));
CompletableFuture<ReportStatusManage> rsmPushFuture = CompletableFuture.supplyAsync(() ->
reportStatusRepository.findReportStatusManageByParam(date, reportType + "推送"));
try {
// 设置超时时间,避免无限等待
ReportStatusManage rsm = rsmFuture.get(30, TimeUnit.SECONDS);
FileStore fileStoreByBusiType = fileStoreFuture.get(30, TimeUnit.SECONDS);
ReportStatusManage rsmPush = rsmPushFuture.get(30, TimeUnit.SECONDS);
// 设置状态,优先级:已推送 > 报告预生成 > 报告预览 > 未生成
if(rsmPush!=null){
result.setStatus("已推送");
} else if(fileStoreByBusiType!=null){
result.setStatus("报告预生成");
} else if(rsm!=null){
result.setStatus("报告预览");
} else {
result.setStatus("未生成");
}
} catch (TimeoutException e) {
logger.error("查询报告状态超时", e);
result.setStatus("查询超时");
} catch (Exception e) {
logger.error("查询报告状态时发生异常", e);
result.setStatus("查询失败");
}
return result;
}
private void extractValuePairs(String name, String value, List<Map<String, String>> values) {
if (name != null && !name.trim().isEmpty() && value != null && !value.trim().isEmpty()) {
Map<String, String> item = new HashMap<>();
item.put("name", name.trim());
item.put("value", value.trim());
values.add(item);
}
}
}
检查一下代码有没有问题
最新发布