1、防水涂料修改

2、定时器同步应收明细错误
3、销售BI汇总销量销额过滤防水涂料取值问题
This commit is contained in:
llllon 2025-09-26 16:25:21 +08:00
parent 639f338c38
commit 3b544b04a2
7 changed files with 546 additions and 298 deletions

View File

@ -6,7 +6,6 @@ import com.actionsoft.bpms.schedule.IJob;
import com.actionsoft.bpms.server.UserContext; import com.actionsoft.bpms.server.UserContext;
import com.actionsoft.bpms.util.DBSql; import com.actionsoft.bpms.util.DBSql;
import com.actionsoft.sdk.local.SDK; import com.actionsoft.sdk.local.SDK;
import com.actionsoft.sdk.local.api.cc.RDSAPI;
import com.awspaas.user.apps.bnbm.datalinkup.enums.Section; import com.awspaas.user.apps.bnbm.datalinkup.enums.Section;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
import org.quartz.JobExecutionContext; import org.quartz.JobExecutionContext;
@ -19,27 +18,27 @@ import java.time.LocalDate;
import java.time.ZoneId; import java.time.ZoneId;
import java.time.format.DateTimeFormatter; import java.time.format.DateTimeFormatter;
import java.util.*; import java.util.*;
import java.util.stream.Collectors;
/** /**
* @ClassName: WaterproofPaintAccountsReceivableJob * @ClassName: WaterproofPaintAccountsReceivableJob
* @Description: 防水涂料计算应收单 - 每月最大日期版本月末按昨天查询 * @Description: 防水涂料计算应收单 - 优化版本批量处理提升性能
* @date: 2025/8/29 16:38 * @date: 2025/8/29 16:38
* @Blog: https://
*/ */
public class WaterproofPaintAccountsReceivableJob implements IJob { public class WaterproofPaintAccountsReceivableJob implements IJob {
private static final Logger LOGGER = LoggerFactory.getLogger(WaterproofPaintAccountsReceivableJob.class); private static final Logger LOGGER = LoggerFactory.getLogger(WaterproofPaintAccountsReceivableJob.class);
// 定义常量 // 定义常量
private static final String RDS_ID = "e19d738a-8eac-4c42-9c08-7fe93e75638d"; private static final String RDS_ID = "e19d738a-8eac-4c42-9c08-7fe93e75638d";
private static final String DEFAULT_BKGS_FS = "北新防水";
private static final String DEFAULT_BKGS_TL = "北新涂料";
private static final int BATCH_SIZE = 1000; private static final int BATCH_SIZE = 1000;
private static final int CUSTOMER_BATCH_SIZE = 500; // 客户分批大小
@Override @Override
public void execute(JobExecutionContext job) throws JobExecutionException { public void execute(JobExecutionContext job) throws JobExecutionException {
try { try {
String param = SDK.getJobAPI().getJobParameter(job); String param = SDK.getJobAPI().getJobParameter(job);
int timeRange = StringUtils.isNotBlank(param) ? Integer.parseInt(param) : 0; int timeRange = StringUtils.isNotBlank(param) ? Integer.parseInt(param) : 0;
// 获取当前时间 // 获取当前时间
LocalDate nowDate = LocalDate.now(); LocalDate nowDate = LocalDate.now();
LocalDate startDate; LocalDate startDate;
@ -49,17 +48,19 @@ public class WaterproofPaintAccountsReceivableJob implements IJob {
// 默认计算去年第一天到现在的数据 // 默认计算去年第一天到现在的数据
startDate = nowDate.minusYears(1).withDayOfYear(1); startDate = nowDate.minusYears(1).withDayOfYear(1);
} }
LOGGER.info("开始执行防水涂料应收单计算任务,时间范围:{} 到 {}", startDate, nowDate); LOGGER.info("开始执行防水涂料应收单计算任务,时间范围:{} 到 {}", startDate, nowDate);
// 依次处理防水和涂料两个板块 // 依次处理防水和涂料两个板块
boolean allSuccess = true; boolean allSuccess = true;
for (Section section : Section.values()) { for (Section section : Section.values()) {
boolean success = processSection(section, startDate, nowDate); boolean success = processSectionOptimized(section, startDate, nowDate);
if (!success) { if (!success) {
allSuccess = false; allSuccess = false;
LOGGER.error("{}板块处理失败", section.getName()); LOGGER.error("{}板块处理失败", section.getName());
} }
} }
if (!allSuccess) { if (!allSuccess) {
throw new JobExecutionException("部分板块处理失败"); throw new JobExecutionException("部分板块处理失败");
} }
@ -72,119 +73,48 @@ public class WaterproofPaintAccountsReceivableJob implements IJob {
} }
/** /**
* 处理单个板块的数据 * 优化后的板块数据处理方法
* @param section 板块配置
* @param startDate 开始日期
* @param nowDate 结束日期
* @return 处理是否成功
*/ */
private boolean processSection(Section section, LocalDate startDate, LocalDate nowDate) { private boolean processSectionOptimized(Section section, LocalDate startDate, LocalDate endDate) {
String sectionName = section.getName(); String sectionName = section.getName();
LOGGER.info("开始处理{}板块数据,时间范围:{} 到 {}", sectionName, startDate, nowDate); LOGGER.info("开始处理{}板块数据,时间范围:{} 到 {}", sectionName, startDate, endDate);
try { try {
// 开始清理开始时间到结束时间的数据后再进行计算更新数据 // 清理目标表数据
String startDateFormat = startDate.format(DateTimeFormatter.ofPattern("yyyy-MM-dd")) + " 00:00:00"; String startDateFormat = startDate.format(DateTimeFormatter.ofPattern("yyyy-MM-dd")) + " 00:00:00";
String nowDateFormat = nowDate.format(DateTimeFormatter.ofPattern("yyyy-MM-dd"))+" 23:59:59"; int deleteCount = DBSql.update("DELETE FROM " + section.getTargetTable() + " WHERE RQ >= ?", new String[]{startDateFormat});
int delete = DBSql.update("DELETE FROM " + section.getTargetTable() + LOGGER.info("已删除目标表[{}]中{}条数据", section.getTargetTable(), deleteCount);
" WHERE RQ >= '" + startDateFormat + "' ");
LOGGER.info("已删除目标表[{}]中{}条数据(时间范围: {} )",
section.getTargetTable(), delete, startDateFormat);
// 查询销售组织和客户分组信息 // 获取所有销售组织-客户组合
List<RowMap> maps = DBSql.getMaps("SELECT QYGS, FCUSTNAME, SQ AS FPROVINCE,CS AS FCITY,QY AS FDISTRICT ,XSZZ FROM " + List<RowMap> customerMaps = DBSql.getMaps(
section.getYsdTable() + " WHERE QYGS IS NOT NULL GROUP BY QYGS, FCUSTNAME, SQ,CS"); "SELECT DISTINCT QYGS, FCUSTNAME, SQ AS FPROVINCE, CS AS FCITY, QY AS FDISTRICT, XSZZ " +
"FROM " + section.getYsdTable() + " WHERE QYGS IS NOT NULL AND FCUSTNAME IS NOT NULL"
if (maps == null || maps.isEmpty()) {
LOGGER.warn("{}板块未查询到销售组织和客户数据", sectionName);
return true; // 没有数据也算成功
}
LOGGER.info("{}板块共查询到 {} 个销售组织-客户组合", sectionName, maps.size());
// 用于批量插入的数据列表
List<BO> batchData = new ArrayList<>();
int processedCount = 0;
// 获取每个月的最大日期月末日期
List<LocalDate> monthEndDates = getMonthEndDates(startDate, nowDate);
LOGGER.info("{}板块将处理 {} 个月末日期", sectionName, monthEndDates.size());
// 遍历每个月末日期
for (LocalDate monthEndDate : monthEndDates) {
LOGGER.info("{}板块正在处理月末日期: {}", sectionName, monthEndDate);
// 计算该月的日期范围月初到月末或昨天
LocalDate monthStartDate = monthEndDate.withDayOfMonth(1);
LocalDate monthEnd = monthEndDate;
// 遍历每个销售组织-客户组合
for (RowMap row : maps) {
try {
String manageRegionName = row.getString("QYGS");
String saleOrgUnit = row.getString("XSZZ");
String custName = row.getString("FCUSTNAME");
// LOGGER.info("manageRegionName:{};saleOrgUnit:{},custName:{}",manageRegionName,saleOrgUnit,custName);
// 查询省市区信息
String province = row != null ? row.getString("FPROVINCE") : "";
String city = row != null ? row.getString("FCITY") : "";
String district = row != null ? row.getString("FDISTRICT")!=null ? row.getString("FDISTRICT"):"": "";
// 计算期初余额上一年度
LocalDate previousYearStart = monthStartDate.minusYears(1).withDayOfYear(1);
LocalDate previousYearEnd = monthStartDate.minusYears(1).withDayOfYear(365);
BigDecimal qcye = calculateInitialBalance(section, saleOrgUnit, custName, previousYearStart, previousYearEnd);
// 计算累计销售本年年初到查询截止日期
LocalDate yearStart = monthStartDate.withDayOfYear(1);
BigDecimal ljxs = calculateTotalSales(section, saleOrgUnit, custName, monthEndDate, monthEnd);
// 计算累计还款本年年初到查询截止日期
BigDecimal ljhk = calculateTotalRepayment(section, saleOrgUnit, custName, monthEndDate, monthEnd);
// 计算应收余额
BigDecimal ysye = qcye.add(ljxs).subtract(ljhk);
// LOGGER.info("计算应收余额={}",ysye.doubleValue());
// 计算账龄分析需要查询历史数据
Map<String, BigDecimal> zlfx = calculateMonthlyAgingAnalysis(section, saleOrgUnit, custName, monthEndDate, ysye);
// for (String key: zlfx.keySet()){
// LOGGER.info("账龄-{}={}",key,zlfx.get(key));
// }
// 创建数据记录记录日期仍使用月末日期
BO record = createRecord(
section, manageRegionName, saleOrgUnit, monthEndDate, custName,
province, city, district, qcye, ljxs, ljhk, ysye, zlfx
); );
batchData.add(record); if (customerMaps == null || customerMaps.isEmpty()) {
LOGGER.warn("{}板块未查询到销售组织和客户数据", sectionName);
// 批量插入 return true;
if (batchData.size() >= BATCH_SIZE) {
batchInsert(section, batchData);
batchData.clear();
} }
// 更新处理计数 LOGGER.info("{}板块共查询到 {} 个销售组织-客户组合", sectionName, customerMaps.size());
processedCount++;
if (processedCount % 1000 == 0) {
LOGGER.info("{}板块已处理 {} 条记录", sectionName, processedCount);
}
} catch (Exception e) { // 分批次处理客户数据
LOGGER.error("{}板块处理销售组织 {} 客户 {} 月末日期 {} 时发生错误", int totalCustomers = customerMaps.size();
sectionName, row.getString("XSZZ"), row.getString("FCUSTNAME"), monthEndDate, e); for (int i = 0; i < totalCustomers; i += CUSTOMER_BATCH_SIZE) {
} int endIndex = Math.min(i + CUSTOMER_BATCH_SIZE, totalCustomers);
List<RowMap> batchCustomers = customerMaps.subList(i, endIndex);
LOGGER.info("{}板块正在处理第 {} 批客户,进度: {}/{}",
sectionName, (i / CUSTOMER_BATCH_SIZE) + 1, endIndex, totalCustomers);
boolean batchSuccess = processCustomerBatch(section, batchCustomers, startDate, endDate);
if (!batchSuccess) {
LOGGER.error("{}板块第 {} 批客户处理失败", sectionName, (i / CUSTOMER_BATCH_SIZE) + 1);
return false;
} }
} }
// 插入剩余数据 LOGGER.info("{}板块数据处理完成,共处理 {} 个客户组合", sectionName, totalCustomers);
if (!batchData.isEmpty()) {
batchInsert(section, batchData);
}
LOGGER.info("{}板块数据处理完成,共处理 {} 条记录", sectionName, processedCount);
return true; return true;
} catch (Exception e) { } catch (Exception e) {
@ -194,179 +124,403 @@ public class WaterproofPaintAccountsReceivableJob implements IJob {
} }
/** /**
* 判断是否为当前月月末 * 处理一批客户数据
* @param monthEndDate 月末日期
* @param nowDate 当前日期
* @return 是否为当前月月末
*/ */
private boolean isCurrentMonthEnd(LocalDate monthEndDate, LocalDate nowDate) { private boolean processCustomerBatch(Section section, List<RowMap> customerBatch,
// 判断是否为当前月的月末并且月末日期大于或等于当前日期
return monthEndDate.getMonth() == nowDate.getMonth() &&
monthEndDate.getYear() == nowDate.getYear() &&
monthEndDate.getDayOfMonth() == monthEndDate.lengthOfMonth() &&
monthEndDate.isAfter(nowDate.minusDays(1)); // 确保是当前月月末
}
/**
* 获取时间范围内的所有月末日期
*/
private List<LocalDate> getMonthEndDates(LocalDate startDate, LocalDate endDate) {
List<LocalDate> monthEndDates = new ArrayList<>();
LocalDate current = startDate.withDayOfMonth(1);
while (!current.isAfter(endDate)) {
// 如果当前月份与endDate不是同年同月
if (current.getYear() != endDate.getYear() || current.getMonth() != endDate.getMonth()) {
LocalDate monthEnd = current.withDayOfMonth(current.lengthOfMonth());
// 确保月末日期在时间范围内
if (!monthEnd.isBefore(startDate) && !monthEnd.isAfter(endDate)) {
monthEndDates.add(monthEnd);
}
}
// 如果当前月份与endDate是同年同月
else {
LocalDate dayBeforeEnd = endDate.minusDays(1);
// 确保前一天在时间范围内
if (!dayBeforeEnd.isBefore(startDate)) {
monthEndDates.add(dayBeforeEnd);
}
break; // 遇到同年同月后就可以结束循环了
}
current = current.plusMonths(1);
}
return monthEndDates;
}
/**
* 计算期初余额
*/
private BigDecimal calculateInitialBalance(Section section, String saleOrgUnit, String custName,
LocalDate startDate, LocalDate endDate) { LocalDate startDate, LocalDate endDate) {
String startDateStr = startDate.format(DateTimeFormatter.ofPattern("yyyy-MM-dd"))+" 00:00:00";
String endDateStr = endDate.format(DateTimeFormatter.ofPattern("yyyy-MM-dd"))+" 23:59:59";
try { try {
// 查询应收单总额 // 提取销售组织和客户名称列表
RowMap ysResult = DBSql.getMap( List<String> saleOrgUnits = customerBatch.stream()
"SELECT SUM(SSJERMB) as total FROM " + section.getYsdTable() + .map(row -> row.getString("XSZZ"))
" WHERE XSZZ = ? AND FCUSTNAME = ? AND DZRQ >= ? AND DZRQ< ?", .distinct()
saleOrgUnit, custName, startDateStr, endDateStr .collect(Collectors.toList());
List<String> custNames = customerBatch.stream()
.map(row -> row.getString("FCUSTNAME"))
.distinct()
.collect(Collectors.toList());
// 获取需要处理的所有月末日期
List<LocalDate> monthEndDates = getMonthEndDates(startDate, endDate);
// 批量预加载所有需要的数据
Map<String, BigDecimal> preloadedResults = preloadAllData(
section, saleOrgUnits, custNames, monthEndDates);
// 批量处理数据
List<BO> allRecords = new ArrayList<>();
for (LocalDate monthEndDate : monthEndDates) {
for (RowMap customer : customerBatch) {
String saleOrgUnit = customer.getString("XSZZ");
String custName = customer.getString("FCUSTNAME");
String keyPrefix = saleOrgUnit + "_" + custName + "_";
try {
// 从预加载数据中获取计算结果
BigDecimal qcye = getPreloadedValue(preloadedResults, keyPrefix + "QCYE_" + monthEndDate);
BigDecimal ljxs = getPreloadedValue(preloadedResults, keyPrefix + "LJXS_" + monthEndDate);
BigDecimal ljhk = getPreloadedValue(preloadedResults, keyPrefix + "LJHK_" + monthEndDate);
BigDecimal ysye = qcye.add(ljxs).subtract(ljhk);
// 从预加载数据中获取账龄分析
Map<String, BigDecimal> zlfx = new HashMap<>();
for (String zlfxKey : Arrays.asList("ZLFX0_60", "ZLFX60_1", "ZLFX1_2", "ZLFX2_3", "ZLFX3_4", "ZLFX4_5", "ZLFX5")) {
BigDecimal value = getPreloadedValue(preloadedResults, keyPrefix + zlfxKey + "_" + monthEndDate);
zlfx.put(zlfxKey, value);
}
// 创建记录
BO record = createRecord(
section,
customer.getString("QYGS"),
saleOrgUnit,
monthEndDate,
custName,
customer.getString("FPROVINCE"),
customer.getString("FCITY"),
customer.getString("FDISTRICT") != null ? customer.getString("FDISTRICT") : "",
qcye, ljxs, ljhk, ysye, zlfx
); );
// LOGGER.info("期初余额-应收单总额sql:SELECT SUM(SSJERMB) as total FROM " + section.getYsdTable() +
// " WHERE XSZZ = "+saleOrgUnit+" AND FCUSTNAME = "+custName+" AND DZRQ >= "+startDateStr+" AND DZRQ< "+endDateStr+"");
BigDecimal ysTotal = ysResult != null && ysResult.get("total") != null ? allRecords.add(record);
new BigDecimal(ysResult.get("total").toString()) : BigDecimal.ZERO;
// 查询收款单总额
RowMap skResult = DBSql.getMap(
"SELECT SUM(FSALEAMOUNTRMB) as total FROM " + section.getSkdTable() +
" WHERE FSALEORGUNIT = ? AND FCUSTNAME = ? AND FBILLDATE >= ? AND FBILLDATE < ?",
saleOrgUnit, custName, startDateStr, endDateStr
);
// LOGGER.info("期初余额-收款单总额sql:SELECT SUM(FSALEAMOUNTRMB) as total FROM " + section.getSkdTable() +
// " WHERE FSALEORGUNIT = "+saleOrgUnit+" AND FCUSTNAME = "+custName+" AND FBILLDATE >= "+startDateStr+" AND FBILLDATE< "+endDateStr+"");
BigDecimal skTotal = skResult != null && skResult.get("total") != null ?
new BigDecimal(skResult.get("total").toString()) : BigDecimal.ZERO;
// 查询收款退款单总额
RowMap sktkResult = DBSql.getMap(
"SELECT SUM(FSALEAMOUNTRMB) as total FROM " + section.getSktkdTable() +
" WHERE FSALEORGUNIT = ? AND FCUSTNAME = ? AND FBILLDATE >= ? AND FBILLDATE < ?",
saleOrgUnit, custName, startDateStr, endDateStr
);
// LOGGER.info("期初余额-收款退款单总额sql:SELECT SUM(FSALEAMOUNTRMB) as total FROM " + section.getSktkdTable() +
// " WHERE FSALEORGUNIT = "+saleOrgUnit+" AND FCUSTNAME = "+custName+" AND FBILLDATE >= "+startDateStr+" AND FBILLDATE< "+endDateStr+"");
BigDecimal sktkTotal = sktkResult != null && sktkResult.get("total") != null ?
new BigDecimal(sktkResult.get("total").toString()) : BigDecimal.ZERO;
// LOGGER.info("期初余额:{}",sktkTotal.doubleValue());
// 期初余额 = 应收单总额 - 收款单总额 + 收款退款单总额
return ysTotal.subtract(skTotal).add(sktkTotal);
} catch (Exception e) { } catch (Exception e) {
LOGGER.error("计算{}板块期初余额时发生错误,销售组织: {}, 客户: {}", section.getName(), saleOrgUnit, custName, e); LOGGER.error("处理客户数据时发生错误,销售组织: {}, 客户: {}, 日期: {}",
return BigDecimal.ZERO; saleOrgUnit, custName, monthEndDate, e);
}
} }
} }
/** // 分批插入数据
* 计算累计销售 for (int i = 0; i < allRecords.size(); i += BATCH_SIZE) {
*/ int endIndex = Math.min(i + BATCH_SIZE, allRecords.size());
private BigDecimal calculateTotalSales(Section section, String saleOrgUnit, String custName, List<BO> batchRecords = allRecords.subList(i, endIndex);
LocalDate startDate, LocalDate endDate) { batchInsert(section, batchRecords);
String startDateStr = startDate.format(DateTimeFormatter.ofPattern("yyyy-MM-dd"))+" 00:00:00"; }
String endDateStr = endDate.format(DateTimeFormatter.ofPattern("yyyy-MM-dd"))+" 23:59:59";
try {
RowMap result = DBSql.getMap(
"SELECT SUM(SSJERMB) as total FROM " + section.getYsdTable() +
" WHERE XSZZ = ? AND FCUSTNAME = ? AND DZRQ >= ? AND DZRQ < ?",
saleOrgUnit, custName, startDateStr, endDateStr
);
// LOGGER.info("计算累计销售SELECT SUM(SSJERMB) as total FROM " + section.getYsdTable() +
// " WHERE XSZZ = "+saleOrgUnit+" AND FCUSTNAME = "+custName+" AND DZRQ >= "+startDateStr+" AND DZRQ < "+endDateStr+"");
// LOGGER.info("累计销售={}",result != null && result.get("total") != null ? return true;
// new BigDecimal(result.get("total").toString()) : BigDecimal.ZERO);
return result != null && result.get("total") != null ?
new BigDecimal(result.get("total").toString()) : BigDecimal.ZERO;
} catch (Exception e) { } catch (Exception e) {
LOGGER.error("计算{}板块累计销售时发生错误,销售组织: {}, 客户: {}", section.getName(), saleOrgUnit, custName, e); LOGGER.error("处理客户批次数据时发生错误", e);
return BigDecimal.ZERO; return false;
} }
} }
/** /**
* 计算累计还款 * 安全获取预加载值
*/ */
private BigDecimal calculateTotalRepayment(Section section, String saleOrgUnit, String custName, private BigDecimal getPreloadedValue(Map<String, BigDecimal> preloadedData, String key) {
LocalDate startDate, LocalDate endDate) { return preloadedData.getOrDefault(key, BigDecimal.ZERO);
String startDateStr = startDate.format(DateTimeFormatter.ofPattern("yyyy-MM-dd"))+" 00:00:00"; }
String endDateStr = endDate.format(DateTimeFormatter.ofPattern("yyyy-MM-dd"))+" 23:59:59";
/**
* 预加载所有需要的数据
*/
private Map<String, BigDecimal> preloadAllData(Section section,
List<String> saleOrgUnits, List<String> custNames, List<LocalDate> monthEndDates) {
Map<String, BigDecimal> results = new HashMap<>();
try { try {
// 查询收款单总额 // 批量查询应收单数据
RowMap skResult = DBSql.getMap( Map<String, BigDecimal> ysData = batchQueryYSDData(section, saleOrgUnits, custNames, monthEndDates);
"SELECT SUM(FSALEAMOUNTRMB) as total FROM " + section.getSkdTable() +
" WHERE FSALEORGUNIT = ? AND FCUSTNAME = ? AND FBILLDATE >= ? AND FBILLDATE < ?",
saleOrgUnit, custName, startDateStr, endDateStr
);
// LOGGER.info("计算累计还款:SELECT SUM(FSALEAMOUNTRMB) as total FROM " + section.getSkdTable() +
// " WHERE FSALEORGUNIT = "+saleOrgUnit+" AND FCUSTNAME = "+custName+" AND FBILLDATE >= "+startDateStr+" AND FBILLDATE < "+endDateStr+"");
BigDecimal skTotal = skResult != null && skResult.get("total") != null ? // 批量查询收款单数据
new BigDecimal(skResult.get("total").toString()) : BigDecimal.ZERO; Map<String, BigDecimal> skData = batchQuerySKDData(section, saleOrgUnits, custNames, monthEndDates);
// 查询收款退款单总额 // 批量查询收款退款单数据
RowMap sktkResult = DBSql.getMap( Map<String, BigDecimal> sktkData = batchQuerySKTKDData(section, saleOrgUnits, custNames, monthEndDates);
"SELECT SUM(FSALEAMOUNTRMB) as total FROM " + section.getSktkdTable() +
" WHERE FSALEORGUNIT = ? AND FCUSTNAME = ? AND FBILLDATE >= ? AND FBILLDATE < ?",
saleOrgUnit, custName, startDateStr, endDateStr
);
// LOGGER.info("计算累计还款:SELECT SUM(FSALEAMOUNTRMB) as total FROM " + section.getSktkdTable() +
// " WHERE FSALEORGUNIT = "+saleOrgUnit+" AND FCUSTNAME = "+custName+" AND FBILLDATE >= "+startDateStr+" AND FBILLDATE < "+endDateStr+"");
BigDecimal sktkTotal = sktkResult != null && sktkResult.get("total") != null ? // 批量查询历史余额数据
new BigDecimal(sktkResult.get("total").toString()) : BigDecimal.ZERO; Map<String, BigDecimal> historyData = batchQueryHistoryBalance(section, saleOrgUnits, custNames, monthEndDates);
// LOGGER.info("累计还款={}",skTotal.subtract(sktkTotal).doubleValue());
// 累计还款 = 收款单总额 - 收款退款单总额 // 计算所有需要的指标
return skTotal.subtract(sktkTotal); calculateAllMetrics(results, ysData, skData, sktkData, historyData, saleOrgUnits, custNames, monthEndDates);
} catch (Exception e) { } catch (Exception e) {
LOGGER.error("计算{}板块累计还款时发生错误,销售组织: {}, 客户: {}", section.getName(), saleOrgUnit, custName, e); LOGGER.error("预加载数据时发生错误", e);
return BigDecimal.ZERO;
} }
return results;
} }
/** /**
* 计算月度账龄分析 * 批量查询应收单数据
*/ */
private Map<String, BigDecimal> calculateMonthlyAgingAnalysis(Section section, String saleOrgUnit, String custName, private Map<String, BigDecimal> batchQueryYSDData(Section section, List<String> saleOrgUnits,
LocalDate currentDate, BigDecimal currentBalance) { List<String> custNames, List<LocalDate> monthEndDates) {
Map<String, BigDecimal> result = new HashMap<>();
if (saleOrgUnits.isEmpty() || custNames.isEmpty() || monthEndDates.isEmpty()) {
return result;
}
try {
String inSaleOrgs = buildInCondition(saleOrgUnits);
String inCustNames = buildInCondition(custNames);
// 构建日期条件
StringBuilder dateCondition = new StringBuilder();
for (LocalDate date : monthEndDates) {
LocalDate monthStart = date.withDayOfMonth(1);
if (dateCondition.length() > 0) {
dateCondition.append(" OR ");
}
dateCondition.append("(DZRQ >= '")
.append(monthStart.format(DateTimeFormatter.ofPattern("yyyy-MM-dd")))
.append(" 00:00:00' AND DZRQ <= '")
.append(date.format(DateTimeFormatter.ofPattern("yyyy-MM-dd")))
.append(" 23:59:59')");
}
String sql = "SELECT XSZZ, FCUSTNAME, DATE_FORMAT(DZRQ, '%Y-%m-%d') as BILL_DATE, SUM(SSJERMB) as TOTAL " +
"FROM " + section.getYsdTable() +
" WHERE XSZZ IN (" + inSaleOrgs + ") " +
" AND FCUSTNAME IN (" + inCustNames + ") " +
" AND (" + dateCondition + ") " +
" GROUP BY XSZZ, FCUSTNAME, DATE_FORMAT(DZRQ, '%Y-%m-%d')";
List<RowMap> queryResults = DBSql.getMaps(sql);
for (RowMap row : queryResults) {
String key = row.getString("XSZZ") + "_" + row.getString("FCUSTNAME") + "_" + row.getString("BILL_DATE");
BigDecimal value = row.get("TOTAL") != null ? new BigDecimal(row.get("TOTAL").toString()) : BigDecimal.ZERO;
result.put(key, value);
}
} catch (Exception e) {
LOGGER.error("批量查询应收单数据时发生错误", e);
}
return result;
}
/**
* 批量查询收款单数据
*/
private Map<String, BigDecimal> batchQuerySKDData(Section section, List<String> saleOrgUnits,
List<String> custNames, List<LocalDate> monthEndDates) {
Map<String, BigDecimal> result = new HashMap<>(); Map<String, BigDecimal> result = new HashMap<>();
try { try {
// 计算各个时间点的应收余额 String inSaleOrgs = buildInCondition(saleOrgUnits);
String inCustNames = buildInCondition(custNames);
StringBuilder dateCondition = new StringBuilder();
for (LocalDate date : monthEndDates) {
LocalDate monthStart = date.withDayOfMonth(1);
if (dateCondition.length() > 0) {
dateCondition.append(" OR ");
}
dateCondition.append("(FBILLDATE >= '")
.append(monthStart.format(DateTimeFormatter.ofPattern("yyyy-MM-dd")))
.append(" 00:00:00' AND FBILLDATE <= '")
.append(date.format(DateTimeFormatter.ofPattern("yyyy-MM-dd")))
.append(" 23:59:59')");
}
String sql = "SELECT FSALEORGUNIT, FCUSTNAME, DATE_FORMAT(FBILLDATE, '%Y-%m-%d') as BILL_DATE, SUM(FSALEAMOUNTRMB) as TOTAL " +
"FROM " + section.getSkdTable() +
" WHERE FSALEORGUNIT IN (" + inSaleOrgs + ") " +
" AND FCUSTNAME IN (" + inCustNames + ") " +
" AND (" + dateCondition + ") " +
" GROUP BY FSALEORGUNIT, FCUSTNAME, DATE_FORMAT(FBILLDATE, '%Y-%m-%d')";
List<RowMap> queryResults = DBSql.getMaps(sql);
for (RowMap row : queryResults) {
String key = row.getString("FSALEORGUNIT") + "_" + row.getString("FCUSTNAME") + "_" + row.getString("BILL_DATE");
BigDecimal value = row.get("TOTAL") != null ? new BigDecimal(row.get("TOTAL").toString()) : BigDecimal.ZERO;
result.put(key, value);
}
} catch (Exception e) {
LOGGER.error("批量查询收款单数据时发生错误", e);
}
return result;
}
/**
* 批量查询收款退款单数据
*/
private Map<String, BigDecimal> batchQuerySKTKDData(Section section, List<String> saleOrgUnits,
List<String> custNames, List<LocalDate> monthEndDates) {
Map<String, BigDecimal> result = new HashMap<>();
try {
String inSaleOrgs = buildInCondition(saleOrgUnits);
String inCustNames = buildInCondition(custNames);
StringBuilder dateCondition = new StringBuilder();
for (LocalDate date : monthEndDates) {
LocalDate monthStart = date.withDayOfMonth(1);
if (dateCondition.length() > 0) {
dateCondition.append(" OR ");
}
dateCondition.append("(FBILLDATE >= '")
.append(monthStart.format(DateTimeFormatter.ofPattern("yyyy-MM-dd")))
.append(" 00:00:00' AND FBILLDATE <= '")
.append(date.format(DateTimeFormatter.ofPattern("yyyy-MM-dd")))
.append(" 23:59:59')");
}
String sql = "SELECT FSALEORGUNIT, FCUSTNAME, DATE_FORMAT(FBILLDATE, '%Y-%m-%d') as BILL_DATE, SUM(FSALEAMOUNTRMB) as TOTAL " +
"FROM " + section.getSktkdTable() +
" WHERE FSALEORGUNIT IN (" + inSaleOrgs + ") " +
" AND FCUSTNAME IN (" + inCustNames + ") " +
" AND (" + dateCondition + ") " +
" GROUP BY FSALEORGUNIT, FCUSTNAME, DATE_FORMAT(FBILLDATE, '%Y-%m-%d')";
List<RowMap> queryResults = DBSql.getMaps(sql);
for (RowMap row : queryResults) {
String key = row.getString("FSALEORGUNIT") + "_" + row.getString("FCUSTNAME") + "_" + row.getString("BILL_DATE");
BigDecimal value = row.get("TOTAL") != null ? new BigDecimal(row.get("TOTAL").toString()) : BigDecimal.ZERO;
result.put(key, value);
}
} catch (Exception e) {
LOGGER.error("批量查询收款退款单数据时发生错误", e);
}
return result;
}
/**
* 批量查询历史余额数据
*/
private Map<String, BigDecimal> batchQueryHistoryBalance(Section section, List<String> saleOrgUnits,
List<String> custNames, List<LocalDate> monthEndDates) {
Map<String, BigDecimal> result = new HashMap<>();
try {
String inSaleOrgs = buildInCondition(saleOrgUnits);
String inCustNames = buildInCondition(custNames);
String inDates = monthEndDates.stream()
.map(date -> "'" + date.format(DateTimeFormatter.ofPattern("yyyy-MM-dd")) + " 23:59:59'")
.collect(Collectors.joining(","));
String sql = "SELECT XSZZ, KH, DATE_FORMAT(RQ, '%Y-%m-%d') as BALANCE_DATE, YSYE " +
"FROM " + section.getTargetTable() +
" WHERE XSZZ IN (" + inSaleOrgs + ") " +
" AND KH IN (" + inCustNames + ") " +
" AND RQ IN (" + inDates + ")";
List<RowMap> queryResults = DBSql.getMaps(sql);
for (RowMap row : queryResults) {
String key = row.getString("XSZZ") + "_" + row.getString("KH") + "_" + row.getString("BALANCE_DATE");
BigDecimal value = row.get("YSYE") != null ? new BigDecimal(row.get("YSYE").toString()) : BigDecimal.ZERO;
result.put(key, value);
}
} catch (Exception e) {
LOGGER.error("批量查询历史余额数据时发生错误", e);
}
return result;
}
/**
* 计算所有指标
*/
private void calculateAllMetrics(Map<String, BigDecimal> results,
Map<String, BigDecimal> ysData, Map<String, BigDecimal> skData,
Map<String, BigDecimal> sktkData, Map<String, BigDecimal> historyData,
List<String> saleOrgUnits, List<String> custNames, List<LocalDate> monthEndDates) {
// 计算每个客户每个月的指标
for (String saleOrgUnit : saleOrgUnits) {
for (String custName : custNames) {
String keyPrefix = saleOrgUnit + "_" + custName + "_";
for (LocalDate monthEndDate : monthEndDates) {
String dateKey = monthEndDate.format(DateTimeFormatter.ofPattern("yyyy-MM-dd"));
String fullKeyPrefix = keyPrefix + dateKey;
// 计算期初余额上一年度累计
LocalDate previousYearStart = monthEndDate.minusYears(1).withDayOfYear(1);
LocalDate previousYearEnd = monthEndDate.minusYears(1).withDayOfYear(365);
BigDecimal qcye = calculatePeriodBalance(ysData, skData, sktkData, saleOrgUnit, custName, previousYearStart, previousYearEnd);
// 计算累计销售本年年初到当前月末
LocalDate yearStart = monthEndDate.withDayOfYear(1);
BigDecimal ljxs = calculatePeriodBalance(ysData, null, null, saleOrgUnit, custName, yearStart, monthEndDate);
// 计算累计还款本年年初到当前月末
BigDecimal ljhk = calculatePeriodBalance(null, skData, sktkData, saleOrgUnit, custName, yearStart, monthEndDate);
// 计算应收余额
BigDecimal ysye = qcye.add(ljxs).subtract(ljhk);
// 计算账龄分析
Map<String, BigDecimal> zlfx = calculateAgingAnalysis(historyData, saleOrgUnit, custName, monthEndDate, ysye);
// 存储计算结果
results.put(keyPrefix + "QCYE_" + monthEndDate, qcye);
results.put(keyPrefix + "LJXS_" + monthEndDate, ljxs);
results.put(keyPrefix + "LJHK_" + monthEndDate, ljhk);
results.put(keyPrefix + "YSYE_" + monthEndDate, ysye);
for (Map.Entry<String, BigDecimal> entry : zlfx.entrySet()) {
results.put(keyPrefix + entry.getKey() + "_" + monthEndDate, entry.getValue());
}
}
}
}
}
/**
* 计算指定时间段的余额
*/
private BigDecimal calculatePeriodBalance(Map<String, BigDecimal> ysData, Map<String, BigDecimal> skData,
Map<String, BigDecimal> sktkData, String saleOrgUnit, String custName,
LocalDate startDate, LocalDate endDate) {
BigDecimal result = BigDecimal.ZERO;
String keyPrefix = saleOrgUnit + "_" + custName + "_";
// 累加指定时间段内的数据
LocalDate current = startDate;
while (!current.isAfter(endDate)) {
String dateKey = current.format(DateTimeFormatter.ofPattern("yyyy-MM-dd"));
String fullKey = keyPrefix + dateKey;
if (ysData != null) {
result = result.add(ysData.getOrDefault(fullKey, BigDecimal.ZERO));
}
if (skData != null) {
result = result.subtract(skData.getOrDefault(fullKey, BigDecimal.ZERO));
}
if (sktkData != null) {
result = result.add(sktkData.getOrDefault(fullKey, BigDecimal.ZERO));
}
current = current.plusDays(1);
}
return result;
}
/**
* 计算账龄分析
*/
private Map<String, BigDecimal> calculateAgingAnalysis(Map<String, BigDecimal> historyData,
String saleOrgUnit, String custName, LocalDate currentDate, BigDecimal currentBalance) {
Map<String, BigDecimal> result = new HashMap<>();
String keyPrefix = saleOrgUnit + "_" + custName + "_";
try {
// 计算各个时间点的历史余额
LocalDate date60DaysAgo = currentDate.minusDays(60); LocalDate date60DaysAgo = currentDate.minusDays(60);
LocalDate date1YearAgo = currentDate.minusYears(1); LocalDate date1YearAgo = currentDate.minusYears(1);
LocalDate date2YearsAgo = currentDate.minusYears(2); LocalDate date2YearsAgo = currentDate.minusYears(2);
@ -374,13 +528,13 @@ public class WaterproofPaintAccountsReceivableJob implements IJob {
LocalDate date4YearsAgo = currentDate.minusYears(4); LocalDate date4YearsAgo = currentDate.minusYears(4);
LocalDate date5YearsAgo = currentDate.minusYears(5); LocalDate date5YearsAgo = currentDate.minusYears(5);
// 询历史月末的应收余额 // 找历史余额
BigDecimal balance60DaysAgo = findMonthlyBalance(section, saleOrgUnit, custName, date60DaysAgo); BigDecimal balance60DaysAgo = findHistoricalBalance(historyData, keyPrefix, date60DaysAgo);
BigDecimal balance1YearAgo = findMonthlyBalance(section, saleOrgUnit, custName, date1YearAgo); BigDecimal balance1YearAgo = findHistoricalBalance(historyData, keyPrefix, date1YearAgo);
BigDecimal balance2YearsAgo = findMonthlyBalance(section, saleOrgUnit, custName, date2YearsAgo); BigDecimal balance2YearsAgo = findHistoricalBalance(historyData, keyPrefix, date2YearsAgo);
BigDecimal balance3YearsAgo = findMonthlyBalance(section, saleOrgUnit, custName, date3YearsAgo); BigDecimal balance3YearsAgo = findHistoricalBalance(historyData, keyPrefix, date3YearsAgo);
BigDecimal balance4YearsAgo = findMonthlyBalance(section, saleOrgUnit, custName, date4YearsAgo); BigDecimal balance4YearsAgo = findHistoricalBalance(historyData, keyPrefix, date4YearsAgo);
BigDecimal balance5YearsAgo = findMonthlyBalance(section, saleOrgUnit, custName, date5YearsAgo); BigDecimal balance5YearsAgo = findHistoricalBalance(historyData, keyPrefix, date5YearsAgo);
// 计算各账龄段金额 // 计算各账龄段金额
result.put("ZLFX0_60", currentBalance.subtract(balance60DaysAgo.max(BigDecimal.ZERO))); result.put("ZLFX0_60", currentBalance.subtract(balance60DaysAgo.max(BigDecimal.ZERO)));
@ -393,7 +547,7 @@ public class WaterproofPaintAccountsReceivableJob implements IJob {
} catch (Exception e) { } catch (Exception e) {
LOGGER.error("计算账龄分析时发生错误,销售组织: {}, 客户: {}", saleOrgUnit, custName, e); LOGGER.error("计算账龄分析时发生错误,销售组织: {}, 客户: {}", saleOrgUnit, custName, e);
// 发生错误时设置默认值 // 设置默认值
result.put("ZLFX0_60", BigDecimal.ZERO); result.put("ZLFX0_60", BigDecimal.ZERO);
result.put("ZLFX60_1", BigDecimal.ZERO); result.put("ZLFX60_1", BigDecimal.ZERO);
result.put("ZLFX1_2", BigDecimal.ZERO); result.put("ZLFX1_2", BigDecimal.ZERO);
@ -407,29 +561,55 @@ public class WaterproofPaintAccountsReceivableJob implements IJob {
} }
/** /**
* 查找指定月末的应收余额 * 查找历史余额
*/ */
private BigDecimal findMonthlyBalance(Section section, String saleOrgUnit, String custName, LocalDate targetDate) { private BigDecimal findHistoricalBalance(Map<String, BigDecimal> historyData, String keyPrefix, LocalDate targetDate) {
// 调整为目标月份的月末日期 // 调整为目标月份的月末日期
LocalDate monthEndDate = targetDate.withDayOfMonth(targetDate.lengthOfMonth()); LocalDate monthEndDate = targetDate.withDayOfMonth(targetDate.lengthOfMonth());
String dateStr = monthEndDate.format(DateTimeFormatter.ofPattern("yyyy-MM-dd")) + " 23:59:59"; String dateKey = monthEndDate.format(DateTimeFormatter.ofPattern("yyyy-MM-dd"));
String fullKey = keyPrefix + dateKey;
try { return historyData.getOrDefault(fullKey, BigDecimal.ZERO);
// 查询目标表中该月末的应收余额
RowMap result = DBSql.getMap(
"SELECT YSYE FROM " + section.getTargetTable() +
" WHERE XSZZ = ? AND KH = ? AND RQ = ?",
saleOrgUnit, custName, dateStr
);
return result != null && result.get("YSYE") != null ?
new BigDecimal(result.get("YSYE").toString()) : BigDecimal.ZERO;
} catch (Exception e) {
LOGGER.debug("未找到{}板块销售组织 {} 客户 {} 日期 {} 的历史余额使用默认值0",
section.getName(), saleOrgUnit, custName, monthEndDate);
return BigDecimal.ZERO;
} }
/**
* 构建IN查询条件
*/
private String buildInCondition(List<String> values) {
if (values == null || values.isEmpty()) {
return "''";
}
return values.stream()
.map(value -> "'" + value.replace("'", "''") + "'")
.collect(Collectors.joining(","));
}
/**
* 获取时间范围内的所有月末日期优化版
*/
private List<LocalDate> getMonthEndDates(LocalDate startDate, LocalDate endDate) {
List<LocalDate> monthEndDates = new ArrayList<>();
LocalDate current = startDate.withDayOfMonth(1);
while (!current.isAfter(endDate)) {
if (current.getYear() == endDate.getYear() && current.getMonth() == endDate.getMonth()) {
// 当前月份与结束日期同年同月使用结束日期前一天
LocalDate dayBeforeEnd = endDate.minusDays(1);
if (!dayBeforeEnd.isBefore(startDate)) {
monthEndDates.add(dayBeforeEnd);
}
break;
} else {
// 其他月份使用月末日期
LocalDate monthEnd = current.withDayOfMonth(current.lengthOfMonth());
if (!monthEnd.isBefore(startDate) && !monthEnd.isAfter(endDate)) {
monthEndDates.add(monthEnd);
}
}
current = current.plusMonths(1);
}
return monthEndDates;
} }
/** /**
@ -456,13 +636,13 @@ public class WaterproofPaintAccountsReceivableJob implements IJob {
record.set("YSYE", ysye); record.set("YSYE", ysye);
// 账龄分析字段 // 账龄分析字段
record.set("ZLFX0_60", zlfx.get("ZLFX0_60")); record.set("ZLFX0_60", zlfx.getOrDefault("ZLFX0_60", BigDecimal.ZERO));
record.set("ZLFX60_1", zlfx.get("ZLFX60_1")); record.set("ZLFX60_1", zlfx.getOrDefault("ZLFX60_1", BigDecimal.ZERO));
record.set("ZLFX1_2", zlfx.get("ZLFX1_2")); record.set("ZLFX1_2", zlfx.getOrDefault("ZLFX1_2", BigDecimal.ZERO));
record.set("ZLFX2_3", zlfx.get("ZLFX2_3")); record.set("ZLFX2_3", zlfx.getOrDefault("ZLFX2_3", BigDecimal.ZERO));
record.set("ZLFX3_4", zlfx.get("ZLFX3_4")); record.set("ZLFX3_4", zlfx.getOrDefault("ZLFX3_4", BigDecimal.ZERO));
record.set("ZLFX4_5", zlfx.get("ZLFX4_5")); record.set("ZLFX4_5", zlfx.getOrDefault("ZLFX4_5", BigDecimal.ZERO));
record.set("ZLFX5", zlfx.get("ZLFX5")); record.set("ZLFX5", zlfx.getOrDefault("ZLFX5", BigDecimal.ZERO));
return record; return record;
} }
@ -472,9 +652,8 @@ public class WaterproofPaintAccountsReceivableJob implements IJob {
*/ */
private void batchInsert(Section section, List<BO> batchData) { private void batchInsert(Section section, List<BO> batchData) {
try { try {
int[] dataBO = SDK.getBOAPI().createDataBO(section.getTargetTable(), batchData, UserContext.fromUID("admin")); int[] results = SDK.getBOAPI().createDataBO(section.getTargetTable(), batchData, UserContext.fromUID("admin"));
long result = Arrays.stream(dataBO).count(); LOGGER.info("成功插入 {} 条数据到 {} 表", batchData.size(), section.getTargetTable());
LOGGER.info("成功插入 {} 条数据到 {} 表", result, section.getTargetTable());
} catch (Exception e) { } catch (Exception e) {
LOGGER.error("批量插入{}板块数据到表{}时发生错误", section.getName(), section.getTargetTable(), e); LOGGER.error("批量插入{}板块数据到表{}时发生错误", section.getName(), section.getTargetTable(), e);
} }

View File

@ -501,7 +501,9 @@ public class SaleCountDimensionImpl implements DataSummaryService {
bo.set("JD", location.getLongitude()); bo.set("JD", location.getLongitude());
bo.set("WD", location.getLatitude()); bo.set("WD", location.getLatitude());
} }
if ("石膏板".equals(lb_1) || "高分子".equals(lb_1)){ if ("石膏板".equals(lb_1)
|| (bkgs.equals("北新防水") && ("高分子".equals(lb_1) || "卷材".equals(lb_1) || "涂料".equals(lb_1)))
|| (bkgs.equals("北新涂料") && "涂料".equals(lb_1))){
bo.set("XL", map.getDouble("TSXL")); bo.set("XL", map.getDouble("TSXL"));
bo.set("SNTQXL", map.getString("sntqtsxl")); bo.set("SNTQXL", map.getString("sntqtsxl"));
}else { }else {

View File

@ -97,13 +97,13 @@ public class SaleDataSyncServiceImpl implements DataSyncService {
String targetTable = mainConfig.getString("LDB"); String targetTable = mainConfig.getString("LDB");
String ccId = mainConfig.getString("CC_ID"); String ccId = mainConfig.getString("CC_ID");
String partitionField = mainConfig.getString("FQBZD"); String partitionField = mainConfig.getString("FQBZD");
String bkgs = mainConfig.getString("BKGS"); String bkgs = mainConfig.getString("SSBK");
String jezd = mainConfig.getString("JEZD"); String jezd = mainConfig.getString("JEZD");
String tablename = mainConfig.getString("TABLENAME"); String tablename = mainConfig.getString("TABLENAME");
DateRange dateRange = new DateRange(); DateRange dateRange = new DateRange();
LOGGER.info("处理配置BindID={}, 源表={}, 目标表={}, CC_ID={}, 时间字段={}, 分区字段配置={}", LOGGER.info("处理配置BindID={}, 源表={}, 目标表={}, CC_ID={}, 时间字段={}, 分区字段配置={}, 板块={}",
bindId, tableName, targetTable, ccId,timeField,partitionField); bindId, tableName, targetTable, ccId,timeField,partitionField,bkgs);
// 查询子表字段映射配置 // 查询子表字段映射配置
List<BO> fieldMappings = SDK.getBOAPI() List<BO> fieldMappings = SDK.getBOAPI()
@ -144,7 +144,7 @@ public class SaleDataSyncServiceImpl implements DataSyncService {
// 查询源表数据跨库查询 // 查询源表数据跨库查询
if (tablename.equals("应收表")){ if (tablename.equals("应收表")){
LOGGER.info("开始执行应收的明细汇总"); LOGGER.info("开始执行应收的明细汇总");
if ((!bkgs.equals("北新防水")) || (!bkgs.equals("北新涂料"))) { if (!bkgs.equals("北新防水") || !bkgs.equals("北新涂料")) {
querySourceDataYS(ccId, tableName, timeField, startDate, endDate, partitionField, querySourceDataYS(ccId, tableName, timeField, startDate, endDate, partitionField,
fieldMappings, targetTable, jezd); fieldMappings, targetTable, jezd);
} }
@ -845,7 +845,7 @@ public class SaleDataSyncServiceImpl implements DataSyncService {
if ("北新防水".equals(map.getString("BKGS")) && "".equals(map.getString("F_SFNBJY")) if ("北新防水".equals(map.getString("BKGS")) && "".equals(map.getString("F_SFNBJY"))
&& !map.getString("XSZZ").equals("北新防水工程(辽宁)有限公司") && !map.getString("XSZZ").equals("北新防水工程(辽宁)有限公司")
&& !map.getString("XSZZ").equals("北新防水工程(四川)有限公司") && !map.getString("XSZZ").equals("北新防水工程(四川)有限公司")
&& StringUtils.isBlank(map.getString("F_SFNBJY"))){ && StringUtils.isBlank(map.getString("QYGS").trim())){
continue; continue;
} }
// 复制所有字段排除系统字段 // 复制所有字段排除系统字段
@ -997,7 +997,8 @@ public class SaleDataSyncServiceImpl implements DataSyncService {
} }
if ("北新防水".equals(map.getString("BKGS")) && "".equals(map.getString("F_SFNBJY")) if ("北新防水".equals(map.getString("BKGS")) && "".equals(map.getString("F_SFNBJY"))
&& !map.getString("XSZZ").equals("北新防水工程(辽宁)有限公司") && !map.getString("XSZZ").equals("北新防水工程(辽宁)有限公司")
&& !map.getString("XSZZ").equals("北新防水工程(四川)有限公司")){ && !map.getString("XSZZ").equals("北新防水工程(四川)有限公司")
&& StringUtils.isBlank(map.getString("QYGS").trim())){
continue; continue;
} }
// 复制所有字段排除系统字段 // 复制所有字段排除系统字段
@ -1118,12 +1119,26 @@ public class SaleDataSyncServiceImpl implements DataSyncService {
" AND MONTH = " + firstDayOfLastYearMonth.getMonthValue()); " AND MONTH = " + firstDayOfLastYearMonth.getMonthValue());
LOGGER.info("先清空{}去年同期数{}",lastYearFirstDayStr,update1); LOGGER.info("先清空{}去年同期数{}",lastYearFirstDayStr,update1);
// 构建插入SQL注意需确保字段匹配且处理可能的主键冲突 // 构建插入SQL注意需确保字段匹配且处理可能的主键冲突
String insertCurrentMonthLastYearSql = "INSERT INTO " + targetTable +
" SELECT * FROM " + targetTable + String CurrentMonthLastYearSql = "SELECT * FROM " + targetTable +
" WHERE " + targetTimeField + " >= '" + lastYearFirstDayStr + " WHERE " +targetTimeField+">='"+lastYearFirstDayStr+"' AND "+
"' AND " + targetTimeField + " < '" + lastYearNextMonthFirstDayStr + "'"; targetTimeField+"<'"+lastYearNextMonthFirstDayStr+"'";
ArrayList<BO> bos = new ArrayList<>();
List<RowMap> maps = DBSql.getMaps(CurrentMonthLastYearSql);
for (RowMap map : maps) {
map.remove("ID");
map.remove("ORGID");
map.remove("CREATEDATE");
map.remove("CREATEUSER");
map.remove("UPDATEDATE");
map.remove("UPDATEUSER");
map.remove("ISEND");
map.remove("BINDID");
BO bo = new BO().setAll(map);
bos.add(bo);
}
// 执行插入操作 // 执行插入操作
DBSql.update(insertCurrentMonthLastYearSql); SDK.getBOAPI().createDataBO(hzb, bos, UserContext.fromUID("admin"));
LOGGER.info("{}已新增当月去年同期数据",lastYearFirstDayStr); LOGGER.info("{}已新增当月去年同期数据",lastYearFirstDayStr);
} catch (Exception e) { } catch (Exception e) {
@ -1329,23 +1344,75 @@ public class SaleDataSyncServiceImpl implements DataSyncService {
String lastYearFirstDayStr = firstDayOfLastYearMonth.format(formatter); String lastYearFirstDayStr = firstDayOfLastYearMonth.format(formatter);
String lastYearNextMonthFirstDayStr = firstDayOfNextMonthLastYear.format(formatter); String lastYearNextMonthFirstDayStr = firstDayOfNextMonthLastYear.format(formatter);
//删除清空去年同期数据 //删除清空去年同期数据
int update1 = DBSql.update("DELETE FROM " + targetTable + int update1 = DBSql.update("DELETE FROM " + targetTable +
" WHERE RQ = '" + lastYearNextMonthFirstDayStr+"'"); " WHERE RQ = '" + lastYearNextMonthFirstDayStr+"'");
LOGGER.info("先清空{}去年同期数{}",lastYearFirstDayStr,update1); LOGGER.info("先清空{}去年同期数{}",lastYearFirstDayStr,update1);
// 构建插入SQL注意需确保字段匹配且处理可能的主键冲突 // 构建查询去年同期全部数据的SQL
String insertCurrentMonthLastYearSql = "INSERT INTO " + targetTable + String lastYearQuerySql;
" SELECT * FROM " + targetTable + List<Object> lastYearParams = new ArrayList<>();
" WHERE RQ >= '" + lastYearFirstDayStr +
"' AND RQ < '" + lastYearNextMonthFirstDayStr + "'"; // 根据不同的数据库类型构建查询语句
// 执行插入操作 if ("ORACLE".equalsIgnoreCase(DBname)) {
rdsapi.update(insertCurrentMonthLastYearSql); lastYearQuerySql = "SELECT * FROM " + tableName +
LOGGER.info("{}已新增当月去年同期数据",lastYearFirstDayStr); " WHERE TO_DATE(" + timeField + ", 'YYYY-MM-DD') BETWEEN TO_DATE(?, 'YYYY-MM-DD') AND TO_DATE(?, 'YYYY-MM-DD')";
lastYearParams.add(lastYearFirstDayStr);
lastYearParams.add(lastYearNextMonthFirstDayStr);
} else if ("POSTGRESQL".equalsIgnoreCase(DBname) || "GAUSS".equalsIgnoreCase(DBname)) {
lastYearQuerySql = "SELECT * FROM " + tableName +
" WHERE " + timeField + "::DATE BETWEEN ?::DATE AND ?::DATE";
lastYearParams.add(lastYearFirstDayStr);
lastYearParams.add(lastYearNextMonthFirstDayStr);
} else if ("SQLSERVER".equalsIgnoreCase(DBname)) {
lastYearQuerySql = "SELECT * FROM " + tableName +
" WHERE CONVERT(DATE, " + timeField + ") BETWEEN CONVERT(DATE, ?) AND CONVERT(DATE, ?)";
lastYearParams.add(lastYearFirstDayStr);
lastYearParams.add(lastYearNextMonthFirstDayStr);
} else {
// 默认处理如MySQL
lastYearQuerySql = "SELECT * FROM " + tableName +
" WHERE STR_TO_DATE(" + timeField + ", '%Y-%m-%d') BETWEEN STR_TO_DATE(?, '%Y-%m-%d') AND STR_TO_DATE(?, '%Y-%m-%d')";
lastYearParams.add(lastYearFirstDayStr);
lastYearParams.add(lastYearNextMonthFirstDayStr);
}
// 添加分区条件如果存在
if (partitionField != null && !partitionField.isEmpty() && !maxPartition.isEmpty()) {
if ("ORACLE".equalsIgnoreCase(DBname)) {
lastYearQuerySql += " AND " + partitionField + " = '" + maxPartition + "'";
} else {
lastYearQuerySql += " AND " + partitionField + " = '" + maxPartition + "'";
}
}
LOGGER.info("查询去年同期数据SQL: {}", lastYearQuerySql);
LOGGER.info("查询参数: 开始日期={}, 结束日期={}", lastYearFirstDayStr, lastYearNextMonthFirstDayStr);
// 执行查询去年同期数据
List<RowMap> lastYearData;
if (lastYearParams.isEmpty()) {
lastYearData = rdsapi.getMaps(lastYearQuerySql);
} else {
// 这里需要根据您的rdsapi接口调整参数传递方式
lastYearData = rdsapi.getMaps(lastYearQuerySql, lastYearParams.toArray());
}
if (lastYearData != null && !lastYearData.isEmpty()) {
// 批量插入去年同期数据
int lastYearSuccessCount = this.processAndInsertData(lastYearData, fieldMappings, targetTable);
LOGGER.info("成功插入去年同期数据{}条,时间范围: {}-{}",
lastYearSuccessCount, lastYearFirstDayStr, lastYearNextMonthFirstDayStr);
} else {
LOGGER.warn("未查询到去年同期数据,时间范围: {}-{}",
lastYearFirstDayStr, lastYearNextMonthFirstDayStr);
}
} catch (Exception e) { } catch (Exception e) {
LOGGER.error("每月1号任务执行失败: {}", e.getMessage(), e); LOGGER.error("每月1号任务执行失败: {}", e.getMessage(), e);
} }
// } // }
LOGGER.info("从表[{}]共查询到{}条数据,成功同步{}条数据", LOGGER.info("从表[{}]共查询到{}条数据,成功同步{}条数据",