浏览代码

远通数据源接入机制:
①系统启动时执行全数据检查机制
②每天每个整点的10分和15分分别执行原始数据和小时用水量数据的检查 检查范围为当前时间到0点的数据

1037015548@qq.com 1 年之前
父节点
当前提交
f555206ad4

+ 5 - 0
pom.xml

@@ -256,6 +256,11 @@
 			<version>2.5.0</version>
 		</dependency>
 
+		<dependency>
+			<groupId>com.oracle.database.jdbc</groupId>
+			<artifactId>ojdbc8</artifactId>
+			<version>19.3.0.0</version>
+		</dependency>
 	</dependencies>
 
 	<build>

+ 466 - 0
src/main/java/com/shkpr/service/aimodelpower/bizmgr/KprAimTapWaterBizFun.java

@@ -0,0 +1,466 @@
+package com.shkpr.service.aimodelpower.bizmgr;
+
+import com.global.base.log.LogLevelFlag;
+import com.global.base.log.LogPrintMgr;
+import com.global.base.tools.FastJsonUtil;
+import com.shkpr.service.aimodelpower.commtools.TimeTool;
+import com.shkpr.service.aimodelpower.constants.LogFlagBusiType;
+import com.shkpr.service.aimodelpower.dbdao.DBMgrProxy;
+import com.shkpr.service.aimodelpower.dbdao.otherDataSource.service.intef.WaterTapWaterService;
+import com.shkpr.service.aimodelpower.dto.TraceRunnable;
+import com.shkpr.service.aimodelpower.globalmgr.ThreadTaskMgr;
+import com.shkpr.service.aimodelpower.globalmgr.TraceLogMgr;
+import org.apache.commons.collections.list.SynchronizedList;
+import org.springframework.util.CollectionUtils;
+
+import java.text.DateFormat;
+import java.time.Duration;
+import java.time.LocalDateTime;
+import java.time.format.DateTimeFormatter;
+import java.util.*;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
+import java.util.stream.Collectors;
+
+/**
+ * @ClassName KprAimTapWaterBizFun
+ * @Description: TODO
+ * @Author LX
+ * @Date 2024/5/22
+ * @Version V1.0
+ **/
+public class KprAimTapWaterBizFun {
+    private static final String MSG_SUCCESS = "success.";
+    private static final String MSG_FAILED = "failed.";
+    private static final String mStrClassName = "KprAimTapWaterBizFun";
+    private static final String EMPTY_NULL = "NULL";
+
+    public static WaterTapWaterService getWaterTapWaterApi(){
+        return DBMgrProxy.getInstance().applyWaterTapWaterService();
+    }
+    static DateTimeFormatter formater = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
+
+    //TODO 小时用水量 每天整点10分检查并写入,检查范围为当前时间到今天0点
+    public static void checkRecordAllData(){
+        //TODO 检查小时用水量
+        DateTimeFormatter formater = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
+
+        System.out.println("检查机制-计算小时用水量开始时间:"+TimeTool.convertUTC2DateStr(TimeTool.getCurMsUTC(),TimeTool.TIMESTAMP_FORMAT));
+        System.out.println("检查机制-计算小时用水量进行中:......");
+        List<Map<String, Object>> configList = getWaterTapWaterApi().getWaterCollectionConfigList(null);
+        if (!CollectionUtils.isEmpty(configList)) {
+            //TODO 按照组织机构分组
+            Map<Object, List<Map<String, Object>>> groupedData =
+                    configList.stream().collect(Collectors.groupingBy(item -> item.get("org_name")));
+            final CountDownLatch latch = new CountDownLatch(configList.size());
+            for (Object key:groupedData.keySet()){
+                try {
+                    ThreadTaskMgr.runTask(new TraceRunnable(TraceLogMgr.getTraceId()) {
+                        @Override
+                        public void function() {
+                            //TODO 根据当前配置信息item 查询远通数据中的历史数据
+                            //TODO 首先查询当前水厂设备的从昨天之后到得到数据的数据
+                            LocalDateTime today = LocalDateTime.now();
+                            LocalDateTime startDateTime = today.withHour(0).withMinute(0).withSecond(0).withNano(0);
+
+                            //TODO 需计算的循环天数
+
+                            //TODO 此循环天数每一天所查的是所有设备每小时数据合
+                            LocalDateTime newStartDateTime = startDateTime;
+                            String startDate = newStartDateTime.format(formater);
+                            String endDate = today.withMinute(0).withSecond(0).format(formater);
+                            List<Map<String, Object>> deviceList = groupedData.get(key);
+                            //TODO 循环获取该天该水厂每个设备数据
+
+                            //TODO 查询当前天日期内每小时的设备数据
+                            for (int i = 0; i < Integer.valueOf(String.valueOf(Duration.between(startDateTime, today.withMinute(0).withSecond(0)).toHours())); i++) {
+                                String startTime = newStartDateTime.withHour(i).format(formater);
+                                String endTime = newStartDateTime.minusHours(-(i + 1)).format(formater);
+
+                                Map<String, Object> recordAllEntity = new HashMap<>();//需要添加的实体数据
+                                recordAllEntity.put("org_name", key.toString());//水厂
+                                recordAllEntity.put("time", endTime);//采集时间(小时的最后时间)
+                                recordAllEntity.put("value", null);
+                                recordAllEntity.put("value_tag", "water");
+                                recordAllEntity.put("collcation_tag_array", FastJsonUtil.toJSON(deviceList));
+                                Double value = null;
+                                //TODO 此循环计算该小时所有设备的用水量
+                                for (Map<String, Object> item : deviceList) {
+                                    Integer itemCount = getWaterTapWaterApi().getTabWaterHistoryCount(
+                                            " WHERE TAG_CODE = '" + item.get("collcation_tag") + "' " +
+                                                    " and QCQUISITION_TIME >= to_date('" + startDate + "', 'yyyy-mm-dd hh24:mi:ss')" +
+                                                    " and QCQUISITION_TIME < to_date('" + endDate + "', 'yyyy-mm-dd hh24:mi:ss')");
+                                    if (itemCount != null && itemCount > 0) {
+                                        List<Map<String, Object>> tapWaterHistoryList = getWaterTapWaterApi().getPageZILAISHUI_HISTORY2(itemCount, 0,
+                                                " AND TAG_CODE = '" + item.get("collcation_tag") + "' " +
+                                                        " and QCQUISITION_TIME >= to_date('" + startTime + "', 'yyyy-mm-dd hh24:mi:ss')" +
+                                                        " and QCQUISITION_TIME < to_date('" + endTime + "', 'yyyy-mm-dd hh24:mi:ss')" +
+                                                        " order by QCQUISITION_TIME");
+                                        //TODO tapWaterHistoryList此集合为该设备该小时内的数据,取第一条和最后一条的相差值作为用水量
+                                        if (!CollectionUtils.isEmpty(tapWaterHistoryList) && tapWaterHistoryList.size() > 1) {
+                                            Double firstValue = tapWaterHistoryList.get(0).get("VAL") != null ? Double.valueOf(tapWaterHistoryList.get(0).get("val").toString()) : null;
+                                            Double lastValue = tapWaterHistoryList.get((tapWaterHistoryList.size() - 1)).get("VAL") != null ? Double.valueOf(tapWaterHistoryList.get((tapWaterHistoryList.size() - 1)).get("val").toString()) : null;
+                                            if (firstValue != null && lastValue != null) {
+                                                //到此处是该小时一个设备的用水量已加上
+                                                if (value == null) {
+                                                    value = 0.00;
+                                                }
+                                                System.out.println();
+                                                value += Math.abs(lastValue - firstValue);
+                                            }
+                                        }
+                                    }
+                                }
+                                recordAllEntity.put("value", value);
+                                List<Map<String, Object>> queryWaterRecord = getWaterTapWaterApi().getWaterCollectionRecordAllList(1, 0,
+                                        " WHERE org_name = '" + recordAllEntity.get("org_name")
+                                                + "' AND time = '" + recordAllEntity.get("time") + "' AND value_tag = '" + recordAllEntity.get("value_tag") + "'");
+                                if (CollectionUtils.isEmpty(queryWaterRecord)) {
+                                    //TODO 说明不存在,进行插入
+                                    int insertCode = getWaterTapWaterApi().insertWaterCollectionRecordAll(" (" +
+                                            "'" + recordAllEntity.get("org_name") + "'," +
+                                            "'" + recordAllEntity.get("time") + "'," +
+                                            "'" + recordAllEntity.get("value") + "'," +
+                                            "'" + recordAllEntity.get("value_tag") + "'," +
+                                            "'" + recordAllEntity.get("collcation_tag_array") + "'" +
+                                            ") ");
+                                    if (insertCode < 0) {
+                                        LogPrintMgr.getInstance().printLogMsg(LogLevelFlag.LOG_ERROR
+                                                , mStrClassName
+                                                , mStrClassName
+                                                , String.format("Batch initTapWaterDataThread 未成功:{%s} ",
+                                                        FastJsonUtil.toJSON(recordAllEntity)));
+                                    }
+                                }
+                            }
+                            latch.countDown();
+                        }
+                    });
+                }catch(Exception ex){}
+            }
+            try{latch.await();}catch(Exception ex){}
+            System.out.println("检查机制-计算小时用水量结束时间:"+TimeTool.convertUTC2DateStr(TimeTool.getCurMsUTC(),TimeTool.TIMESTAMP_FORMAT));
+        }
+    }
+
+    //TODO 原始历史数据 每天整点15分检查并写入,检查范围为当前时间到昨天
+    public static void checkRecordData(){
+//TODO ① 首先查询水厂设备配置信息
+        try {
+            List<Map<String, Object>> configList = getWaterTapWaterApi().getWaterCollectionConfigList(null);
+            if(!CollectionUtils.isEmpty(configList)){
+                //声明总数据的数据数组
+                List<Map<String,Object>> newRecordAll = Collections.synchronizedList(new LinkedList<Map<String,Object>>());
+                //TODO ②开启多线程并发处理各水厂设备的数据
+                System.out.println("检查机制--开始时间:"+TimeTool.convertUTC2DateStr(TimeTool.getCurMsUTC(),TimeTool.TIMESTAMP_FORMAT));
+                System.out.println("检查机制--进行中:......");
+                final CountDownLatch latch = new CountDownLatch(configList.size());
+                for(Map<String,Object> item:configList){
+                    try{
+                        ThreadTaskMgr.runTask(new TraceRunnable(TraceLogMgr.getTraceId()) {
+                            @Override
+                            public void function() {
+                                //TODO 根据当前配置信息item 查询远通数据中的历史数据
+                                //TODO 首先查询当前水厂设备的昨天0点之后到当前时间最新数据的数据
+                                LocalDateTime today = LocalDateTime.now();
+                                LocalDateTime yesterday = today.minusDays(1).withHour(0).withMinute(0).withSecond(0).withNano(0);
+                                Integer itemCount = getWaterTapWaterApi().getTabWaterHistoryCount(" WHERE TAG_CODE = '"+item.get("collcation_tag")+"' " +
+                                        " and QCQUISITION_TIME >= to_date('"+yesterday.format(formater)+"', 'yyyy-mm-dd hh24:mi:ss')");
+                                if(itemCount!=null&&itemCount>0) {
+                                    //TODO 优化 以分页方式查询所有,初始分页行数定为2000查询速率较好
+                                    int pageNum = itemCount%2000==0?itemCount/2000:(itemCount/2000)+1;//总页数
+                                    Integer limit = 2000;
+                                    if(pageNum<=1){
+                                        limit = itemCount;//说明总数比第一页小
+                                    }
+                                    for (int i = 0; i < pageNum; i++) {
+                                        Integer offset = i*limit;
+                                        //tapWaterHistoryList 为远通水量数据源
+                                        //TODO 因为是orcale数据库 分页方式以伪列rownum为分页条件,因此limit实际上永远比offset大2000,因此只要不是第一页,limit=offset+2000
+                                        Integer limitNew = 0;
+                                        if(i>0){
+                                            limitNew = offset+2000;
+                                        }else{
+                                            limitNew = 2000;
+                                        }
+                                        List<Map<String,Object>> tapWaterHistoryList = getWaterTapWaterApi().getPageZILAISHUI_HISTORY2(limitNew,offset," " +
+                                                "AND TAG_CODE = '"+item.get("collcation_tag")+"' " +
+                                                "and QCQUISITION_TIME >= to_date('"+yesterday.format(formater)+"', 'yyyy-mm-dd hh24:mi:ss')");
+                                        if(!CollectionUtils.isEmpty(tapWaterHistoryList)){
+                                            //TODO 循环远通水量数据列表,查询数据不存在的话就插入
+                                            for (int j = 0; j < tapWaterHistoryList.size(); j++) {
+                                                List<Map<String,Object>> queryWaterRecord = getWaterTapWaterApi().getWaterCollectionRecordList(1,0,
+                                                        " WHERE collcation_tag = '"+tapWaterHistoryList.get(j).get("TAG_CODE")
+                                                                +"' AND org_name = '"+tapWaterHistoryList.get(j).get("NAME")+"' AND time = '"+TimeTool.convertDateStr2UTC(tapWaterHistoryList.get(j).get("QCQUISITION_TIME").toString())+"'");
+                                                if(CollectionUtils.isEmpty(queryWaterRecord)){
+                                                    //TODO 说明没插入过本系统,执行插入
+                                                    String extend =  " ('"+tapWaterHistoryList.get(j).get("TAG_CODE")+"','"+tapWaterHistoryList.get(j).get("NAME")+"',"
+                                                            + ""+TimeTool.convertDateStr2UTC(tapWaterHistoryList.get(j).get("QCQUISITION_TIME").toString())+","
+                                                            + "'"+tapWaterHistoryList.get(j).get("VAL")+"',"
+                                                            + TimeTool.convertDateStr2UTC(tapWaterHistoryList.get(j).get("UPDATE_TIME").toString())
+                                                            +") ";
+                                                    int insertCode = getWaterTapWaterApi().insertWaterCollectionRecord(extend);
+                                                    if(insertCode<=0){
+                                                        LogPrintMgr.getInstance().printLogMsg(LogLevelFlag.LOG_ERROR
+                                                                , mStrClassName
+                                                                , mStrClassName
+                                                                , String.format("Batch initTapWaterDataThread 未成功:{%s} ",
+                                                                        extend));
+                                                    }
+                                                }
+                                            }
+                                        }
+                                    }
+                                }
+                                latch.countDown();
+                            }
+                        });
+                    }catch(Exception ex){
+                        LogPrintMgr.getInstance().printLogMsg(LogLevelFlag.LOG_ERROR
+                                , mStrClassName
+                                , mStrClassName
+                                , String.format("Batch initTapWaterDataThread 水厂:{%s},标识:{%s} ERROR:{%s} ",
+                                        item.get("org_name"),
+                                        item.get("collcation_tag")
+                                        , ex.getLocalizedMessage()));
+                    }
+                }
+                latch.await();
+                System.out.println("检查机制--结束时间:"+TimeTool.convertUTC2DateStr(TimeTool.getCurMsUTC(),TimeTool.TIMESTAMP_FORMAT));
+            }
+        }catch(Exception ex){
+            LogPrintMgr.getInstance().printLogMsg(LogLevelFlag.LOG_ERROR
+                    , mStrClassName
+                    , mStrClassName
+                    , String.format("Batch initTapWaterData ERROR:{%s} "
+                            , ex.getLocalizedMessage()));
+        }
+    }
+
+    //TODO 初始化添加对比远通数据
+    public static void initTapWaterData(){
+        //TODO ① 首先查询水厂设备配置信息
+        try {
+            List<Map<String, Object>> configList = getWaterTapWaterApi().getWaterCollectionConfigList(null);
+            if(!CollectionUtils.isEmpty(configList)){
+                //声明总数据的数据数组
+                List<Map<String,Object>> newRecordAll = Collections.synchronizedList(new LinkedList<Map<String,Object>>());
+                //TODO ②开启多线程并发处理各水厂设备的数据
+                System.out.println("开始时间:"+TimeTool.convertUTC2DateStr(TimeTool.getCurMsUTC(),TimeTool.TIMESTAMP_FORMAT));
+                System.out.println("进行中:......");
+                final CountDownLatch latch = new CountDownLatch(configList.size());
+                for(Map<String,Object> item:configList){
+                    try{
+                        ThreadTaskMgr.runTask(new TraceRunnable(TraceLogMgr.getTraceId()) {
+                            @Override
+                            public void function() {
+                                //TODO 根据当前配置信息item 查询远通数据中的历史数据
+                                //TODO 首先查询当前水厂设备的2023-01-01之后到最新数据的数据总数,然后分页形式获取数据
+                                Integer itemCount = getWaterTapWaterApi().getTabWaterHistoryCount(" WHERE TAG_CODE = '"+item.get("collcation_tag")+"' and QCQUISITION_TIME >= to_date('2023-01-01 00:00:00', 'yyyy-mm-dd hh24:mi:ss')");
+                                if(itemCount!=null&&itemCount>0) {
+                                    //TODO 优化 以分页方式查询所有,初始分页行数定为2000查询速率较好
+                                    int pageNum = itemCount%2000==0?itemCount/2000:(itemCount/2000)+1;//总页数
+                                    Integer limit = 2000;
+                                    if(pageNum<=1){
+                                        limit = itemCount;//说明总数比第一页小
+                                    }
+                                    for (int i = 0; i < pageNum; i++) {
+                                        Integer offset = i*limit;
+                                        //tapWaterHistoryList 为远通水量数据源
+                                        //TODO 因为是orcale数据库 分页方式以伪列rownum为分页条件,因此limit实际上永远比offset大2000,因此只要不是第一页,limit=offset+2000
+                                        Integer limitNew = 0;
+                                        if(i>0){
+                                            limitNew = offset+2000;
+                                        }else{
+                                            limitNew = 2000;
+                                        }
+                                        List<Map<String,Object>> tapWaterHistoryList = getWaterTapWaterApi().getPageZILAISHUI_HISTORY2(limitNew,offset," AND TAG_CODE = '"+item.get("collcation_tag")+"' and QCQUISITION_TIME >= to_date('2023-01-01 00:00:00', 'yyyy-mm-dd hh24:mi:ss')");
+                                        if(!CollectionUtils.isEmpty(tapWaterHistoryList)){
+                                            //TODO 循环远通水量数据列表,查询数据不存在的话就插入
+                                            for (int j = 0; j < tapWaterHistoryList.size(); j++) {
+                                                List<Map<String,Object>> queryWaterRecord = getWaterTapWaterApi().getWaterCollectionRecordList(1,0,
+                                                        " WHERE collcation_tag = '"+tapWaterHistoryList.get(j).get("TAG_CODE")
+                                                        +"' AND org_name = '"+tapWaterHistoryList.get(j).get("NAME")+"' AND time = '"+TimeTool.convertDateStr2UTC(tapWaterHistoryList.get(j).get("QCQUISITION_TIME").toString())+"'");
+                                                if(CollectionUtils.isEmpty(queryWaterRecord)){
+                                                    //TODO 说明没插入过本系统,执行插入
+                                                    String extend =  " ('"+tapWaterHistoryList.get(j).get("TAG_CODE")+"','"+tapWaterHistoryList.get(j).get("NAME")+"',"
+                                                            + ""+TimeTool.convertDateStr2UTC(tapWaterHistoryList.get(j).get("QCQUISITION_TIME").toString())+","
+                                                            + "'"+tapWaterHistoryList.get(j).get("VAL")+"',"
+                                                            + TimeTool.convertDateStr2UTC(tapWaterHistoryList.get(j).get("UPDATE_TIME").toString())
+                                                            +") ";
+                                                    int insertCode = getWaterTapWaterApi().insertWaterCollectionRecord(extend);
+                                                    if(insertCode<=0){
+                                                        LogPrintMgr.getInstance().printLogMsg(LogLevelFlag.LOG_ERROR
+                                                                , mStrClassName
+                                                                , mStrClassName
+                                                                , String.format("Batch initTapWaterDataThread 未成功:{%s} ",
+                                                                        extend));
+                                                    }
+                                                }
+                                            }
+                                        }
+                                    }
+                                }
+                                latch.countDown();
+                            }
+                        });
+                    }catch(Exception ex){
+                        LogPrintMgr.getInstance().printLogMsg(LogLevelFlag.LOG_ERROR
+                                , mStrClassName
+                                , mStrClassName
+                                , String.format("Batch initTapWaterDataThread 水厂:{%s},标识:{%s} ERROR:{%s} ",
+                                        item.get("org_name"),
+                                        item.get("collcation_tag")
+                                        , ex.getLocalizedMessage()));
+                    }
+                }
+                latch.await();
+                System.out.println("结束时间:"+TimeTool.convertUTC2DateStr(TimeTool.getCurMsUTC(),TimeTool.TIMESTAMP_FORMAT));
+            }
+        }catch(Exception ex){
+            LogPrintMgr.getInstance().printLogMsg(LogLevelFlag.LOG_ERROR
+                    , mStrClassName
+                    , mStrClassName
+                    , String.format("Batch initTapWaterData ERROR:{%s} "
+                            , ex.getLocalizedMessage()));
+        }
+    }
+
+    //TODO 初始化添加计算水厂所有设备每日的每小时用水量计算
+    public static void initWaterCollecationReacordAll(){
+        //TODO ① 首先查询水厂设备配置信息
+        try {
+
+            System.out.println("计算小时用水量开始时间:"+TimeTool.convertUTC2DateStr(TimeTool.getCurMsUTC(),TimeTool.TIMESTAMP_FORMAT));
+            System.out.println("计算小时用水量进行中:......");
+            List<Map<String, Object>> configList = getWaterTapWaterApi().getWaterCollectionConfigList(null);
+            if (!CollectionUtils.isEmpty(configList)) {
+                //TODO 按照组织机构分组
+                Map<Object, List<Map<String, Object>>> groupedData =
+                        configList.stream().collect(Collectors.groupingBy(item -> item.get("org_name")));
+                final CountDownLatch latch = new CountDownLatch(groupedData.keySet().size());
+
+                //TODO 外层循环组织机构
+                for (Object key:groupedData.keySet()){
+                    try{
+                        ThreadTaskMgr.runTask(new TraceRunnable(TraceLogMgr.getTraceId()) {
+                            @Override
+                            public void function() {
+                                //TODO 根据当前配置信息item 查询远通数据中的历史数据
+                                //TODO 首先查询当前水厂设备的从2023-01-01之后到得到数据
+                                LocalDateTime startDateTime = LocalDateTime.of(2023, 01, 01, 00, 00, 00);
+
+                                //TODO 需计算的循环天数
+                                Long days = 0L;
+                                days = Duration.between(startDateTime, LocalDateTime.now()).toDays();
+
+                                //TODO 此循环天数每一天所查的是所有设备每小时数据合
+                                final CountDownLatch latch2 = new CountDownLatch(days.intValue());
+                                for(Long k = 0L;k<days;k++) {
+                                    LocalDateTime newStartDateTime = startDateTime.minusDays(-k.intValue());
+                                    String startDate = newStartDateTime.format(formater);
+                                    String endDate = newStartDateTime.minusDays(-1).format(formater);
+                                    try {
+                                        ThreadTaskMgr.runTask(new TraceRunnable(TraceLogMgr.getTraceId()) {
+                                            @Override
+                                            public void function() {
+
+                                                List<Map<String, Object>> deviceList = groupedData.get(key);
+
+                                                //TODO 循环获取该天该水厂每个设备数据
+
+                                                //TODO 查询当前天日期内每小时的设备数据
+                                                for (int i = 0; i < 24; i++) {
+                                                    String startTime = newStartDateTime.withHour(i).format(formater);
+                                                    String endTime = newStartDateTime.minusHours(-(i + 1)).format(formater);
+
+                                                    Map<String, Object> recordAllEntity = new HashMap<>();//需要添加的实体数据
+                                                    recordAllEntity.put("org_name", key.toString());//水厂
+                                                    recordAllEntity.put("time", endTime);//采集时间(小时的最后时间)
+                                                    recordAllEntity.put("value", null);
+                                                    recordAllEntity.put("value_tag", "water");
+                                                    recordAllEntity.put("collcation_tag_array", FastJsonUtil.toJSON(deviceList));
+                                                    Double value = null;
+                                                    //TODO 此循环计算该小时所有设备的用水量
+                                                    for (Map<String, Object> item : deviceList) {
+                                                        Integer itemCount = getWaterTapWaterApi().getTabWaterHistoryCount(
+                                                                " WHERE TAG_CODE = '" + item.get("collcation_tag") + "' " +
+                                                                        " and QCQUISITION_TIME >= to_date('" + startDate + "', 'yyyy-mm-dd hh24:mi:ss')" +
+                                                                        " and QCQUISITION_TIME < to_date('" + endDate + "', 'yyyy-mm-dd hh24:mi:ss')");
+                                                        if (itemCount != null && itemCount > 0) {
+                                                            List<Map<String, Object>> tapWaterHistoryList = getWaterTapWaterApi().getPageZILAISHUI_HISTORY2(itemCount, 0,
+                                                                    " AND TAG_CODE = '" + item.get("collcation_tag") + "' " +
+                                                                            " and QCQUISITION_TIME >= to_date('" + startTime + "', 'yyyy-mm-dd hh24:mi:ss')" +
+                                                                            " and QCQUISITION_TIME < to_date('" + endTime + "', 'yyyy-mm-dd hh24:mi:ss')" +
+                                                                            " order by QCQUISITION_TIME");
+                                                            //TODO tapWaterHistoryList此集合为该设备该小时内的数据,取第一条和最后一条的相差值作为用水量
+                                                            if (!CollectionUtils.isEmpty(tapWaterHistoryList) && tapWaterHistoryList.size() > 1) {
+                                                                Double firstValue = tapWaterHistoryList.get(0).get("VAL") != null ? Double.valueOf(tapWaterHistoryList.get(0).get("val").toString()) : null;
+                                                                Double lastValue = tapWaterHistoryList.get((tapWaterHistoryList.size() - 1)).get("VAL") != null ? Double.valueOf(tapWaterHistoryList.get((tapWaterHistoryList.size() - 1)).get("val").toString()) : null;
+                                                                if (firstValue != null && lastValue != null) {
+                                                                    //到此处是该小时一个设备的用水量已加上
+                                                                    if (value == null) {
+                                                                        value = 0.00;
+                                                                    }
+                                                                    value += Math.abs(lastValue - firstValue);
+                                                                }
+                                                            }
+                                                        }
+                                                    }
+                                                    recordAllEntity.put("value", value);
+                                                    List<Map<String, Object>> queryWaterRecord = getWaterTapWaterApi().getWaterCollectionRecordAllList(1, 0,
+                                                            " WHERE org_name = '" + recordAllEntity.get("org_name")
+                                                                    + "' AND time = '" + recordAllEntity.get("time") + "' AND value_tag = '" + recordAllEntity.get("value_tag") + "'");
+                                                    if (CollectionUtils.isEmpty(queryWaterRecord)) {
+                                                        //TODO 说明不存在,进行插入
+                                                        int insertCode = getWaterTapWaterApi().insertWaterCollectionRecordAll(" (" +
+                                                                "'" + recordAllEntity.get("org_name") + "'," +
+                                                                "'" + recordAllEntity.get("time") + "'," +
+                                                                "'" + recordAllEntity.get("value") + "'," +
+                                                                "'" + recordAllEntity.get("value_tag") + "'," +
+                                                                "'" + recordAllEntity.get("collcation_tag_array") + "'" +
+                                                                ") ");
+                                                        if (insertCode < 0) {
+                                                            LogPrintMgr.getInstance().printLogMsg(LogLevelFlag.LOG_ERROR
+                                                                    , mStrClassName
+                                                                    , mStrClassName
+                                                                    , String.format("Batch initTapWaterDataThread 未成功:{%s} ",
+                                                                            FastJsonUtil.toJSON(recordAllEntity)));
+                                                        }
+                                                    }
+                                                }
+                                                latch2.countDown();
+                                            }
+                                        });
+                                    }catch(Exception ex){
+
+                                    }
+                                }
+                                try {
+                                    latch2.await();
+                                }catch(Exception ex){
+
+                                }
+                                latch.countDown();
+                            }
+                        });
+                    }catch(Exception ex){
+                        LogPrintMgr.getInstance().printLogMsg(LogLevelFlag.LOG_ERROR
+                                , mStrClassName
+                                , mStrClassName
+                                , String.format("Batch initWaterReacordAll ERROR:{%s} "
+                                        , ex.getLocalizedMessage()));
+                    }
+                }
+                latch.await();
+                System.out.println("计算小时用水量结束时间:"+TimeTool.convertUTC2DateStr(TimeTool.getCurMsUTC(),TimeTool.TIMESTAMP_FORMAT));
+            }
+        }catch(Exception ex){
+            LogPrintMgr.getInstance().printLogMsg(LogLevelFlag.LOG_ERROR
+                    , mStrClassName
+                    , mStrClassName
+                    , String.format("Batch initWaterCollecationReacordAll ERROR:{%s} "
+                            , ex.getLocalizedMessage()));
+        }
+    }
+}

