From ecd282bfc3f87f34ce04ec8887169b99fe04478e Mon Sep 17 00:00:00 2001
From: 6c <420680616@qq.com>
Date: 星期五, 08 八月 2025 18:10:35 +0800
Subject: [PATCH] 请求历史特殊处理-通过历史表补充报表库数据

---
 product-server-data-center/src/main/java/com/product/data/center/config/ErrorCode.java      |    6 
 product-server-data-center/src/main/java/com/product/data/center/service/SpDealService.java |  491 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 497 insertions(+), 0 deletions(-)

diff --git a/product-server-data-center/src/main/java/com/product/data/center/config/ErrorCode.java b/product-server-data-center/src/main/java/com/product/data/center/config/ErrorCode.java
index 7999791..6888e35 100644
--- a/product-server-data-center/src/main/java/com/product/data/center/config/ErrorCode.java
+++ b/product-server-data-center/src/main/java/com/product/data/center/config/ErrorCode.java
@@ -145,6 +145,12 @@
 	PRODUCT_SN_TABLE_NOT_EXISTS("T_WIP_PRODUCT_SN褰掓。琛ㄤ笉瀛樺湪", "089"),
 
 	PRODUCT_SN_DATA_NOT_FOUND("T_WIP_PRODUCT_SN鏈壘鍒扮浉搴旂殑鏁版嵁", "090"),
+	REQUEST_HISTORY_SP_DEAL_FAIL("璇锋眰鍘嗗彶鐗规畩澶勭悊澶辫触", "091"),
+	REQUEST_HISTORY_SP_DEAL_FAIL_NO_DB_LINK_INFO("璇锋眰鍘嗗彶鐗规畩澶勭悊澶辫触-閲囬泦鎻愬彇搴�-鏈幏鍙栧埌瀛愬簱鎴栨姤琛ㄥ簱杩炴帴淇℃伅", "092"),
+	REQUEST_HISTORY_SP_DEAL_FAIL_NO_TABLE_INFO("璇锋眰鍘嗗彶鐗规畩澶勭悊澶辫触-閲囬泦鎻愬彇搴�-鏈幏鍙栧埌瀛愬簱琛ㄤ俊鎭�", "093"),
+	REQUEST_HISTORY_SP_DEAL_FAIL_NO_SP_DEAL_INFO("璇锋眰鍘嗗彶鐗规畩澶勭悊澶辫触-閲囬泦鎻愬彇搴�-鏈幏鍙栧埌鐗规畩澶勭悊淇℃伅", "094"),
+	REQUEST_HISTORY_SP_DEAL_FAIL_WITH_SUB_DB_DATA("璇锋眰鍘嗗彶鐗规畩澶勭悊澶辫触-瀛愬簱-鏁版嵁鑾峰彇澶辫触", "095"),
+	REQUEST_HISTORY_SP_DEAL_FAIL_NO_TABLE_DATA("璇锋眰鍘嗗彶鐗规畩澶勭悊澶辫触-閲囬泦鎻愬彇搴�-鏈幏鍙栧埌", "096"),
 
 	;
 
