|
@@ -7,7 +7,9 @@ import com.global.base.log.LogPrintMgr;
|
|
import com.global.base.tools.FastJsonUtil;
|
|
import com.global.base.tools.FastJsonUtil;
|
|
import com.shkpr.service.aimodelpower.commtools.ProbabilityAlgorithm;
|
|
import com.shkpr.service.aimodelpower.commtools.ProbabilityAlgorithm;
|
|
import com.shkpr.service.aimodelpower.commtools.TimeTool;
|
|
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.DBMgrProxy;
|
|
|
|
+import com.shkpr.service.aimodelpower.dbdao.shizilaishuiDataSource.WaterZILAISHUIDao;
|
|
import com.shkpr.service.aimodelpower.dbdao.shizilaishuiDataSource.service.intef.WaterCollecationService;
|
|
import com.shkpr.service.aimodelpower.dbdao.shizilaishuiDataSource.service.intef.WaterCollecationService;
|
|
import com.shkpr.service.aimodelpower.dbdao.shizilaishuiDataSource.service.intef.WaterTapWaterService;
|
|
import com.shkpr.service.aimodelpower.dbdao.shizilaishuiDataSource.service.intef.WaterTapWaterService;
|
|
import com.shkpr.service.aimodelpower.dto.ResponseCode;
|
|
import com.shkpr.service.aimodelpower.dto.ResponseCode;
|
|
@@ -18,7 +20,9 @@ import com.shkpr.service.aimodelpower.globalmgr.ThreadTaskMgr;
|
|
import com.shkpr.service.aimodelpower.globalmgr.TraceLogMgr;
|
|
import com.shkpr.service.aimodelpower.globalmgr.TraceLogMgr;
|
|
import com.shkpr.service.aimodelpower.jsonbean.zilaishui.*;
|
|
import com.shkpr.service.aimodelpower.jsonbean.zilaishui.*;
|
|
import com.shkpr.service.aimodelpower.services.ServiceMgrProxy;
|
|
import com.shkpr.service.aimodelpower.services.ServiceMgrProxy;
|
|
|
|
+import org.apache.commons.collections.MapUtils;
|
|
import org.springframework.util.CollectionUtils;
|
|
import org.springframework.util.CollectionUtils;
|
|
|
|
+import org.springframework.util.ObjectUtils;
|
|
import org.springframework.util.StringUtils;
|
|
import org.springframework.util.StringUtils;
|
|
|
|
|
|
import java.io.*;
|
|
import java.io.*;
|
|
@@ -29,6 +33,8 @@ import java.time.format.DateTimeFormatter;
|
|
import java.time.temporal.TemporalAdjusters;
|
|
import java.time.temporal.TemporalAdjusters;
|
|
import java.util.*;
|
|
import java.util.*;
|
|
import java.util.concurrent.CountDownLatch;
|
|
import java.util.concurrent.CountDownLatch;
|
|
|
|
+import java.util.concurrent.ExecutorService;
|
|
|
|
+import java.util.concurrent.Executors;
|
|
import java.util.concurrent.ThreadLocalRandom;
|
|
import java.util.concurrent.ThreadLocalRandom;
|
|
import java.util.stream.Collectors;
|
|
import java.util.stream.Collectors;
|
|
|
|
|
|
@@ -333,16 +339,34 @@ public class KprAimWaterCollecationBizFun {
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+ /**
|
|
|
|
+ * 通过 orgId 查找对应的 orgName
|
|
|
|
+ *
|
|
|
|
+ * @param workZoneIds Map 集合
|
|
|
|
+ * @param orgId 指定的 orgId
|
|
|
|
+ * @return Optional<String> 对应的 orgName
|
|
|
|
+ */
|
|
|
|
+ public static Optional<String> findOrgNameByOrgId(Map<String, String> workZoneIds, String orgId) {
|
|
|
|
+ return workZoneIds.entrySet()
|
|
|
|
+ .stream()
|
|
|
|
+ .filter(entry -> orgId.equals(entry.getValue())) // 过滤出值等于 orgId 的条目
|
|
|
|
+ .map(Map.Entry::getKey) // 提取键(orgName)
|
|
|
|
+ .findFirst(); // 返回第一个匹配的 orgName
|
|
|
|
+ }
|
|
|
|
+ private static double parseDouble(Object value) {
|
|
|
|
+ return value == null ? 0.0 : Double.parseDouble(value.toString());
|
|
|
|
+ }
|
|
//TODO 查询日取水量预测接口
|
|
//TODO 查询日取水量预测接口
|
|
|
|
|
|
/**
|
|
/**
|
|
* 1.传入水厂Id及起止日期(日期格式为YYYY-MM-DD),返回日期内,每天的预测取水量数据和实际取水量数据
|
|
* 1.传入水厂Id及起止日期(日期格式为YYYY-MM-DD),返回日期内,每天的预测取水量数据和实际取水量数据
|
|
* 2.同时返回指定截止日期之后,未来4天的预测水量数据和实际水量(如没有,则返回为空数据)
|
|
* 2.同时返回指定截止日期之后,未来4天的预测水量数据和实际水量(如没有,则返回为空数据)
|
|
*/
|
|
*/
|
|
- public static ResponseRes selectTbWaterList(JPTbMWater jpTbMWater){
|
|
|
|
|
|
+ public static ResponseRes selectTbWaterList(JPTbMWater jpTbMWater,Integer level,Map<String, Map<String, List<String>>> result
|
|
|
|
+ ,Map<String,String> workZonIds){
|
|
ResponseRes responseRes = new ResponseRes();
|
|
ResponseRes responseRes = new ResponseRes();
|
|
List<Map<String,Object>> list =new ArrayList<>();
|
|
List<Map<String,Object>> list =new ArrayList<>();
|
|
- if("water_volume_prediction_jiangjin".equals(databaseName)){
|
|
|
|
|
|
+ if("water_volume_prediction_jiangjin2".equals(databaseName)){
|
|
Map<String, Object> map = new HashMap<>();
|
|
Map<String, Object> map = new HashMap<>();
|
|
map.put("id", null);
|
|
map.put("id", null);
|
|
map.put("date", null);
|
|
map.put("date", null);
|
|
@@ -387,13 +411,113 @@ public class KprAimWaterCollecationBizFun {
|
|
responseRes.setRescode(ResponseCode.RESULT_NORMAL.toStrCode());
|
|
responseRes.setRescode(ResponseCode.RESULT_NORMAL.toStrCode());
|
|
responseRes.setResmsg(ResponseCode.RESULT_NORMAL.toStrMsg());
|
|
responseRes.setResmsg(ResponseCode.RESULT_NORMAL.toStrMsg());
|
|
try {
|
|
try {
|
|
- //
|
|
|
|
- List<Map<String, Object>> resList = getWaterTapWaterApi().getTbMWater(jpTbMWater.getIsPage(),
|
|
|
|
- jpTbMWater.getLimit(), jpTbMWater.getOffset(), jpTbMWater.getForDateStr());
|
|
|
|
- if(!CollectionUtils.isEmpty(resList)){
|
|
|
|
- responseRes.setRescode(ResponseCode.RESULT_NORMAL.toStrCode());
|
|
|
|
- responseRes.setResmsg(ResponseCode.RESULT_NORMAL.toStrMsg());
|
|
|
|
- responseRes.setResdata(resList);
|
|
|
|
|
|
+ if ("water_volume_prediction".equals(databaseName)){
|
|
|
|
+ //TODO 自来水分了二级泵房,要做查询数据处理,点击水厂查询条件时,查询其下的泵房数据 再相加,
|
|
|
|
+ //TODO 点击泵房则就查泵房的数据 ,无需做处理
|
|
|
|
+ List<String> childList = new ArrayList<>();//要查询的组织机构名称集合
|
|
|
|
+ List<String> childIdList = new ArrayList<>();//要查询的组织机构id集合
|
|
|
|
+ if (level==1){
|
|
|
|
+ //TODO 一级已经没有数据了(水厂), 查询一级的话则是将其下的供水数据相加
|
|
|
|
+ //TODO 查询二级,及其二级带的三级
|
|
|
|
+ Optional zoneNameOpt = findOrgNameByOrgId(workZonIds,jpTbMWater.getOrgId());
|
|
|
|
+ if(zoneNameOpt.isPresent()){
|
|
|
|
+ String zoneName = zoneNameOpt.get().toString();
|
|
|
|
+ Map<String, List<String>> childMap = result.get(zoneName);//二级
|
|
|
|
+ Collection<List<String>> child2Map = childMap.values();//三级
|
|
|
|
+ // 添加二级组织机构名称(childMap 的 keySet)
|
|
|
|
+ childList.addAll(childMap.keySet());
|
|
|
|
+ // 添加三级组织机构名称(child2Map 的所有 List<String>)
|
|
|
|
+ for (List<String> child2List : child2Map) {
|
|
|
|
+ childList.addAll(child2List);
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }else if(level==2){
|
|
|
|
+ //TODO 如果是二级,就查询其自身,看看其下还有没有集合,有的话就查其下的所有集合,没有的话就查其自身
|
|
|
|
+ Optional zoneNameOpt = findOrgNameByOrgId(workZonIds,jpTbMWater.getOrgId());
|
|
|
|
+ if(zoneNameOpt.isPresent()) {
|
|
|
|
+ String zoneName = zoneNameOpt.get().toString();
|
|
|
|
+ List<String> childMap = new ArrayList<>();//三级
|
|
|
|
+ // 遍历第一级 Map
|
|
|
|
+ for (Map.Entry<String, Map<String, List<String>>> entry : result.entrySet()) {
|
|
|
|
+ Map<String, List<String>> nestedMap = entry.getValue();
|
|
|
|
+ // 检查第二级键
|
|
|
|
+ if (nestedMap.containsKey(zoneName)) {
|
|
|
|
+ childMap = nestedMap.get(zoneName);
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ if(childMap.size()>0) {
|
|
|
|
+ // 添三级组织机构名称(childMap 的 keySet)
|
|
|
|
+ childList.addAll(childMap);
|
|
|
|
+ }else{
|
|
|
|
+ childList.add(zoneName);
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }else if(level==3){
|
|
|
|
+ LogPrintMgr.getInstance().printLogMsg(LogLevelFlag.LOG_INFO, LogFlagBusiType.BUSI_INTERNAL.toStrValue(), mStrClassName, ""
|
|
|
|
+ , "5555");
|
|
|
|
+ //TODO 如果是三级,就查询其自身
|
|
|
|
+ Optional zoneNameOpt = findOrgNameByOrgId(workZonIds,jpTbMWater.getOrgId());
|
|
|
|
+ if(zoneNameOpt.isPresent()) {
|
|
|
|
+ String zoneName = zoneNameOpt.get().toString();
|
|
|
|
+ childList.add(zoneName);
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ //TODO 开始查询
|
|
|
|
+ // 结果集合,存储 childList 对应的组织机构 ID
|
|
|
|
+ // 遍历 childList,从 workZonIds 中获取对应的 ID
|
|
|
|
+ for (String orgName : childList) {
|
|
|
|
+ String orgId = workZonIds.get(orgName);
|
|
|
|
+ if (orgId != null) { // 避免空值
|
|
|
|
+ childIdList.add(orgId);
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ List<Map<String,Object>> newResList = new ArrayList<>();
|
|
|
|
+ int index = 0;
|
|
|
|
+ for (String orgId:childIdList){
|
|
|
|
+ jpTbMWater.setOrgId(orgId);
|
|
|
|
+ jpTbMWater.checkValid();
|
|
|
|
+ List<Map<String, Object>> resList = getWaterTapWaterApi().getTbMWater(jpTbMWater.getIsPage(),
|
|
|
|
+ jpTbMWater.getLimit(), jpTbMWater.getOffset(), jpTbMWater.getForDateStr() + " ORDER BY \"Date\" ASC ");
|
|
|
|
+ if(!CollectionUtils.isEmpty(newResList)&&!CollectionUtils.isEmpty(resList)){
|
|
|
|
+ //TODO 说明要查询的分区不止一个,则把原来有的数据与新查的数据相加,因为按Date排了序所以一致
|
|
|
|
+ for (int i=0;i<newResList.size();i++){
|
|
|
|
+ newResList.get(i).put("LastActualWaterWithdrawals",
|
|
|
|
+ parseDouble(newResList.get(i).get("LastActualWaterWithdrawals")) +
|
|
|
|
+ parseDouble(resList.get(i).get("LastActualWaterWithdrawals")));
|
|
|
|
+ newResList.get(i).put("LastActualWaterSupply",
|
|
|
|
+ parseDouble(newResList.get(i).get("LastActualWaterSupply")) +
|
|
|
|
+ parseDouble(resList.get(i).get("LastActualWaterSupply")));
|
|
|
|
+ newResList.get(i).put("ActualWaterWithdrawals",
|
|
|
|
+ parseDouble(newResList.get(i).get("ActualWaterWithdrawals")) +
|
|
|
|
+ parseDouble(resList.get(i).get("ActualWaterWithdrawals")));
|
|
|
|
+ newResList.get(i).put("ActualWaterSupply",
|
|
|
|
+ parseDouble(newResList.get(i).get("ActualWaterSupply")) +
|
|
|
|
+ parseDouble(resList.get(i).get("ActualWaterSupply")));
|
|
|
|
+ newResList.get(i).put("ForecastWaterWithdrawals",
|
|
|
|
+ parseDouble(newResList.get(i).get("ForecastWaterWithdrawals")) +
|
|
|
|
+ parseDouble(resList.get(i).get("ForecastWaterWithdrawals")));
|
|
|
|
+ newResList.get(i).put("ForecastActualWaterSupply",
|
|
|
|
+ parseDouble(newResList.get(i).get("ForecastActualWaterSupply")) +
|
|
|
|
+ parseDouble(resList.get(i).get("ForecastActualWaterSupply")));
|
|
|
|
+ }
|
|
|
|
+ }else {
|
|
|
|
+ newResList.addAll(resList);
|
|
|
|
+ }
|
|
|
|
+ index++;
|
|
|
|
+ }
|
|
|
|
+ if (!CollectionUtils.isEmpty(newResList)) {
|
|
|
|
+ responseRes.setRescode(ResponseCode.RESULT_NORMAL.toStrCode());
|
|
|
|
+ responseRes.setResmsg(ResponseCode.RESULT_NORMAL.toStrMsg());
|
|
|
|
+ responseRes.setResdata(newResList);
|
|
|
|
+ }
|
|
|
|
+ }else {
|
|
|
|
+ List<Map<String, Object>> resList = getWaterTapWaterApi().getTbMWater(jpTbMWater.getIsPage(),
|
|
|
|
+ jpTbMWater.getLimit(), jpTbMWater.getOffset(), jpTbMWater.getForDateStr());
|
|
|
|
+ if (!CollectionUtils.isEmpty(resList)) {
|
|
|
|
+ responseRes.setRescode(ResponseCode.RESULT_NORMAL.toStrCode());
|
|
|
|
+ responseRes.setResmsg(ResponseCode.RESULT_NORMAL.toStrMsg());
|
|
|
|
+ responseRes.setResdata(resList);
|
|
|
|
+ }
|
|
}
|
|
}
|
|
return responseRes;
|
|
return responseRes;
|
|
}catch(Exception ex){
|
|
}catch(Exception ex){
|
|
@@ -408,10 +532,13 @@ public class KprAimWaterCollecationBizFun {
|
|
/**
|
|
/**
|
|
* 传入水厂id及日期,返回指定日期内的小时取水量预测数据和实际小时取水量数据
|
|
* 传入水厂id及日期,返回指定日期内的小时取水量预测数据和实际小时取水量数据
|
|
*/
|
|
*/
|
|
- public static ResponseRes selectTbHourWaterList(JPTbMHourWater jpTbMHourWater){
|
|
|
|
|
|
+ public static ResponseRes selectTbHourWaterList(JPTbMHourWater jpTbMHourWater,Integer level,Map<String, Map<String, List<String>>> result
|
|
|
|
+ ,Map<String,String> workZonIds){
|
|
|
|
+ LogPrintMgr.getInstance().printLogMsg(LogLevelFlag.LOG_INFO, LogFlagBusiType.BUSI_INTERNAL.toStrValue(), mStrClassName, ""
|
|
|
|
+ , "2222");
|
|
ResponseRes responseRes = new ResponseRes();
|
|
ResponseRes responseRes = new ResponseRes();
|
|
List<Map<String, Object>> list = new ArrayList<>();
|
|
List<Map<String, Object>> list = new ArrayList<>();
|
|
- if("water_volume_prediction_jiangjin".equals(databaseName)){
|
|
|
|
|
|
+ if("water_volume_prediction_jiangjin2".equals(databaseName)){
|
|
Map<String, Object> map = new HashMap<>();
|
|
Map<String, Object> map = new HashMap<>();
|
|
map.put("id", null);
|
|
map.put("id", null);
|
|
map.put("date", null);
|
|
map.put("date", null);
|
|
@@ -446,13 +573,128 @@ public class KprAimWaterCollecationBizFun {
|
|
responseRes.setRescode(ResponseCode.RESULT_NORMAL.toStrCode());
|
|
responseRes.setRescode(ResponseCode.RESULT_NORMAL.toStrCode());
|
|
responseRes.setResmsg(ResponseCode.RESULT_NORMAL.toStrMsg());
|
|
responseRes.setResmsg(ResponseCode.RESULT_NORMAL.toStrMsg());
|
|
try {
|
|
try {
|
|
- //
|
|
|
|
- List<Map<String, Object>> resList = getWaterTapWaterApi().getTbMHourwater(jpTbMHourWater.getIsPage(),
|
|
|
|
- jpTbMHourWater.getLimit(), jpTbMHourWater.getOffset(), jpTbMHourWater.getForDateStr());
|
|
|
|
- if(!CollectionUtils.isEmpty(resList)){
|
|
|
|
- responseRes.setRescode(ResponseCode.RESULT_NORMAL.toStrCode());
|
|
|
|
- responseRes.setResmsg(ResponseCode.RESULT_NORMAL.toStrMsg());
|
|
|
|
- responseRes.setResdata(resList);
|
|
|
|
|
|
+ if ("water_volume_prediction".equals(databaseName)){
|
|
|
|
+ LogPrintMgr.getInstance().printLogMsg(LogLevelFlag.LOG_INFO, LogFlagBusiType.BUSI_INTERNAL.toStrValue(), mStrClassName, ""
|
|
|
|
+ , "3333");
|
|
|
|
+//TODO 自来水分了二级泵房,要做查询数据处理,点击水厂查询条件时,查询其下的泵房数据 再相加,
|
|
|
|
+ //TODO 点击泵房则就查泵房的数据 ,无需做处理
|
|
|
|
+ List<String> childList = new ArrayList<>();//要查询的组织机构名称集合
|
|
|
|
+ List<String> childIdList = new ArrayList<>();//要查询的组织机构id集合
|
|
|
|
+ if (level==1){
|
|
|
|
+ LogPrintMgr.getInstance().printLogMsg(LogLevelFlag.LOG_INFO, LogFlagBusiType.BUSI_INTERNAL.toStrValue(), mStrClassName, ""
|
|
|
|
+ , "4444");
|
|
|
|
+ //TODO 一级已经没有数据了(水厂), 查询一级的话则是将其下的供水数据相加
|
|
|
|
+ //TODO 查询二级,及其二级带的三级
|
|
|
|
+ Optional zoneNameOpt = findOrgNameByOrgId(workZonIds,jpTbMHourWater.getOrgId());
|
|
|
|
+ if(zoneNameOpt.isPresent()){
|
|
|
|
+ String zoneName = zoneNameOpt.get().toString();
|
|
|
|
+ Map<String, List<String>> childMap = result.get(zoneName);//二级
|
|
|
|
+ Collection<List<String>> child2Map = childMap.values();//三级
|
|
|
|
+ // 添加二级组织机构名称(childMap 的 keySet)
|
|
|
|
+ childList.addAll(childMap.keySet());
|
|
|
|
+ // 添加三级组织机构名称(child2Map 的所有 List<String>)
|
|
|
|
+ for (List<String> child2List : child2Map) {
|
|
|
|
+ childList.addAll(child2List);
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }else if(level==2){
|
|
|
|
+ //TODO 如果是二级,就查询其自身,看看其下还有没有集合,有的话就查其下的所有集合,没有的话就查其自身
|
|
|
|
+ Optional zoneNameOpt = findOrgNameByOrgId(workZonIds,jpTbMHourWater.getOrgId());
|
|
|
|
+ if(zoneNameOpt.isPresent()) {
|
|
|
|
+ String zoneName = zoneNameOpt.get().toString();
|
|
|
|
+ List<String> childMap = new ArrayList<>();//三级
|
|
|
|
+ // 遍历第一级 Map
|
|
|
|
+ for (Map.Entry<String, Map<String, List<String>>> entry : result.entrySet()) {
|
|
|
|
+ Map<String, List<String>> nestedMap = entry.getValue();
|
|
|
|
+ // 检查第二级键
|
|
|
|
+ if (nestedMap.containsKey(zoneName)) {
|
|
|
|
+ childMap = nestedMap.get(zoneName);
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ if(childMap.size()>0) {
|
|
|
|
+ // 添三级组织机构名称(childMap 的 keySet)
|
|
|
|
+ childList.addAll(childMap);
|
|
|
|
+ }else{
|
|
|
|
+ childList.add(zoneName);
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }else if(level==3){
|
|
|
|
+ LogPrintMgr.getInstance().printLogMsg(LogLevelFlag.LOG_INFO, LogFlagBusiType.BUSI_INTERNAL.toStrValue(), mStrClassName, ""
|
|
|
|
+ , "5555");
|
|
|
|
+ //TODO 如果是三级,就查询其自身
|
|
|
|
+ Optional zoneNameOpt = findOrgNameByOrgId(workZonIds,jpTbMHourWater.getOrgId());
|
|
|
|
+ if(zoneNameOpt.isPresent()) {
|
|
|
|
+ String zoneName = zoneNameOpt.get().toString();
|
|
|
|
+ childList.add(zoneName);
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ //TODO 开始查询
|
|
|
|
+ // 结果集合,存储 childList 对应的组织机构 ID
|
|
|
|
+ // 遍历 childList,从 workZonIds 中获取对应的 ID
|
|
|
|
+ for (String orgName : childList) {
|
|
|
|
+ String orgId = workZonIds.get(orgName);
|
|
|
|
+ if (orgId != null) { // 避免空值
|
|
|
|
+ childIdList.add(orgId);
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ List<Map<String,Object>> newResList = new ArrayList<>();
|
|
|
|
+ int index = 0;
|
|
|
|
+ for (String orgId:childIdList){
|
|
|
|
+ LogPrintMgr.getInstance().printLogMsg(LogLevelFlag.LOG_INFO, LogFlagBusiType.BUSI_INTERNAL.toStrValue(), mStrClassName, ""
|
|
|
|
+ , "6666");
|
|
|
|
+ jpTbMHourWater.setOrgId(orgId);
|
|
|
|
+ jpTbMHourWater.checkValid();
|
|
|
|
+ List<Map<String, Object>> resList = getWaterTapWaterApi().getTbMHourwater(jpTbMHourWater.getIsPage(),
|
|
|
|
+ jpTbMHourWater.getLimit(), jpTbMHourWater.getOffset(), jpTbMHourWater.getForDateStr()+ " ORDER BY \"Date\",\"Hour\" ASC ");
|
|
|
|
+ if(!CollectionUtils.isEmpty(newResList)&&!CollectionUtils.isEmpty(resList)){
|
|
|
|
+ //TODO 说明要查询的分区不止一个,则&把原来有的数据与新查的数据相加,因为按Date排了序所以一致
|
|
|
|
+ for (int i=0;i<newResList.size();i++){
|
|
|
|
+ newResList.get(i).put("HourForecastWaterWithdrawals",
|
|
|
|
+ parseDouble(newResList.get(i).get("HourForecastWaterWithdrawals")) +
|
|
|
|
+ parseDouble(resList.get(i).get("HourForecastWaterWithdrawals")));
|
|
|
|
+ newResList.get(i).put("HourForecastActualWaterSupply",
|
|
|
|
+ parseDouble(newResList.get(i).get("HourForecastActualWaterSupply")) +
|
|
|
|
+ parseDouble(resList.get(i).get("HourForecastActualWaterSupply")));
|
|
|
|
+ newResList.get(i).put("WaterWithdrawalsEnergy",
|
|
|
|
+ parseDouble(newResList.get(i).get("WaterWithdrawalsEnergy")) +
|
|
|
|
+ parseDouble(resList.get(i).get("WaterWithdrawalsEnergy")));
|
|
|
|
+ newResList.get(i).put("WaterSupplyEnergy",
|
|
|
|
+ parseDouble(newResList.get(i).get("WaterSupplyEnergy")) +
|
|
|
|
+ parseDouble(resList.get(i).get("WaterSupplyEnergy")));
|
|
|
|
+ newResList.get(i).put("RealWaterWithdrawalsEnergy",
|
|
|
|
+ parseDouble(newResList.get(i).get("RealWaterWithdrawalsEnergy")) +
|
|
|
|
+ parseDouble(resList.get(i).get("RealWaterWithdrawalsEnergy")));
|
|
|
|
+ newResList.get(i).put("RealWaterSupplyEnergy",
|
|
|
|
+ parseDouble(newResList.get(i).get("RealWaterSupplyEnergy")) +
|
|
|
|
+ parseDouble(resList.get(i).get("RealWaterSupplyEnergy")));
|
|
|
|
+ newResList.get(i).put("HourActualWaterWithdrawals",
|
|
|
|
+ parseDouble(newResList.get(i).get("HourActualWaterWithdrawals")) +
|
|
|
|
+ parseDouble(resList.get(i).get("HourActualWaterWithdrawals")));
|
|
|
|
+ newResList.get(i).put("HourActualWaterSupply",
|
|
|
|
+ parseDouble(newResList.get(i).get("HourActualWaterSupply")) +
|
|
|
|
+ parseDouble(resList.get(i).get("HourActualWaterSupply")));
|
|
|
|
+ }
|
|
|
|
+ }else {
|
|
|
|
+ newResList.addAll(resList);
|
|
|
|
+ }
|
|
|
|
+ index++;
|
|
|
|
+ }
|
|
|
|
+ if (!CollectionUtils.isEmpty(newResList)) {
|
|
|
|
+ LogPrintMgr.getInstance().printLogMsg(LogLevelFlag.LOG_INFO, LogFlagBusiType.BUSI_INTERNAL.toStrValue(), mStrClassName, ""
|
|
|
|
+ , "7777");
|
|
|
|
+ responseRes.setRescode(ResponseCode.RESULT_NORMAL.toStrCode());
|
|
|
|
+ responseRes.setResmsg(ResponseCode.RESULT_NORMAL.toStrMsg());
|
|
|
|
+ responseRes.setResdata(newResList);
|
|
|
|
+ }
|
|
|
|
+ }else {
|
|
|
|
+ //
|
|
|
|
+ List<Map<String, Object>> resList = getWaterTapWaterApi().getTbMHourwater(jpTbMHourWater.getIsPage(),
|
|
|
|
+ jpTbMHourWater.getLimit(), jpTbMHourWater.getOffset(), jpTbMHourWater.getForDateStr());
|
|
|
|
+ if (!CollectionUtils.isEmpty(resList)) {
|
|
|
|
+ responseRes.setRescode(ResponseCode.RESULT_NORMAL.toStrCode());
|
|
|
|
+ responseRes.setResmsg(ResponseCode.RESULT_NORMAL.toStrMsg());
|
|
|
|
+ responseRes.setResdata(resList);
|
|
|
|
+ }
|
|
}
|
|
}
|
|
return responseRes;
|
|
return responseRes;
|
|
}catch(Exception ex){
|
|
}catch(Exception ex){
|
|
@@ -476,7 +718,7 @@ public class KprAimWaterCollecationBizFun {
|
|
entity.setPumpId(null);
|
|
entity.setPumpId(null);
|
|
entity.setSubType(subType);
|
|
entity.setSubType(subType);
|
|
List<Map<String, Object>> defaultRes = new ArrayList<>();
|
|
List<Map<String, Object>> defaultRes = new ArrayList<>();
|
|
- if("water_volume_prediction_jiangjin".equals(databaseName)){
|
|
|
|
|
|
+ if("water_volume_prediction_jiangjin2".equals(databaseName)){
|
|
Map<String, Object> map = new HashMap<>();
|
|
Map<String, Object> map = new HashMap<>();
|
|
map.put("id", null);
|
|
map.put("id", null);
|
|
map.put("date", null);
|
|
map.put("date", null);
|
|
@@ -568,7 +810,7 @@ public class KprAimWaterCollecationBizFun {
|
|
entity.setPumpId(null);
|
|
entity.setPumpId(null);
|
|
entity.setSubType(subType);
|
|
entity.setSubType(subType);
|
|
List<Map<String, Object>> defaultRes = new ArrayList<>();
|
|
List<Map<String, Object>> defaultRes = new ArrayList<>();
|
|
- if("water_volume_prediction_jiangjin".equals(databaseName)){
|
|
|
|
|
|
+ if("water_volume_prediction_jiangjin2".equals(databaseName)){
|
|
Map<String, Object> map = new HashMap<>();
|
|
Map<String, Object> map = new HashMap<>();
|
|
map.put("id", null);
|
|
map.put("id", null);
|
|
map.put("date", null);
|
|
map.put("date", null);
|
|
@@ -607,7 +849,7 @@ public class KprAimWaterCollecationBizFun {
|
|
//
|
|
//
|
|
List<Map<String, Object>> resList = getWaterTapWaterApi().getTbMHourwaterWatersupply(jpTbMHourWater.getIsPage(),
|
|
List<Map<String, Object>> resList = getWaterTapWaterApi().getTbMHourwaterWatersupply(jpTbMHourWater.getIsPage(),
|
|
jpTbMHourWater.getLimit(), jpTbMHourWater.getOffset(), jpTbMHourWater.getForDateStr());
|
|
jpTbMHourWater.getLimit(), jpTbMHourWater.getOffset(), jpTbMHourWater.getForDateStr());
|
|
- if("water_volume_prediction_jiangjin".equals(databaseName)){
|
|
|
|
|
|
+ if("water_volume_prediction_jiangjin2".equals(databaseName)){
|
|
//TODO 按水厂分组
|
|
//TODO 按水厂分组
|
|
Map<Object, List<Map<String, Object>>> groupedData =
|
|
Map<Object, List<Map<String, Object>>> groupedData =
|
|
resList.stream().collect(Collectors.groupingBy(item -> item.get("zone_id")));
|
|
resList.stream().collect(Collectors.groupingBy(item -> item.get("zone_id")));
|
|
@@ -642,7 +884,6 @@ public class KprAimWaterCollecationBizFun {
|
|
}
|
|
}
|
|
return responseRes;
|
|
return responseRes;
|
|
}else {
|
|
}else {
|
|
- //TODO 按水厂分组
|
|
|
|
Map<Object, List<Map<String, Object>>> groupedData =
|
|
Map<Object, List<Map<String, Object>>> groupedData =
|
|
resList.stream().collect(Collectors.groupingBy(item -> item.get("orgId")));
|
|
resList.stream().collect(Collectors.groupingBy(item -> item.get("orgId")));
|
|
//TODO 查询水厂的取水泵,然后将数据拼接
|
|
//TODO 查询水厂的取水泵,然后将数据拼接
|
|
@@ -900,6 +1141,111 @@ public class KprAimWaterCollecationBizFun {
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+ //TODO 跑+1天
|
|
|
|
+ public static void insertYucePump(String monthNow){
|
|
|
|
+ System.out.println("添加预测泵组优化小时数据正在进行"+ TimeTool.convertUTC2DateStr(TimeTool.getCurMsUTC(),TimeTool.TIMESTAMP_FORMAT));
|
|
|
|
+ try {
|
|
|
|
+ //先获取配置项 根据配置项来进行逻辑添加
|
|
|
|
+ String yearStr = "";
|
|
|
|
+ String monthStr ="";
|
|
|
|
+ if(!StringUtils.isEmpty(monthNow)){
|
|
|
|
+ yearStr = monthNow.split("-")[0];
|
|
|
|
+ monthStr = monthNow.split("-")[1];
|
|
|
|
+ }
|
|
|
|
+ LocalDateTime startDate = LocalDateTime.now().withYear(Integer.valueOf(yearStr))
|
|
|
|
+ .withMonth(Integer.valueOf(monthStr)).withHour(0).withMinute(0).withSecond(0).withNano(0);
|
|
|
|
+
|
|
|
|
+ List<Map<String,Object>> orgConfig = getWaterTapWaterApi().getOrgConfig(false,0,0," AND org_name not like '%水厂'");
|
|
|
|
+ //TODO 总体逻辑: 先查询指定月上一年的每日平均值,再按平均值的上下啊百分比去插入指定的浮动百分比数据
|
|
|
|
+ for (int i = 0;i<1;i++){
|
|
|
|
+ LocalDateTime dateNow = startDate.minusDays(-i);//当前循环时间
|
|
|
|
+ //TODO 数据库操作 A 调用对应时间预测接口 B 在修改实际值
|
|
|
|
+ DateTimeFormatter formatter2 = DateTimeFormatter.ofPattern("yyyy-MM-dd");
|
|
|
|
+ String dateStr = dateNow.withYear(LocalDateTime.now().getYear()).toLocalDate().format(formatter2);
|
|
|
|
+ //TODO A
|
|
|
|
+ for (Map<String,Object> org : orgConfig) {
|
|
|
|
+ JP3TPHour tpHour = new JP3TPHour();
|
|
|
|
+ tpHour.setOrgId(org.get("org_id").toString());
|
|
|
|
+ tpHour.setDate(dateStr);
|
|
|
|
+ LogPrintMgr.getInstance().printLogMsg(LogLevelFlag.LOG_INFO
|
|
|
|
+ , mStrClassName
|
|
|
|
+ , mStrClassName
|
|
|
|
+ , String.format("执行未来预测泵组优化小时数据" + FastJsonUtil.toJSON(tpHour) + "调用"));
|
|
|
|
+ try {
|
|
|
|
+ ResponseRes<String> tpRes = ServiceMgrProxy.getInstance()
|
|
|
|
+ .applyCloud3tpServiceApi().dayHourPump(tpHour);
|
|
|
|
+ if (ResponseCode.RESULT_BAD.toStrCode().equals(tpRes.getRescode())) {
|
|
|
|
+ LogPrintMgr.getInstance().printLogMsg(LogLevelFlag.LOG_ERROR
|
|
|
|
+ , mStrClassName
|
|
|
|
+ , mStrClassName
|
|
|
|
+ , String.format("预测泵小时数据" + dateStr + "调用失败 ERROR:{%s} ",
|
|
|
|
+ tpRes.getResdata()));
|
|
|
|
+ }
|
|
|
|
+ } catch (Exception ex) {
|
|
|
|
+ LogPrintMgr.getInstance().printLogMsg(LogLevelFlag.LOG_ERROR
|
|
|
|
+ , mStrClassName
|
|
|
|
+ , mStrClassName
|
|
|
|
+ , String.format("预测泵小时数据" + dateStr + "调用异常 ERROR:{%s} ",
|
|
|
|
+ ex.getLocalizedMessage()));
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ System.out.println("调用预测模型泵组优化小时数据结束"+ TimeTool.convertUTC2DateStr(TimeTool.getCurMsUTC(),TimeTool.TIMESTAMP_FORMAT));
|
|
|
|
+ }catch(Exception ex){
|
|
|
|
+ ex.printStackTrace();
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ //TODO 跑泵组数据插入预测实际值
|
|
|
|
+ public static void insertYucePumpReal(String monthNow,int monthDay){
|
|
|
|
+ DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
|
|
|
|
+ System.out.println("添加实际值");
|
|
|
|
+ try {
|
|
|
|
+ //先获取配置项 根据配置项来进行逻辑添加
|
|
|
|
+ String yearStr = "";
|
|
|
|
+ String monthStr = "";
|
|
|
|
+ if (!StringUtils.isEmpty(monthNow)) {
|
|
|
|
+ yearStr = monthNow.split("-")[0];
|
|
|
|
+ monthStr = monthNow.split("-")[1];
|
|
|
|
+ }
|
|
|
|
+ LocalDateTime startDate = LocalDateTime.now().withYear(Integer.valueOf(yearStr))
|
|
|
|
+ .withMonth(Integer.valueOf(monthStr)).withDayOfMonth(monthDay).withHour(0).withMinute(0).withSecond(0).withNano(0);
|
|
|
|
+ LocalDateTime endDate = LocalDateTime.now().withMinute(0).withSecond(0).withNano(0);
|
|
|
|
+ //TODO 查询开始时间开始的原始数据
|
|
|
|
+ List<Map<String,Object>> recordAllRes = getWaterTapApi()
|
|
|
|
+ .getPumpCollectionRecordAllListAll(" WHERE 1=1 " +
|
|
|
|
+ " AND \"time\"::timestamp BETWEEN '"+startDate.format(formatter)+"' "+"AND '"+endDate.format(formatter)+"'");
|
|
|
|
+ for (Map<String,Object> recordAll:recordAllRes){
|
|
|
|
+ //TODO 查询对应Day和hour对应的预测数据是否存在, 存在的话就修改实际值状态
|
|
|
|
+ List<Map<String, Object>> resList = getWaterTapWaterApi().getTbMHourwaterWatersupply(true,
|
|
|
|
+ 1, 0, "AND \"PumpID\" = '"+recordAll.get("device_code")+"' AND \"Date\" = '"+LocalDateTime.parse(recordAll.get("time").toString(), formatter).format(DateTimeFormatter.ofPattern("yyyy-MM-dd"))
|
|
|
|
+ +"' AND \"Hour\" = '"+LocalDateTime.parse(recordAll.get("time").toString(), formatter).format(DateTimeFormatter.ofPattern("HH:mm:ss"))+"'");
|
|
|
|
+ if(!CollectionUtils.isEmpty(resList)){
|
|
|
|
+ //TODO 说明存在,则修改
|
|
|
|
+ Map<String,Object> oldMap = resList.get(0);
|
|
|
|
+ if(!ObjectUtils.isEmpty(recordAll.get("startup_state"))){
|
|
|
|
+ oldMap.put("RealPumpStatus",recordAll.get("startup_state"));
|
|
|
|
+ }else if (!ObjectUtils.isEmpty(recordAll.get("active_energy"))){
|
|
|
|
+ oldMap.put("RealPumpStatus",1);
|
|
|
|
+ }else{
|
|
|
|
+ oldMap.put("RealPumpStatus",0);
|
|
|
|
+ }
|
|
|
|
+ oldMap.remove("ID");
|
|
|
|
+ int res = getWaterTapApi().insertOrUpdateTbmHourwaterWatersupply(oldMap);
|
|
|
|
+ if(res<0){
|
|
|
|
+ LogPrintMgr.getInstance().printLogMsg(LogLevelFlag.LOG_ERROR
|
|
|
|
+ , mStrClassName
|
|
|
|
+ , mStrClassName
|
|
|
|
+ ,"修改泵实际状态数据失败");
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ System.out.println("泵数据实际值修改完成");
|
|
|
|
+ }catch(Exception ex){
|
|
|
|
+ ex.printStackTrace();
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
//TODO 定时任务 定时添加预测数据 废弃
|
|
//TODO 定时任务 定时添加预测数据 废弃
|
|
public static void insertYuceDataScheduled(String monthNow){
|
|
public static void insertYuceDataScheduled(String monthNow){
|
|
System.out.println("添加预测日数据正在进行"+ TimeTool.convertUTC2DateStr(TimeTool.getCurMsUTC(),TimeTool.TIMESTAMP_FORMAT));
|
|
System.out.println("添加预测日数据正在进行"+ TimeTool.convertUTC2DateStr(TimeTool.getCurMsUTC(),TimeTool.TIMESTAMP_FORMAT));
|
|
@@ -1280,22 +1626,22 @@ public class KprAimWaterCollecationBizFun {
|
|
// }else{
|
|
// }else{
|
|
// map.put("PumpStatus",1);
|
|
// map.put("PumpStatus",1);
|
|
// }
|
|
// }
|
|
- map.put("PumpStatus",algorithm.getNextValue());
|
|
|
|
- map.put("HourForecastActualWaterSupply",splitRandomYuce.get(kIndex));//预测泵的供水量
|
|
|
|
- map.put("PumpWater",splitRandom.get(kIndex));//实际泵的供水量
|
|
|
|
|
|
+// map.put("PumpStatus",algorithm.getNextValue());
|
|
|
|
+// map.put("HourForecastActualWaterSupply",splitRandomYuce.get(kIndex));//预测泵的供水量/
|
|
|
|
+// map.put("PumpWater",splitRandom.get(kIndex));//实际泵的供水量
|
|
// if(splitRandom.get(kIndex)==0){
|
|
// if(splitRandom.get(kIndex)==0){
|
|
// //TODO 说明泵实际值为0,状态为关
|
|
// //TODO 说明泵实际值为0,状态为关
|
|
// map.put("RealPumpStatus",0);
|
|
// map.put("RealPumpStatus",0);
|
|
// }else{
|
|
// }else{
|
|
// map.put("RealPumpStatus",1);
|
|
// map.put("RealPumpStatus",1);
|
|
// }
|
|
// }
|
|
- map.put("RealPumpStatus",algorithm.getNextValue());
|
|
|
|
|
|
+// map.put("RealPumpStatus",algorithm.getNextValue());
|
|
|
|
|
|
map.put("PumpEnergy",splitRandomYuce.get(kIndex)/1000*180);
|
|
map.put("PumpEnergy",splitRandomYuce.get(kIndex)/1000*180);
|
|
map.put("RealPumpEnergy",splitRandom.get(kIndex)/1000*200);
|
|
map.put("RealPumpEnergy",splitRandom.get(kIndex)/1000*200);
|
|
- map.put("LastModifyTime", LocalDateTime.now().format(formatter));
|
|
|
|
|
|
+// map.put("LastModifyTime", LocalDateTime.now().format(formatter));
|
|
map.put("orgId", orgId);
|
|
map.put("orgId", orgId);
|
|
- //TODO 添加or修改
|
|
|
|
|
|
+ //TODO 添加or修改 暂时注释
|
|
Integer insertRes2 = getWaterTapApi().insertOrUpdateTbmHourwaterWatersupply(map);
|
|
Integer insertRes2 = getWaterTapApi().insertOrUpdateTbmHourwaterWatersupply(map);
|
|
if (insertRes2 < 1) {
|
|
if (insertRes2 < 1) {
|
|
LogPrintMgr.getInstance().printLogMsg(LogLevelFlag.LOG_ERROR
|
|
LogPrintMgr.getInstance().printLogMsg(LogLevelFlag.LOG_ERROR
|
|
@@ -1416,4 +1762,78 @@ public class KprAimWaterCollecationBizFun {
|
|
return responseRes;
|
|
return responseRes;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
+
|
|
|
|
+ //TODO 重新计算原始小时数据的用电量
|
|
|
|
+ //TODO 逻辑:有小时读数的 按小时读数去算, 没有的话就按额定功率*1h去作为用电量
|
|
|
|
+ public static void initPumpPowerZero(){
|
|
|
|
+ DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
|
|
|
|
+ //TODO 首先查询出所有的设备
|
|
|
|
+ System.out.println("计算原始小时数据的用电量....");
|
|
|
|
+ List<Map<String, Object>> configList = getWaterTapApi().getWaterPumpCollectionConfigList("");
|
|
|
|
+ List<Map<String, Object>> energyList = getWaterTapApi().getWatertPumpEnergy("");
|
|
|
|
+ if (!CollectionUtils.isEmpty(configList) && !CollectionUtils.isEmpty(energyList)) {
|
|
|
|
+ // 按照设备分组
|
|
|
|
+ Map<Object, List<Map<String, Object>>> groupedData = configList.stream()
|
|
|
|
+ .collect(Collectors.groupingBy(item -> item.get("device_code")));
|
|
|
|
+
|
|
|
|
+ final CountDownLatch latch = new CountDownLatch(groupedData.keySet().size());
|
|
|
|
+ ExecutorService executor = Executors.newFixedThreadPool(groupedData.keySet().size()); // 使用线程池
|
|
|
|
+
|
|
|
|
+ for (Object config : groupedData.keySet()) {
|
|
|
|
+ try {
|
|
|
|
+ List<Map<String, Object>> recordAll = getWaterTapApi().getWaterPumpRecordAllListAll(
|
|
|
|
+ "WHERE device_code ='" + config + "' " +
|
|
|
|
+ " AND \"time\"::timestamp BETWEEN '" + LocalDateTime.now().minusDays(2).withHour(0).withMinute(0).withSecond(0).withNano(0).format(formatter) + "' " + "AND '" + LocalDateTime.now().format(formatter) + "'" +
|
|
|
|
+ " ORDER BY time ASC ");
|
|
|
|
+ if (CollectionUtils.isEmpty(recordAll)) {
|
|
|
|
+ continue; // 如果设备没有数据,跳过
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ // 遍历 recordAll 中的每条记录
|
|
|
|
+ for (int i = 1; i < recordAll.size(); i++) {
|
|
|
|
+ Map<String, Object> currentRecord = recordAll.get(i);
|
|
|
|
+ Map<String, Object> previousRecord = recordAll.get(i - 1);
|
|
|
|
+
|
|
|
|
+ Double currentEnergy = (Double) currentRecord.get("active_energy");
|
|
|
|
+ Double previousEnergy = (Double) previousRecord.get("active_energy");
|
|
|
|
+
|
|
|
|
+ double powerConsumption = 0.0;
|
|
|
|
+
|
|
|
|
+ if (currentEnergy != null && previousEnergy != null) {
|
|
|
|
+ // 情况1:累计电量读数都非空
|
|
|
|
+ powerConsumption = currentEnergy - previousEnergy;
|
|
|
|
+ } else {
|
|
|
|
+ // 情况2:累计电量读数有一个为空
|
|
|
|
+ String deviceCode = (String) currentRecord.get("device_code");
|
|
|
|
+ Optional<Map<String, Object>> targetMap = energyList.stream()
|
|
|
|
+ .filter(map -> deviceCode.equals(map.get("PumpID"))) // 过滤条件
|
|
|
|
+ .findFirst();
|
|
|
|
+ if (targetMap.isPresent()) {
|
|
|
|
+ Map<String, Object> resultMap = targetMap.get();
|
|
|
|
+ Object ratedPower = resultMap.get(deviceCode);
|
|
|
|
+ if (ratedPower != null) {
|
|
|
|
+ powerConsumption = Double.valueOf(ratedPower.toString()) * 1; // 用电量 = 额定功率 × 1
|
|
|
|
+ } else {
|
|
|
|
+ powerConsumption = 0.0; // 额定功率未找到,用电量为 0
|
|
|
|
+ }
|
|
|
|
+ } else {
|
|
|
|
+ powerConsumption = 500 + (Math.random() - 0.5) * 200; // 额定功率未找到,用电量为 0
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ // 更新当前记录的用电量字段
|
|
|
|
+ currentRecord.put("power_cons", powerConsumption);
|
|
|
|
+ int res = getWaterTapApi().insertOrUpdateWaterPumpRecordAll(currentRecord);
|
|
|
|
+ if (res <= 0) {
|
|
|
|
+ System.out.println("修改小时用电量失败");
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ } catch (Exception ex) {
|
|
|
|
+
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ System.out.println("修改小时用电量完成");
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ }
|
|
}
|
|
}
|