+ 121 - 0
src/main/java/com/shkpr/service/aimodelpower/configuration/ChildPgDataSourceConfig.java

@@ -0,0 +1,121 @@
+package com.shkpr.service.aimodelpower.configuration;
+
+import com.shkpr.service.aimodelpower.globalcache.GlobalData;
+import com.zaxxer.hikari.HikariConfig;
+import com.zaxxer.hikari.HikariDataSource;
+import org.apache.ibatis.session.SqlSessionFactory;
+import org.mybatis.spring.SqlSessionFactoryBean;
+import org.mybatis.spring.SqlSessionTemplate;
+import org.mybatis.spring.annotation.MapperScan;
+import org.springframework.beans.factory.annotation.Qualifier;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.boot.context.properties.ConfigurationProperties;
+import org.springframework.boot.jdbc.DataSourceBuilder;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
+import org.springframework.jdbc.datasource.DataSourceTransactionManager;
+
+import javax.annotation.PostConstruct;
+import javax.sql.DataSource;
+
+/**
+ * @ClassName ChildPgDataSourceConfig
+ * @Description: TODO
+ * @Author LX
+ * @Date 2024/5/21
+ * @Version V1.0
+ **/
+@Configuration
+@MapperScan(basePackages = "com.shkpr.service.aimodelpower.dbdao.mapper.childpg",sqlSessionFactoryRef = "db2SqlSessionFactory")
+public class ChildPgDataSourceConfig {
+
+    @Value("${spring.datasource.db2.driver-class-name:}")
+    private String driveClass = "org.postgresql.Driver";
+
+    @Value("${spring.datasource.db2.jdbc-url:}")
+    private String url = "";
+
+    @Value("${spring.datasource.db2.username:}")
+    private String username = "";
+
+    @Value("${spring.datasource.db2.password:}")
+    private String password = "";
+
+//    @Value("${spring.datasource.db2.maximum-pool-size:200}")
+//    private Integer maxPoolSize;
+//
+//    @Value("${spring.datasource.db2.minimum-idle:1}")
+//    private Integer minIdle;
+//
+//    @Value("${spring.datasource.db2.connection-test-query:}")
+//    private String connectionTestQuery;
+//
+//    @Value("${spring.datasource.db2.max-lifetime:120000}")
+//    private Long maxLifetime;
+//
+//    @Value("${spring.datasource.db2.idle-timeout:30000}")
+//    private Long idleTimeout;
+//
+//    @Value("${spring.datasource.db2.connection-timeout:30000}")
+//    private Long connectionTimeout;
+//
+//    @Value("${spring.datasource.db2.validation-timeout:30000}")
+//    private Long validTimeout;
+//
+//    @Value("${spring.datasource.db2.init-failed-timeout:-1}")
+//    private Long initFailedTimeout;
+
+    @Bean(name = "childDatasource")
+    //@ConfigurationProperties(prefix = "spring.datasource.db2")
+    public DataSource childDataSource() {
+        HikariDataSource obj = new HikariDataSource(getConfig());
+        try {
+            obj.setLoginTimeout((int)(30000/1000));
+        }catch (Exception e){}
+        return obj;
+        //return DataSourceBuilder.create().build();
+        //Spring Boot 2.x默认使用HikariCP
+    }
+
+    private HikariConfig getConfig() {
+        HikariConfig hikariConfig = new HikariConfig();
+        hikariConfig.setDriverClassName(driveClass);
+        hikariConfig.setJdbcUrl(url);
+        hikariConfig.setUsername(username);
+        hikariConfig.setPassword(password);
+
+        hikariConfig.setMaximumPoolSize(200);
+        hikariConfig.setMinimumIdle(1);
+        hikariConfig.setConnectionTestQuery("SELECT 1");
+        hikariConfig.setMaxLifetime(120000);
+        hikariConfig.setIdleTimeout(30000);
+        hikariConfig.setConnectionTimeout(30000);
+        hikariConfig.setValidationTimeout(30000);
+        hikariConfig.setInitializationFailTimeout(-1);
+        return hikariConfig;
+    }
+
+    @Bean("childSqlSessionFactory")
+    public SqlSessionFactory childSqlSessionFactoryBean(@Qualifier("childDatasource") DataSource dataSource) throws Exception {
+        SqlSessionFactoryBean sessionFactoryBean = new SqlSessionFactoryBean();
+        sessionFactoryBean.setDataSource(dataSource);
+
+        org.apache.ibatis.session.Configuration configuration = new org.apache.ibatis.session.Configuration();
+        configuration.setCallSettersOnNulls(true);       //数据库中字段值为null时也要求返回
+        configuration.setMapUnderscoreToCamelCase(true); //开启驼峰映射
+        configuration.setCacheEnabled(false);
+        sessionFactoryBean.setConfiguration(configuration);
+        return sessionFactoryBean.getObject();
+    }
+
+    @Bean("childSqlSessionTemplate")
+    public SqlSessionTemplate childSqlSessionTemplate(@Qualifier("childSqlSessionFactory") SqlSessionFactory sessionFactory) {
+        return new SqlSessionTemplate(sessionFactory);
+    }
+
+    @Bean(name = "childDbTransactionManager")
+    public DataSourceTransactionManager childDbTransactionManager(@Qualifier("childDatasource") DataSource dataSource){
+        return new DataSourceTransactionManager(dataSource);
+    }
+}