diff --git a/product-server-data-center/src/main/java/com/product/data/center/service/SpDealService.java b/product-server-data-center/src/main/java/com/product/data/center/service/SpDealService.java
new file mode 100644
index 0000000..3857fe2
--- /dev/null
+++ b/product-server-data-center/src/main/java/com/product/data/center/service/SpDealService.java
@@ -0,0 +1,491 @@
+package com.product.data.center.service;
+
+import com.alibaba.fastjson.JSONObject;
+import com.beust.jcommander.internal.Lists;
+import com.google.common.collect.Maps;
+import com.product.common.lang.StringUtils;
+import com.product.core.dao.BaseDao;
+import com.product.core.entity.DataTableEntity;
+import com.product.core.entity.FieldSetEntity;
+import com.product.core.exception.BaseException;
+import com.product.core.service.support.AbstractBaseService;
+import com.product.core.spring.context.SpringMVCContextHolder;
+import com.product.data.center.config.CmnConst;
+import com.product.data.center.config.ErrorCode;
+import com.product.datasource.dao.Dao;
+import com.product.datasource.entity.DataBaseEntity;
+import com.product.util.BaseUtil;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import java.text.SimpleDateFormat;
+import java.util.*;
+
+/**
+ * 瀹炵幇鍔熻兘锛�
+ *
+ * @author 浣滆�匸澶滀付鍏塢
+ * @version 1.0.00  2025-08-04 10:48
+ */
+@Service
+public class SpDealService extends AbstractBaseService {
+    @Autowired
+    private BaseDao baseDao;
+    @Autowired
+    private DataArchivingService dataArchivingService;
+    @Autowired
+    private JournalManagerService journalManagerService;
+
+    /*========================璇锋眰鍘嗗彶-start========================*/
+    // 姝e湪澶勭悊鏍囪瘑
+    private static boolean processingFlag = false;
+    // 鍋滄鏍囪瘑
+    private static boolean stopFlag = false;
+    // 鏁版嵁瀛楀吀鍚嶇О-璇锋眰鍘嗗彶
+    private static final String DICT_NAME_REQUEST_HISTORY = "璇锋眰鍘嗗彶鐗规畩澶勭悊";
+    // 椤靛ぇ灏�
+    private static int pageSize = 0;
+    // 瀛愬簱鎿嶄綔鐨勮〃闆嗗悎锛岄渶瑕佷粠鏁版嵁搴撲腑璇诲彇
+    private static List<String> operateTableList = Lists.newArrayList();
+    // 鏁存満瀛愬簱ip
+    private static String subDbIp = "";
+    // 瀛愬簱绔彛
+    private static int subDbPort = 0;
+    // 鎶ヨ〃搴搃p
+    private static String reportDbIp = "";
+    // 鎶ヨ〃搴撶鍙�
+    private static int reportDbPort = 0;
+
+    /**
+     * 閫氬父瀹氭椂浠诲姟瑙﹀彂-鍋滄鎵ц
+     */
+    public void stopExecute() {
+        SpringMVCContextHolder.getSystemLogger().info("[璇锋眰鍘嗗彶鐗规畩澶勭悊-鍋滄]");
+        stopFlag = true;
+    }
+
+    /**
+     * 閫氬父瀹氭椂浠诲姟瑙﹀彂-璇锋眰鍘嗗彶鐗规畩澶勭悊-娴嬭瘯鏂规硶
+     */
+    public void testRequestHistorySpDeal() {
+        requestHistorySpDeal(true);
+    }
+
+    /**
+     * 閫氬父瀹氭椂浠诲姟瑙﹀彂-璇锋眰鍘嗗彶鐗规畩澶勭悊
+     */
+    public void requestHistorySpDeal() {
+        requestHistorySpDeal(false);
+    }
+
+    /**
+     * 璇锋眰鍘嗗彶鐗规畩澶勭悊
+     */
+    private void requestHistorySpDeal(boolean testFlag) {
+        SpringMVCContextHolder.getSystemLogger().info("[璇锋眰鍘嗗彶鐗规畩澶勭悊-寮�濮媇");
+        if (processingFlag) {
+            SpringMVCContextHolder.getSystemLogger().info("[璇锋眰鍘嗗彶鐗规畩澶勭悊-姝e湪杩涜-璺宠繃]");
+            return;
+        }
+        synchronized ("requestHistorySpDeal") {
+            DataBaseEntity subDbe = null;
+            DataBaseEntity reportDbe = null;
+            DataTableEntity waitInsertDte = null;
+            try {
+                if (processingFlag) {
+                    return;
+                }
+                processingFlag = true;
+
+                // 鑾峰彇鐗规畩澶勭悊淇℃伅
+                JSONObject spDealInfoObj = getSpDealInfo();
+                if (spDealInfoObj.isEmpty()) {
+                    throw new BaseException(ErrorCode.REQUEST_HISTORY_SP_DEAL_FAIL_NO_SP_DEAL_INFO);
+                }
+                String tableFormat = spDealInfoObj.getString("tableFormat");
+
+                // 鑾峰彇瀛愬簱鍜屾姤琛ㄥ簱杩炴帴淇℃伅
+                DataTableEntity dbLinkDte = baseDao.listTable(CmnConst.PRODUCT_SYS_DATA_SYNC_MANAGER, "ip=? OR (ip=? AND port=?)", new Object[]{subDbIp, reportDbIp, reportDbPort});
+                FieldSetEntity subDbFse = null;
+                FieldSetEntity reportDbFse = null;
+                for (int i = 0; i < dbLinkDte.getRows(); i++) {
+                    FieldSetEntity singleFse = dbLinkDte.getFieldSetEntity(i);
+                    if (subDbIp.equals(singleFse.getString("ip")) && !StringUtils.isEmpty(singleFse.getString("port")) && subDbPort == singleFse.getInteger("port")) {
+                        subDbFse = singleFse;
+                    } else if (reportDbIp.equals(singleFse.getString("ip")) && !StringUtils.isEmpty(singleFse.getString("port")) && reportDbPort == singleFse.getInteger("port")) {
+                        reportDbFse = singleFse;
+                    }
+                }
+                if (subDbFse == null || reportDbFse == null) {
+                    throw new BaseException(ErrorCode.REQUEST_HISTORY_SP_DEAL_FAIL_NO_DB_LINK_INFO);
+                }
+
+                // 鑾峰彇瀛愬簱瀵瑰簲琛ㄧ殑淇℃伅锛氳〃鍚嶏紝涓婚敭瀛楁锛屾椂闂村瓧娈�
+                JSONObject subDbTableInfoObj = getSubDbTableInfo(subDbFse.getUUID());
+                if (subDbTableInfoObj.isEmpty()) {
+                    throw new BaseException(ErrorCode.REQUEST_HISTORY_SP_DEAL_FAIL_NO_TABLE_INFO);
+                }
+
+                // 鑾峰彇杩炴帴
+                subDbe = new DataBaseEntity(subDbFse);
+                reportDbe = new DataBaseEntity(reportDbFse);
+
+                // 鎸変富閿帓搴忥紝鍒嗛〉鎻愬彇瀛愬簱鏁版嵁锛屽姣旀姤琛ㄥ簱鏁版嵁锛屼笉瀛樺湪鍒欐彃鍏�
+                if (!stopFlag) {
+                    int curMaxMasterKeyValue = 0;
+                    outer: for (String tableNameStr : operateTableList) {
+                        SpringMVCContextHolder.getSystemLogger().info("[璇锋眰鍘嗗彶鐗规畩澶勭悊-鏁版嵁澶勭悊-寮�濮媇-" + tableNameStr);
+                        int index = 0;
+                        JSONObject singleSubDbTableInfoObj = subDbTableInfoObj.getJSONObject(tableNameStr);
+                        // 閲囬泦閰嶇疆琛╥d
+                        String sourceInfo = singleSubDbTableInfoObj.getString(CmnConst.ID);
+                        String tableName = String.format(tableFormat, tableNameStr);
+                        String reportTableNamePrefix = String.format("da_%s", tableNameStr);
+                        String orderBy = singleSubDbTableInfoObj.getString("auto_field");
+                        DataArchivingService.DataArchivingServiceImpl createTableService = getDDLService(tableName, subDbe, reportDbe);
+                        String masterKeyFieldName = singleSubDbTableInfoObj.getString("auto_field");
+                        long initId = spDealInfoObj.getJSONObject(tableNameStr) == null ? 0 : spDealInfoObj.getJSONObject(tableNameStr).getIntValue("dealt_max_id");
+                        long curId = initId;
+                        int count;
+                        int totalCount = 0;
+                        // 缁熻椤垫暟锛屾瘡澶氬皯椤佃褰曚竴娆℃渶澶d
+                        int statisticsPage = 10;
+                        if (!testFlag) {
+                            do {
+                                index++;
+                                if (stopFlag) {
+                                    break outer;
+                                }
+                                DataTableEntity singlePageDataDte;
+                                try {
+                                    singlePageDataDte = subDbe.getDao().getList(tableName, null, masterKeyFieldName + ">?", new Object[]{curId}, orderBy, 1, pageSize);
+                                } catch (Exception e) {
+                                    throw new BaseException(ErrorCode.REQUEST_HISTORY_SP_DEAL_FAIL_WITH_SUB_DB_DATA.getValue(), ErrorCode.REQUEST_HISTORY_SP_DEAL_FAIL_WITH_SUB_DB_DATA.getText() + ":" + e.getMessage());
+                                }
+                                count = singlePageDataDte.getRows();
+                                if (count > 0) {
+                                    curMaxMasterKeyValue = singlePageDataDte.getFieldSetEntity(singlePageDataDte.getRows() - 1).getInteger(singleSubDbTableInfoObj.getString("auto_field"));
+                                    curId = curMaxMasterKeyValue;
+                                    Map<String, Map<String, FieldSetEntity>> monthMap = Maps.newHashMap();
+                                    dealSubDbData(singlePageDataDte, singleSubDbTableInfoObj, monthMap);
+
+                                    // 妫�鏌ユ槸鍚︽墍鏈夎〃閮藉瓨鍦紝鑻ユ槸涓嶅瓨鍦紝閭d箞鍒涘缓
+                                    checkTableIfNoThenCreate(monthMap.keySet(), reportTableNamePrefix, createTableService);
+
+                                    String querySql = joinReportDbQuerySql(monthMap, reportTableNamePrefix, sourceInfo);
+                                    DataTableEntity reportDbExistsDte = reportDbe.getDao().getList(querySql);
+                                    for (int i = 0; i < reportDbExistsDte.getRows(); i++) {
+                                        FieldSetEntity reportDbExistsFse = reportDbExistsDte.getFieldSetEntity(i);
+                                        for (Map<String, FieldSetEntity> singleMonthMap : monthMap.values()) {
+                                            singleMonthMap.remove(reportDbExistsFse.getString("pre_master_key"));
+                                        }
+                                    }
+                                    for (Map.Entry<String, Map<String, FieldSetEntity>> entry : monthMap.entrySet()) {
+                                        String insertTableName = String.format("%s_%s", reportTableNamePrefix, entry.getKey());
+                                        waitInsertDte = getSingleMonthInsertDte(entry.getValue(), insertTableName, sourceInfo);
+                                        reportDbe.getDao().addBatch(waitInsertDte);
+                                        totalCount += waitInsertDte.getRows();
+                                    }
+                                    if (index % statisticsPage == 0) {
+                                        // 鏇存柊褰撳墠鎿嶄綔鐨勮〃缁熻鏃ュ織淇℃伅锛屾瘡鎸囧畾椤垫暟鏇存柊涓�娆�
+                                        updateOperateTableInfo(tableNameStr, initId, curMaxMasterKeyValue, totalCount);
+                                    }
+                                }
+                            } while (count > 0);
+                            if (index % statisticsPage != 0) {
+                                // 鏇存柊褰撳墠鎿嶄綔鐨勮〃缁熻鏃ュ織淇℃伅锛岃嫢鏄笉鏄�嶆暟锛岄偅涔堥渶瑕侀澶栨墽琛屼竴娆�
+                                updateOperateTableInfo(tableNameStr, initId, curMaxMasterKeyValue, totalCount);
+                            }
+                        }
+                    }
+                }
+            } catch (Exception e) {
+                recordErrorLog(waitInsertDte, e);
+                throw e;
+            } finally {
+                stop(subDbe, reportDbe);
+                SpringMVCContextHolder.getSystemLogger().info("[璇锋眰鍘嗗彶鐗规畩澶勭悊-缁撴潫]");
+            }
+        }
+    }
+
+    /**
+     * 璁板綍閿欒鏃ュ織
+     * @param waitInsertDte 绛夊緟鎻掑叆鐨勬暟鎹甦te
+     * @param e             閿欒
+     */
+    private void recordErrorLog(DataTableEntity waitInsertDte, Exception e) {
+        String errorInfo = journalManagerService.getStackTrace(e);
+        String groupUUID = UUID.randomUUID().toString();
+        Date curTime = new Date();
+        if (!DataTableEntity.isEmpty(waitInsertDte)) {
+            // 璁板綍褰撳墠鎶ラ敊鐨勪俊鎭�
+            DataTableEntity logDte = new DataTableEntity();
+            for (int i = 0; i < waitInsertDte.getRows(); i++) {
+                FieldSetEntity singlePageDataFse = waitInsertDte.getFieldSetEntity(i);
+                FieldSetEntity logFse = new FieldSetEntity("product_sys_sp_deal_log");
+                logFse.setValue("content", BaseUtil.fieldSetEntityToJson(singlePageDataFse).toJSONString());
+                logFse.setValue("error", errorInfo);
+                logFse.setValue("group_uuid", groupUUID);
+                logFse.setValue("created_utc_datetime", curTime);
+                logDte.addFieldSetEntity(logFse);
+            }
+            baseDao.add(logDte);
+        } else {
+            FieldSetEntity logFse = new FieldSetEntity("product_sys_sp_deal_log");
+            logFse.setValue("content", "闈炴暟鎹鐞嗛樁娈靛嚭閿�");
+            logFse.setValue("error", errorInfo);
+            logFse.setValue("group_uuid", groupUUID);
+            logFse.setValue("created_utc_datetime", curTime);
+            baseDao.add(logFse);
+        }
+    }
+
+    /**
+     * 鑾峰彇鍗曟湀鎻掑叆dte
+     * @param singleMonthMap  鍗曟湀鏁版嵁map
+     * @param insertTableName 鎶ヨ〃搴撹〃鍚�
+     * @param sourceInfo      閲囬泦閰嶇疆琛╥d
+     * @return  鍗曟壒娆′腑鍗曟湀锛堝洜涓烘寜鏈堝垎琛級寰呮彃鍏ョ殑dte
+     */
+    private DataTableEntity getSingleMonthInsertDte(Map<String, FieldSetEntity> singleMonthMap, String insertTableName, String sourceInfo) {
+        DataTableEntity waitInsertDte = new DataTableEntity();
+        for (Map.Entry<String, FieldSetEntity> entry : singleMonthMap.entrySet()) {
+            FieldSetEntity waitInsertFse = entry.getValue();
+            waitInsertFse.setTableName(insertTableName);
+            waitInsertFse.setValue("pre_master_key", entry.getKey());
+            waitInsertFse.setValue("source_info", sourceInfo);
+            waitInsertDte.addFieldSetEntity(waitInsertFse);
+        }
+        return waitInsertDte;
+    }
+
+    /**
+     * 鑾峰彇鍒涘缓琛ㄧ殑service
+     * @param tableName     琛ㄥ悕锛屽瓙搴撳巻鍙茶〃琛ㄥ悕
+     * @param subDbe        瀛愬簱鏁版嵁搴撹繛鎺ュ疄渚�
+     * @param reportDbe     鎶ヨ〃鏁版嵁搴撹繛鎺ュ疄渚�
+     * @return  鑳藉鎵ц鍒涘缓琛―DL璇彞鐨剆ervice
+     */
+    private DataArchivingService.DataArchivingServiceImpl getDDLService(String tableName, DataBaseEntity subDbe, DataBaseEntity reportDbe) {
+        Dao sourceDao = subDbe.getDao();
+        Dao targetDao = reportDbe.getDao();
+        String sourceDbName = subDbe.getDbName();
+        String targetDbName = reportDbe.getDbName();
+        return dataArchivingService.new DataArchivingServiceImpl(sourceDao, targetDao, tableName, "requestHistory", sourceDbName, targetDbName);
+    }
+
+    /**
+     * 妫�鏌ユ槸鍚︽墍鏈夎〃閮藉瓨鍦紝鑻ユ槸涓嶅瓨鍦紝閭d箞鍒涘缓
+     * @param tableTailSet          琛ㄥ熬缂�闆嗗悎锛屾椂闂�
+     * @param reportTableNamePrefix 鎶ヨ〃搴撹〃鍚嶅墠缂�
+     * @param createTableService    鍒涘缓琛ㄧ殑service
+     */
+    private void checkTableIfNoThenCreate(Set<String> tableTailSet, String reportTableNamePrefix, DataArchivingService.DataArchivingServiceImpl createTableService) {
+        for (String tableTail : tableTailSet) {
+            createTableService.createTable(reportTableNamePrefix, tableTail, null);
+        }
+    }
+
+    /**
+     * 鏇存柊褰撳墠鎿嶄綔鐨勮〃鐨勭粺璁℃棩蹇椾俊鎭�
+     * @param tableName                 琛ㄥ悕锛屽瓙搴撴寮忚〃琛ㄥ悕
+     * @param initId                    鏈鎵ц鍓嶏紝閲囬泦搴撴暟鎹瓧鍏镐腑鍙傛暟閲屽搴旇〃鐨勬渶澶ф墽琛宨d
+     * @param curMaxMasterKeyValue      浠庡瓙搴撲腑鑾峰彇鍒扮殑鏈壒娆℃暟鎹渶澶х殑id
+     * @param operateCount              鎻掑叆鎶ヨ〃搴撴暟鎹殑鎬绘潯鏁�
+     */
+    private void updateOperateTableInfo(String tableName, long initId, int curMaxMasterKeyValue, int operateCount) {
+        String maxIdDictLabel = String.format("%s_dealt_max_id", tableName);
+        String latestTimeDictLabel = String.format("%s_latest_time", tableName);
+        String latestOperateCountDictLabel = String.format("%s_latest_operate_count", tableName);
+        DataTableEntity dictDte = baseDao.listTable(CmnConst.PRODUCT_SYS_DICT, "dict_name=? AND dict_label IN (?,?,?)", new Object[]{DICT_NAME_REQUEST_HISTORY, maxIdDictLabel, latestTimeDictLabel, latestOperateCountDictLabel});
+        FieldSetEntity maxIdDictFse = null;
+        FieldSetEntity latestTimeDictFse = null;
+        FieldSetEntity latestOperateCountDictFse = null;
+        if (!DataTableEntity.isEmpty(dictDte)) {
+            for (int i = 0; i < dictDte.getRows(); i++) {
+                FieldSetEntity dictFse = dictDte.getFieldSetEntity(i);
+                if (maxIdDictLabel.equals(dictFse.getString("dict_label"))) {
+                    maxIdDictFse = dictFse;
+                } else if (latestTimeDictLabel.equals(dictFse.getString("dict_label"))) {
+                    latestTimeDictFse = dictFse;
+                } else if (latestOperateCountDictLabel.equals(dictFse.getString("dict_label"))) {
+                    latestOperateCountDictFse = dictFse;
+                }
+            }
+        }
+
+        FieldSetEntity newDictFse = new FieldSetEntity(CmnConst.PRODUCT_SYS_DICT);
+        newDictFse.setValue("dict_name", DICT_NAME_REQUEST_HISTORY);
+        newDictFse.setValue("is_used", 1);
+        newDictFse.setValue("sequence", 1);
+        newDictFse.setValue("client_type", "Web");
+        newDictFse.setValue("created_utc_datetime", new Date());
+        newDictFse.setValue("created_by", 1);
+
+        // 鏈�澶d
+        if (initId < curMaxMasterKeyValue) {
+            saveDictFse(maxIdDictFse, newDictFse, maxIdDictLabel, curMaxMasterKeyValue);
+        }
+        // 鏈�杩戞墽琛屾椂闂�
+        saveDictFse(latestTimeDictFse, newDictFse, latestTimeDictLabel, new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()));
+        // 鏈�杩戜竴娆℃墽琛屾�绘暟
+        saveDictFse(latestOperateCountDictFse, newDictFse, latestOperateCountDictLabel, operateCount);
+    }
+
+    /**
+     * 淇濆瓨璇锋眰鍘嗗彶鍦ㄦ暟鎹瓧鍏搁噷闈㈢殑鍙傛暟fse
+     * @param saveDictFse       闇�瑕佷繚瀛榙ict鐨刦se
+     * @param modelDictFse      妯℃澘fse
+     * @param dictLabel         鏍囩
+     * @param dictValue         鍊�
+     */
+    private void saveDictFse(FieldSetEntity saveDictFse, FieldSetEntity modelDictFse, String dictLabel, Object dictValue) {
+        if (saveDictFse == null) {
+            saveDictFse = modelDictFse.clones();
+            saveDictFse.setValue("dict_label", dictLabel);
+        } else {
+            saveDictFse.setValue("updated_utc_datetime", new Date());
+            saveDictFse.setValue("updated_by", 1);
+        }
+        saveDictFse.setValue("dict_value", dictValue);
+        baseDao.saveFieldSetEntity(saveDictFse);
+    }
+
+    /**
+     * 鎷兼帴鎶ヨ〃搴撴煡璇㈣鍙�
+     * @param monthMap              鏈堜唤map
+     * @param reportTableNamePrefix 鎶ヨ〃搴撹〃鍚嶅墠缂�
+     * @param sourceInfo            閲囬泦琛╥d
+     * @return  鎶ヨ〃搴撴煡璇㈣鍙�
+     */
+    private String joinReportDbQuerySql(Map<String, Map<String, FieldSetEntity>> monthMap, String reportTableNamePrefix, String sourceInfo) {
+        StringBuilder sql = new StringBuilder(128);
+        String model = "SELECT * FROM %s_%s WHERE source_info='%s' AND %s";
+        for (Map.Entry<String, Map<String, FieldSetEntity>> entry : monthMap.entrySet()) {
+            String month = entry.getKey();
+            Set<String> masterKeySet = entry.getValue().keySet();
+            if (sql.length() > 0) {
+                sql.append("\nUNION ALL\n");
+            }
+            sql.append(String.format(model, reportTableNamePrefix, month, sourceInfo, BaseUtil.buildQuestionMarkFilter("pre_master_key", masterKeySet.toArray(), true)));
+        }
+        return sql.toString();
+    }
+
+    /**
+     * 鑾峰彇瀛愬簱瀵瑰簲琛ㄧ殑淇℃伅锛氳〃鍚嶏紝涓婚敭瀛楁锛屾椂闂村瓧娈电瓑
+     * @param subDbUuid     瀛愬簱杩炴帴閰嶇疆琛╱uid
+     * @return  JSONObject 瀛愬簱瀵瑰簲琛ㄧ殑淇℃伅
+     */
+    private JSONObject getSubDbTableInfo(String subDbUuid) {
+        String filter = String.format("data_source=? AND %s", BaseUtil.buildQuestionMarkFilter("source_table", operateTableList.size(), true));
+        List<String> paramList = Lists.newArrayList();
+        paramList.add(subDbUuid);
+        paramList.addAll(operateTableList);
+        DataTableEntity tableDte = baseDao.listTable(CmnConst.PRODUCT_SYS_DATA_COLLECT, filter, paramList.toArray());
+        JSONObject resultObj = new JSONObject();
+        for (int i = 0; i < tableDte.getRows(); i++) {
+            FieldSetEntity singleFse = tableDte.getFieldSetEntity(i);
+            String tableName = singleFse.getString("source_table").toLowerCase(Locale.ROOT);
+            resultObj.computeIfAbsent(tableName, s -> BaseUtil.fieldSetEntityToJson(singleFse));
+        }
+        return resultObj;
+    }
+
+    /**
+     * 鑾峰彇鐗规畩澶勭悊淇℃伅 t_wip_detail_dealt_max_id
+     * @return  JSONObject 鐗规畩澶勭悊淇℃伅
+     */
+    private JSONObject getSpDealInfo() {
+        DataTableEntity dictDte = baseDao.listTable(CmnConst.PRODUCT_SYS_DICT, "dict_name=?", new Object[]{DICT_NAME_REQUEST_HISTORY});
+        JSONObject resultObj = new JSONObject();
+        for (int i = 0; i < dictDte.getRows(); i++) {
+            FieldSetEntity singleFse = dictDte.getFieldSetEntity(i);
+            String dictLabel = singleFse.getString("dict_label");
+            String dictValue = singleFse.getString("dict_value");
+            if ("tableFormat".equals(dictLabel)) {
+                if (StringUtils.isEmpty(dictValue)) {
+                    throw new BaseException(ErrorCode.REQUEST_HISTORY_SP_DEAL_FAIL_NO_TABLE_DATA.getValue(), ErrorCode.REQUEST_HISTORY_SP_DEAL_FAIL_NO_TABLE_DATA.getText() + "瀛愬簱鍘嗗彶琛ㄦ牸寮�");
+                }
+                resultObj.put("tableFormat", singleFse.getString("dict_value"));
+            } else if ("dealTables".equals(dictLabel)) {
+                if (StringUtils.isEmpty(dictValue)) {
+                    throw new BaseException(ErrorCode.REQUEST_HISTORY_SP_DEAL_FAIL_NO_TABLE_DATA.getValue(), ErrorCode.REQUEST_HISTORY_SP_DEAL_FAIL_NO_TABLE_DATA.getText() + "闇�瑕佸鐞嗙殑琛ㄥ悕");
+                }
+                operateTableList = Arrays.asList(dictValue.split(","));
+            } else if ("pageSize".equals(dictLabel)) {
+                if (StringUtils.isEmpty(dictValue)) {
+                    throw new BaseException(ErrorCode.REQUEST_HISTORY_SP_DEAL_FAIL_NO_TABLE_DATA.getValue(), ErrorCode.REQUEST_HISTORY_SP_DEAL_FAIL_NO_TABLE_DATA.getText() + "鍗曢〉澶勭悊椤靛ぇ灏�");
+                }
+                pageSize = Integer.parseInt(dictValue);
+                if (pageSize <= 0) {
+                    throw new BaseException(ErrorCode.REQUEST_HISTORY_SP_DEAL_FAIL_NO_TABLE_DATA.getValue(), ErrorCode.REQUEST_HISTORY_SP_DEAL_FAIL_NO_TABLE_DATA.getText() + "姝g‘鐨勫崟椤靛鐞嗛〉澶у皬");
+                }
+            } else if ("subDbIp".equals(dictLabel)) {
+                if (StringUtils.isEmpty(dictValue)) {
+                    throw new BaseException(ErrorCode.REQUEST_HISTORY_SP_DEAL_FAIL_NO_TABLE_DATA.getValue(), ErrorCode.REQUEST_HISTORY_SP_DEAL_FAIL_NO_TABLE_DATA.getText() + "瀛愬簱鍦板潃");
+                }
+                subDbIp = dictValue;
+            } else if ("subDbPort".equals(dictLabel)) {
+                if (StringUtils.isEmpty(dictValue)) {
+                    throw new BaseException(ErrorCode.REQUEST_HISTORY_SP_DEAL_FAIL_NO_TABLE_DATA.getValue(), ErrorCode.REQUEST_HISTORY_SP_DEAL_FAIL_NO_TABLE_DATA.getText() + "瀛愬簱绔彛");
+                }
+                subDbPort = Integer.parseInt(dictValue);
+            } else if ("reportDbIp".equals(dictLabel)) {
+                if (StringUtils.isEmpty(dictValue)) {
+                    throw new BaseException(ErrorCode.REQUEST_HISTORY_SP_DEAL_FAIL_NO_TABLE_DATA.getValue(), ErrorCode.REQUEST_HISTORY_SP_DEAL_FAIL_NO_TABLE_DATA.getText() + "鎶ヨ〃搴撳湴鍧�");
+                }
+                reportDbIp = dictValue;
+            } else if ("reportDbPort".equals(dictLabel)) {
+                if (StringUtils.isEmpty(dictValue)) {
+                    throw new BaseException(ErrorCode.REQUEST_HISTORY_SP_DEAL_FAIL_NO_TABLE_DATA.getValue(), ErrorCode.REQUEST_HISTORY_SP_DEAL_FAIL_NO_TABLE_DATA.getText() + "鎶ヨ〃搴撶鍙�");
+                }
+                reportDbPort = Integer.parseInt(dictValue);
+            } else {
+                String dictLabelLowerCase = dictLabel.toLowerCase(Locale.ROOT);
+                for (String tableName : operateTableList) {
+                    String tablenNameLowerCase = tableName.toLowerCase(Locale.ROOT);
+                    if (dictLabelLowerCase.startsWith(tablenNameLowerCase)) {
+                        JSONObject singleObj = (JSONObject) resultObj.computeIfAbsent(tablenNameLowerCase, s -> new JSONObject());
+                        singleObj.put(dictLabelLowerCase.replace(String.format("%s_", tablenNameLowerCase), ""), singleFse.getValue("dict_value"));
+                    }
+                }
+            }
+        }
+        return resultObj;
+    }
+
+    /**
+     * 澶勭悊瀛愬簱涓煡璇㈠埌鐨勬暟鎹紝鎸夌収鏈堜唤鍜屼富閿垎鍒疆浜庝笉鍚岀殑瀹瑰櫒涓�
+     * @param singlePageDataDte         瀛愬簱鏁版嵁
+     * @param singleSubDbTableInfoObj   琛ㄤ俊鎭�
+     * @param monthMap                  瀹瑰櫒锛歁ap<yyyyMM, <masterKey, Fse>>
+     */
+    private void dealSubDbData(DataTableEntity singlePageDataDte, JSONObject singleSubDbTableInfoObj, Map<String, Map<String, FieldSetEntity>> monthMap) {
+        String masterKeyFieldName = singleSubDbTableInfoObj.getString("auto_field");
+        String timeFieldName = singleSubDbTableInfoObj.getString("time_field");
+        for (int i = 0; i < singlePageDataDte.getRows(); i++) {
+            FieldSetEntity singlePageDataFse = singlePageDataDte.getFieldSetEntity(i);
+            String timeStr = singlePageDataFse.getDate(timeFieldName, "yyyyMM");
+            String masterValue = singlePageDataFse.getString(masterKeyFieldName);
+            monthMap.computeIfAbsent(timeStr, s -> Maps.newHashMap()).put(masterValue, singlePageDataFse);
+        }
+    }
+
+    /**
+     * 鍋滄
+     */
+    private void stop(DataBaseEntity... dbeArr) {
+        if (dbeArr != null) {
+            for (DataBaseEntity dbe : dbeArr) {
+                if (dbe != null && dbe.getDao() != null) {
+                    dbe.getDao().closeConnection();
+                }
+            }
+        }
+        processingFlag = false;
+        stopFlag = false;
+    }
+    /*========================璇锋眰鍘嗗彶-final========================*/
+}

--
Gitblit v1.9.2