+ 59 - 0
src/main/java/com/shkpr/service/aimodelpower/configuration/OrcaleDataSourceConfig.java

@@ -0,0 +1,59 @@
+package com.shkpr.service.aimodelpower.configuration;
+
+import com.zaxxer.hikari.HikariConfig;
+import com.zaxxer.hikari.HikariDataSource;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Qualifier;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.jdbc.core.JdbcTemplate;
+
+import javax.sql.DataSource;
+
+/**
+ * @ClassName OrcaleDataSourceConfig
+ * @Description: TODO
+ * @Author LX
+ * @Date 2024/5/21
+ * @Version V1.0
+ **/
+@Configuration
+public class OrcaleDataSourceConfig {
+    @Bean(name = "primaryDataSource")
+    public DataSource primaryDataSource(@Value("${spring.datasource.primary.url}") String url,
+                                        @Value("${spring.datasource.primary.username}") String username,
+                                        @Value("${spring.datasource.primary.password}") String password,
+                                        @Value("${spring.datasource.primary.driver-class-name}") String driverClassName) {
+        HikariConfig config = new HikariConfig();
+        config.setJdbcUrl(url);
+        config.setUsername(username);
+        config.setPassword(password);
+        config.setDriverClassName(driverClassName);
+        return new HikariDataSource(config);
+    }
+
+//    @Bean(name = "secondaryDataSource")
+//    public DataSource secondaryDataSource(@Value("${spring.datasource.secondary.url}") String url,
+//                                          @Value("${spring.datasource.secondary.username}") String username,
+//                                          @Value("${spring.datasource.secondary.password}") String password,
+//                                          @Value("${spring.datasource.secondary.driver-class-name}") String driverClassName) {
+//        HikariConfig config = new HikariConfig();
+//        config.setJdbcUrl(url);
+//        config.setUsername(username);
+//        config.setPassword(password);
+//        config.setDriverClassName(driverClassName);
+//        return new HikariDataSource(config);
+//    }
+
+    @Bean(name = "oneTemplate")
+    public JdbcTemplate primaryJdbcTemplate(@Qualifier("primaryDataSource") DataSource dataSource) {
+        return new JdbcTemplate(dataSource);
+    }
+
+//    @Bean(name = "twoTemplate")
+//    public JdbcTemplate secondaryJdbcTemplate(@Qualifier("secondaryDataSource") DataSource dataSource) {
+//        return new JdbcTemplate(dataSource);
+//    }
+
+}

+ 2 - 0
src/main/java/com/shkpr/service/aimodelpower/constants/LogFlagBusiType.java

@@ -147,6 +147,8 @@ public enum  LogFlagBusiType {
     BUSI_DB_WARN_REPORT_PUSH_REQ_LINK(174,"DB Warn Report Push Req Link"),
     BUSI_DB_WARN_TYPE_DICT_MGR(175,"DB Warn Type Dict Mgr"),
 
+    BUSI_CHILD_DB_TAP_WATER(176,"DB TAP WATER Mgr"),
+
     BUSI_ALL(999,"ALL Busi"),
     BUSI_REDIS(1000,"Redis Busi");
 

+ 71 - 0
src/main/java/com/shkpr/service/aimodelpower/controllerapi/CustomXXXController.java

@@ -0,0 +1,71 @@
+package com.shkpr.service.aimodelpower.controllerapi;
+
+import com.global.base.log.LogLevelFlag;
+import com.global.base.log.LogPrintMgr;
+import com.global.base.tools.FastJsonUtil;
+import com.shkpr.service.aimodelpower.commtools.CommTool;
+import com.shkpr.service.aimodelpower.commtools.HttpTool;
+import com.shkpr.service.aimodelpower.constants.ApiURI;
+import com.shkpr.service.aimodelpower.constants.LogFlagBusiType;
+import com.shkpr.service.aimodelpower.controllerfilter.TokenAuthenticationService;
+import com.shkpr.service.aimodelpower.dbdao.otherDataSource.WaterZILAISHUIDao;
+import com.shkpr.service.aimodelpower.dto.MsgNotifyBean;
+import com.shkpr.service.aimodelpower.dto.ResponseCode;
+import com.shkpr.service.aimodelpower.dto.ResponseRes;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestHeader;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+import javax.servlet.http.HttpServletRequest;
+import java.util.concurrent.atomic.AtomicInteger;
+
+@RequestMapping(ApiURI.URI_CUSTOMIZE_H)
+@RestController
+public class CustomXXXController {
+    final String MSG_SUCCESS = "success.";
+    final String MSG_FAILED = "failed.";
+    private String mStrClassName;
+    private AtomicInteger mSeqNotify = null;
+
+    public CustomXXXController() {
+        mStrClassName = "CustomXXXController";
+        mSeqNotify = new AtomicInteger(0);
+    }
+
+    @Autowired
+    private WaterZILAISHUIDao waterZILAISHUIDao;
+
+    @PostMapping(value = ApiURI.URI_XXX_NOTIFY)
+    public ResponseRes notifyMsg(HttpServletRequest request
+            , @RequestHeader(value= ApiURI.HEADER_CLIENT_TYPE, required=false) String strClientType
+            , @RequestHeader(value= ApiURI.HEADER_USER_AGENT, required=false) String strUserAgent) throws Exception{
+        final String URI_PATH = request.getRequestURI();
+        final String strPlatform = CommTool.getPlatformByAgent(strClientType, strUserAgent);
+        final String strUserId = (String)request.getAttribute(TokenAuthenticationService.HEADER_USERID);
+        MsgNotifyBean oJsonParam = FastJsonUtil.fromJSONByGson(HttpTool.getJsonBodyStr(request), MsgNotifyBean.class);
+
+        long llReqBefore = System.currentTimeMillis();
+        String strRunSeq = String.format("%d-%d", llReqBefore, mSeqNotify.incrementAndGet());
+
+        ResponseRes<String> resResult = new ResponseRes<String>();
+        resResult.setRescode(ResponseCode.RESULT_NORMAL.toStrCode());
+        resResult.setResmsg(MSG_SUCCESS);
+        resResult.setResdata("");
+
+//        resResult.setResdata(waterZILAISHUIDao.getCount("WHERE TAG_CODE = 'SPB.SSWD.total_flow1' and QCQUISITION_TIME >= to_date('2023-01-01 00:00:00', 'yyyy-mm-dd hh24:mi:ss')").toString());
+        resResult.setResdata(FastJsonUtil.toJSON(waterZILAISHUIDao.getWaterCollectionConfigList(null)));
+
+        resResult.setTimestamp(System.currentTimeMillis());
+        LogPrintMgr.getInstance().printLogMsg(LogLevelFlag.LOG_INFO, LogFlagBusiType.BUSI_INTERNAL.toStrValue(), mStrClassName, strUserId
+                ,String.format("%s:%s seq:{%s} rescode:{%s} resmsg:{%s} time:{%d ms} end<===="
+                        ,strPlatform
+                        ,URI_PATH
+                        ,strRunSeq
+                        ,resResult.getRescode()
+                        ,resResult.getResmsg()
+                        ,resResult.getTimestamp()-llReqBefore));
+        return resResult;
+    }
+}

+ 1 - 0
src/main/java/com/shkpr/service/aimodelpower/controllerfilter/third/ThirdJWTCustomXXXFilter.java

@@ -21,6 +21,7 @@ public class ThirdJWTCustomXXXFilter extends JWTAuthenticationFilter {
     static {
         msMapURI2Method = new HashMap<String, String>();
         msMapURI2Method.put(String.format("%s/%s", ApiURI.URI_CUSTOMIZE_COMPLEX_OPTIONS_H, ApiURI.URI_XXX_LISTS), "GET");
+        msMapURI2Method.put(String.format("%s/%s", ApiURI.URI_CUSTOMIZE_H, ApiURI.URI_XXX_NOTIFY), "POST");
     }
 
     public ThirdJWTCustomXXXFilter(AuthenticationManager authenticationManager) {

+ 9 - 0
src/main/java/com/shkpr/service/aimodelpower/dbdao/DBMgrProxy.java

@@ -1,6 +1,7 @@
 package com.shkpr.service.aimodelpower.dbdao;
 
 import com.shkpr.service.aimodelpower.SpringContextUtil;
+import com.shkpr.service.aimodelpower.dbdao.otherDataSource.service.intef.WaterTapWaterService;
 import com.shkpr.service.aimodelpower.dbdao.services.intef.*;
 
 public class DBMgrProxy {
@@ -11,6 +12,10 @@ public class DBMgrProxy {
     private volatile FileAttachmentDBService fileAttachmentDBService = null;
     private volatile TypeDefineDBService typeDefineDBService = null;
     private volatile TestGeomInfoDBService testGeomInfoDBService = null;
+
+    //TODO 其他数据源
+    private volatile WaterTapWaterService waterTapWaterService = null;
+
     private static volatile DBMgrProxy msInstance = null;
     public static DBMgrProxy getInstance(){
         if (msInstance == null){
@@ -38,6 +43,8 @@ public class DBMgrProxy {
             fileAttachmentDBService = (FileAttachmentDBService)SpringContextUtil.getBean(FileAttachmentDBService.class);
         if (typeDefineDBService == null)
             typeDefineDBService = (TypeDefineDBService)SpringContextUtil.getBean(TypeDefineDBService.class);
+        if (waterTapWaterService == null)
+            waterTapWaterService = (WaterTapWaterService)SpringContextUtil.getBean(WaterTapWaterService.class);
     }
 
     public RolePowerDBService applyRolePowerApi() {return rolePowerDBService;}
@@ -53,4 +60,6 @@ public class DBMgrProxy {
     public TypeDefineDBService applyTypeDefineApi() { return typeDefineDBService; }
 
     public TestGeomInfoDBService applyTestGeomApi() {return  testGeomInfoDBService;}
+
+    public WaterTapWaterService applyWaterTapWaterService() {return  waterTapWaterService;}
 }

+ 32 - 0
src/main/java/com/shkpr/service/aimodelpower/dbdao/otherDataSource/TestDao.java

@@ -0,0 +1,32 @@
+package com.shkpr.service.aimodelpower.dbdao.otherDataSource;
+
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.jdbc.core.JdbcTemplate;
+import org.springframework.stereotype.Repository;
+
+import javax.annotation.Resource;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * @ClassName TestDao
+ * @Description: TODO
+ * @Author LX
+ * @Date 2024/5/21
+ * @Version V1.0
+ **/
+@Slf4j
+@Repository
+public class TestDao {
+    @Resource
+    private JdbcTemplate oneTemplate;
+
+    public List<Map<String,Object>> getTest(){
+        String sql = "select " +
+                " a.* from ( select t.*,rownum AS rownumber from cqda.V_SHIZILAISHUI_HISTORY2  t where rownum <= 2000) a " +
+                " where rownumber >0";
+        List<Map<String, Object>> tableData = oneTemplate.queryForList(sql);
+        log.info("这是在database1中获取的数据:{}",tableData);
+        return tableData;
+    }
+}

+ 149 - 0
src/main/java/com/shkpr/service/aimodelpower/dbdao/otherDataSource/WaterZILAISHUIDao.java

@@ -0,0 +1,149 @@
+package com.shkpr.service.aimodelpower.dbdao.otherDataSource;
+
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Qualifier;
+import org.springframework.jdbc.core.JdbcTemplate;
+import org.springframework.stereotype.Repository;
+import org.springframework.util.StringUtils;
+
+import javax.annotation.Resource;
+import javax.sql.DataSource;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * @ClassName TestDao
+ * @Description: TODO
+ * @Author LX
+ * @Date 2024/5/21
+ * @Version V1.0
+ **/
+@Slf4j
+@Repository
+public class WaterZILAISHUIDao {
+    @Resource
+    private JdbcTemplate oneTemplate;
+
+    @Autowired
+    @Qualifier("childDatasource")
+    private DataSource childDataSource;
+
+    //TODO orcale相关
+    //TODO 获取满足条件的历史水量数据总数
+    public Integer getTabWaterHistoryCount(String extend){
+        try {
+            String sql = "select count(1)  from cqda.V_SHIZILAISHUI_HISTORY2 ";
+            if(!StringUtils.isEmpty(extend)){
+                sql += extend;
+            }
+            int count = oneTemplate.queryForObject(sql, Integer.class);
+            return count;
+        }catch(Exception ex){
+            return null;
+        }
+    }
+    //TODO 分页获取历史水量数据
+    public List<Map<String,Object>> getPageZILAISHUI_HISTORY2(int limit,int offset,String extend){
+        try {
+            String sql = "select " +
+                    " a.TAG_CODE,a.NAME,a.VAL,TO_CHAR(a.QCQUISITION_TIME,'yyyy-mm-dd hh24:mi:ss') AS QCQUISITION_TIME," +
+                    " TO_CHAR(a.UPDATE_TIME,'yyyy-mm-dd hh24:mi:ss') AS UPDATE_TIME " +
+                    " from ( select t.*,rownum AS rownumber from cqda.V_SHIZILAISHUI_HISTORY2  t where rownum <= "+limit+") a " +
+                    " where rownumber > "+offset;
+            if (!StringUtils.isEmpty(extend)) {
+                sql = "select " +
+                        " a.TAG_CODE,a.NAME,a.VAL,TO_CHAR(a.QCQUISITION_TIME,'yyyy-mm-dd hh24:mi:ss') AS QCQUISITION_TIME," +
+                        " TO_CHAR(a.UPDATE_TIME,'yyyy-mm-dd hh24:mi:ss') AS UPDATE_TIME " +
+                        " from ( select t.*,rownum AS rownumber from cqda.V_SHIZILAISHUI_HISTORY2  t where rownum <= "+limit+" "+extend+") a " +
+                        " where rownumber >"+offset;
+            }
+            List<Map<String, Object>> tableData = oneTemplate.queryForList(sql);
+            return tableData;
+        }catch(Exception ex){
+            return null;
+        }
+    }
+
+    //TODO pgsql water_volume_prediction数据库相关
+    //TODO 查询设备关系表信息·不分页
+    public List<Map<String,Object>> getWaterCollectionConfigList(String extend){
+        try{
+            String sql = "SELECT * FROM water_collection_config ";
+            if(!StringUtils.isEmpty(extend)){
+                sql+=extend;
+            }
+            JdbcTemplate pgJdbc = new JdbcTemplate(childDataSource);
+            List<Map<String, Object>> tableData = pgJdbc.queryForList(sql);
+            return tableData;
+        }catch(Exception ex){
+            return null;
+        }
+    }
+
+    //TODO 查询市自来水历史记录表·分页
+    public List<Map<String,Object>> getWaterCollectionRecordList(int limit,int offset,String extend){
+        try{
+            String sql = "SELECT * FROM water_collecation_record ";
+            if(!StringUtils.isEmpty(extend)){
+                sql += extend;
+            }
+            sql += " LIMIT " + limit + " OFFSET "+ offset;
+            JdbcTemplate pgJdbc = new JdbcTemplate(childDataSource);
+            List<Map<String,Object>> tableData = pgJdbc.queryForList(sql);
+            return tableData;
+        }catch(Exception ex){
+            return null;
+        }
+    }
+
+    //TODO 查询市自来水小时用水量记录表·分页
+    public List<Map<String,Object>> getWaterCollectionRecordAllList(int limit,int offset,String extend){
+        try{
+            String sql = "SELECT * FROM water_collecation_record_all ";
+            if(!StringUtils.isEmpty(extend)){
+                sql += extend;
+            }
+            sql += " LIMIT " + limit + " OFFSET "+ offset;
+            JdbcTemplate pgJdbc = new JdbcTemplate(childDataSource);
+            List<Map<String,Object>> tableData = pgJdbc.queryForList(sql);
+            return tableData;
+        }catch(Exception ex){
+            return null;
+        }
+    }
+
+    //TODO 插入自来水历史记录表
+    public int insertWaterCollectionRecord(String extend){
+        try{
+            String sql = "INSERT INTO water_collecation_record " +
+                    "(collcation_tag,org_name,time,value,update_time) VALUES ";
+            if(StringUtils.isEmpty(extend)){
+                return -1;
+            }
+            sql+=extend;
+            JdbcTemplate pgJdbc = new JdbcTemplate(childDataSource);
+            Integer resCode = pgJdbc.update(sql);
+            return resCode;
+        }catch(Exception ex){
+            return -1;
+        }
+    }
+
+    //TODO 插入自来水小时用水量记录表
+    public int insertWaterCollectionRecordAll(String extend){
+        try{
+            String sql = "INSERT INTO water_collecation_record_all " +
+                    "(org_name,time,value,value_tag,collcation_tag_array) VALUES ";
+            if(StringUtils.isEmpty(extend)){
+                return -1;
+            }
+            sql+=extend;
+            JdbcTemplate pgJdbc = new JdbcTemplate(childDataSource);
+            Integer resCode = pgJdbc.update(sql);
+            return resCode;
+        }catch(Exception ex){
+            return -1;
+        }
+    }
+}

+ 174 - 0
src/main/java/com/shkpr/service/aimodelpower/dbdao/otherDataSource/service/WaterTapWaterServiceImpl.java

@@ -0,0 +1,174 @@
+package com.shkpr.service.aimodelpower.dbdao.otherDataSource.service;
+
+
+import com.global.base.log.LogLevelFlag;
+import com.global.base.log.LogPrintMgr;
+import com.shkpr.service.aimodelpower.commtools.CommTool;
+import com.shkpr.service.aimodelpower.constants.LogFlagBusiType;
+import com.shkpr.service.aimodelpower.dbdao.mapper.UserMapper;
+import com.shkpr.service.aimodelpower.dbdao.otherDataSource.WaterZILAISHUIDao;
+import com.shkpr.service.aimodelpower.dbdao.otherDataSource.service.intef.WaterTapWaterService;
+import com.shkpr.service.aimodelpower.dbdao.services.intef.UserDBService;
+import com.shkpr.service.aimodelpower.dbdao.tables.UserTable;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+@Service
+public class WaterTapWaterServiceImpl implements WaterTapWaterService {
+    private String mStrClassName = "";
+    public WaterTapWaterServiceImpl() {
+        mStrClassName = this.getClass().getSimpleName();
+    }
+
+    @SuppressWarnings("all")
+    @Autowired
+    private WaterZILAISHUIDao waterZILAISHUIDao;
+
+    @Override
+    public Integer getTabWaterHistoryCount(String extend) {
+        int nCode = 0;
+        String strMsg = "Success";
+        Integer arrRes = null;
+        try {
+            arrRes = waterZILAISHUIDao.getTabWaterHistoryCount(extend);
+        }catch (Exception e){
+            nCode = LogLevelFlag.LOG_ERROR.ordinal();
+            strMsg = e.getLocalizedMessage();
+        }finally {
+//            LogPrintMgr.getInstance().printLogMsg(LogLevelFlag.valueFromInt(nCode)
+//                    , LogFlagBusiType.BUSI_CHILD_DB_TAP_WATER.toStrValue()
+//                    , mStrClassName
+//                    , String.format("Batch Query TabWaterCount:{%s},{%s} from database, code:{%s} msg:{%s} ..."
+//                            , arrRes
+//                            ,extend
+//                            , nCode, strMsg));
+        }
+        return arrRes;
+    }
+
+    @Override
+    public List<Map<String, Object>> getPageZILAISHUI_HISTORY2(int limit, int offset, String extend) {
+        int nCode = 0;
+        String strMsg = "Success";
+        List<Map<String, Object>> arrRes = null;
+        try {
+            arrRes = waterZILAISHUIDao.getPageZILAISHUI_HISTORY2(limit,offset,extend);
+        }catch (Exception e){
+            nCode = LogLevelFlag.LOG_ERROR.ordinal();
+            strMsg = e.getLocalizedMessage();
+        }finally {
+//            LogPrintMgr.getInstance().printLogMsg(LogLevelFlag.valueFromInt(nCode)
+//                    , LogFlagBusiType.BUSI_CHILD_DB_TAP_WATER.toStrValue()
+//                    , mStrClassName
+//                    , String.format("Batch Query TabWaterHistory from database, code:{%d} msg:{%s} ..."
+//                            , nCode, strMsg));
+        }
+        return arrRes;
+    }
+
+    @Override
+    public List<Map<String,Object>> getWaterCollectionConfigList(String extend) {
+        int nCode = 0;
+        String strMsg = "Success";
+        List<Map<String, Object>> arrRes = null;
+        try {
+            arrRes = waterZILAISHUIDao.getWaterCollectionConfigList(extend);
+        }catch (Exception e){
+            nCode = LogLevelFlag.LOG_ERROR.ordinal();
+            strMsg = e.getLocalizedMessage();
+        }finally {
+//            LogPrintMgr.getInstance().printLogMsg(LogLevelFlag.valueFromInt(nCode)
+//                    , LogFlagBusiType.BUSI_CHILD_DB_TAP_WATER.toStrValue()
+//                    , mStrClassName
+//                    , String.format("Batch Query TabWaterHistory from database, code:{%d} msg:{%s} ..."
+//                            , nCode, strMsg));
+        }
+        return arrRes;
+    }
+
+    @Override
+    public List<Map<String, Object>> getWaterCollectionRecordList(int limit, int offset, String extend) {
+        int nCode = 0;
+        String strMsg = "Success";
+        List<Map<String, Object>> arrRes = null;
+        try {
+            arrRes = waterZILAISHUIDao.getWaterCollectionRecordList(limit,offset,extend);
+        }catch (Exception e){
+            nCode = LogLevelFlag.LOG_ERROR.ordinal();
+            strMsg = e.getLocalizedMessage();
+        }finally {
+//            LogPrintMgr.getInstance().printLogMsg(LogLevelFlag.valueFromInt(nCode)
+//                    , LogFlagBusiType.BUSI_CHILD_DB_TAP_WATER.toStrValue()
+//                    , mStrClassName
+//                    , String.format("Batch Query TabWaterHistory from database, code:{%d} msg:{%s} ..."
+//                            , nCode, strMsg));
+        }
+        return arrRes;
+    }
+
+    @Override
+    public List<Map<String, Object>> getWaterCollectionRecordAllList(int limit, int offset, String extend) {
+        int nCode = 0;
+        String strMsg = "Success";
+        List<Map<String, Object>> arrRes = null;
+        try {
+            arrRes = waterZILAISHUIDao.getWaterCollectionRecordAllList(limit,offset,extend);
+        }catch (Exception e){
+            nCode = LogLevelFlag.LOG_ERROR.ordinal();
+            strMsg = e.getLocalizedMessage();
+        }finally {
+//            LogPrintMgr.getInstance().printLogMsg(LogLevelFlag.valueFromInt(nCode)
+//                    , LogFlagBusiType.BUSI_CHILD_DB_TAP_WATER.toStrValue()
+//                    , mStrClassName
+//                    , String.format("Batch Query TabWaterHistory from database, code:{%d} msg:{%s} ..."
+//                            , nCode, strMsg));
+        }
+        return arrRes;
+    }
+
+    @Override
+    public Integer insertWaterCollectionRecord(String extend) {
+        int nCode = 0;
+        String strMsg = "Success";
+        Integer arrRes = null;
+        try {
+            arrRes = waterZILAISHUIDao.insertWaterCollectionRecord(extend);
+        }catch (Exception e){
+            nCode = LogLevelFlag.LOG_ERROR.ordinal();
+            strMsg = e.getLocalizedMessage();
+        }finally {
+//            LogPrintMgr.getInstance().printLogMsg(LogLevelFlag.valueFromInt(nCode)
+//                    , LogFlagBusiType.BUSI_CHILD_DB_TAP_WATER.toStrValue()
+//                    , mStrClassName
+//                    , String.format("Batch Insert WaterRecord:{%s} from database, code:{%s} msg:{%s} ..."
+//                            , arrRes
+//                            , nCode, strMsg));
+        }
+        return arrRes;
+    }
+
+    @Override
+    public Integer insertWaterCollectionRecordAll(String extend) {
+        int nCode = 0;
+        String strMsg = "Success";
+        Integer arrRes = null;
+        try {
+            arrRes = waterZILAISHUIDao.insertWaterCollectionRecordAll(extend);
+        }catch (Exception e){
+            nCode = LogLevelFlag.LOG_ERROR.ordinal();
+            strMsg = e.getLocalizedMessage();
+        }finally {
+//            LogPrintMgr.getInstance().printLogMsg(LogLevelFlag.valueFromInt(nCode)
+//                    , LogFlagBusiType.BUSI_CHILD_DB_TAP_WATER.toStrValue()
+//                    , mStrClassName
+//                    , String.format("Batch Insert WaterRecord:{%s} from database, code:{%s} msg:{%s} ..."
+//                            , arrRes
+//                            , nCode, strMsg));
+        }
+        return arrRes;
+    }
+}

+ 27 - 0
src/main/java/com/shkpr/service/aimodelpower/dbdao/otherDataSource/service/intef/WaterTapWaterService.java

@@ -0,0 +1,27 @@
+package com.shkpr.service.aimodelpower.dbdao.otherDataSource.service.intef;
+
+import java.util.List;
+import java.util.Map;
+
+public interface WaterTapWaterService {
+
+    //TODO orcale 获取市自来水历史用水记录总数
+    public Integer getTabWaterHistoryCount(String extend);
+
+    //TODO orcale 获取市自来水历史用水记录·分页
+    public List<Map<String,Object>> getPageZILAISHUI_HISTORY2(int limit, int offset, String extend);
+
+    //TODO pgsql 获取市自来水历史用水记录
+    public List<Map<String,Object>> getWaterCollectionConfigList(String extend);
+
+    //TODO pgsql 查询市自来水历史记录表·分页
+    public List<Map<String,Object>> getWaterCollectionRecordList(int limit,int offset,String extend);
+
+    //TODO pgsql 查询市自来水小时用水量记录表·分页
+    public List<Map<String,Object>> getWaterCollectionRecordAllList(int limit,int offset,String extend);
+
+    //TODO pgsql 插入自来水历史记录表
+    public Integer insertWaterCollectionRecord(String extend);
+    //TODO pgsql 插入自来水小时用水量记录表
+    public Integer insertWaterCollectionRecordAll(String extend);
+}

+ 42 - 0
src/main/java/com/shkpr/service/aimodelpower/globalmgr/ScheduleTaskMgr.java

@@ -3,6 +3,7 @@ package com.shkpr.service.aimodelpower.globalmgr;
 import com.global.base.log.LogLevelFlag;
 import com.global.base.log.LogPrintMgr;
 import com.global.base.thread.ThreadPoolProxy;
+import com.shkpr.service.aimodelpower.bizmgr.KprAimTapWaterBizFun;
 import com.shkpr.service.aimodelpower.commtools.TimeTool;
 import com.shkpr.service.aimodelpower.constants.LogFlagBusiType;
 import com.zaxxer.hikari.HikariDataSource;
@@ -15,6 +16,8 @@ import javax.annotation.PostConstruct;
 import javax.annotation.PreDestroy;
 import javax.sql.DataSource;
 import java.sql.Connection;
+import java.util.Timer;
+import java.util.TimerTask;
 
 @Component
 @EnableScheduling   // 1.开启定时任务
@@ -88,4 +91,43 @@ public class ScheduleTaskMgr {
             }
         }
     }
+
+    //TODO 每天整点的十分执行检查小时用水量是否对齐,检查时间范围为当前时间到昨天
+    @Scheduled(cron = "0 10 * * * *")
+    public void executeTaskEveryHourAtTenMinutesRecordAll() {
+        KprAimTapWaterBizFun.checkRecordAllData();
+    }
+
+    //TODO 每天整点的十分执行检查小时用水量是否对齐,检查时间范围为当前时间到昨天
+    @Scheduled(cron = "0 15 * * * *")
+    public void executeTaskEveryHourAtTenMinutesRecord() {
+        KprAimTapWaterBizFun.checkRecordData();
+    }
+
+
+    //TODO 启动时执行一次
+    @PostConstruct
+    public void initOneTapWater(){
+        Timer timer = new Timer();
+        // 创建定时器任务
+        TimerTask timerTask = new TimerTask() {
+            @Override
+            public void run() {
+                KprAimTapWaterBizFun.initTapWaterData();
+            }
+        };
+        timer.schedule(timerTask, 10000); // 10秒后执行一次
+    }
+
+    @PostConstruct
+    public void initWaterRecordAll(){
+        Timer timer = new Timer();
+        TimerTask timerTask1 = new TimerTask() {
+            @Override
+            public void run() {
+                KprAimTapWaterBizFun.initWaterCollecationReacordAll();
+            }
+        };
+        timer.schedule(timerTask1,11000);//11秒后执行一次
+    }
 }

+ 12 - 0
src/main/resources/application.properties

@@ -67,6 +67,18 @@ global.max.tomcat.accept.queue=200
 #===================数据库配置===========================
 global.sql.config.path=./sql.properties
 
+# oracle数据源
+spring.datasource.primary.url=jdbc:oracle:thin:@10.127.16.117:1521/ORCLPDB1
+spring.datasource.primary.username=v_shizilaishui
+spring.datasource.primary.password=ShiZiLaiShui@0811
+spring.datasource.primary.driver-class-name=oracle.jdbc.driver.OracleDriver
+
+#pgsql 自来水水量预测数据库源
+spring.datasource.db2.jdbc-url=jdbc:postgresql_postGIS://119.96.165.176:5432/water_volume_prediction?useSSL=false&useAffectedRows=false&allowMultiQueries=true
+spring.datasource.db2.username=postgres
+spring.datasource.db2.password=kpr.23417.postgres
+spring.datasource.db2.driver-class-name=org.postgis.DriverWrapper
+
 #开启mybatis内部调试日志输出
 #logging.level.com.sqlmybatis.test.mapper=debug