zhitan-cloud
2025-02-08 0164d6fadfd6590ab8d08b6ec3213a967cc6276f
!54 !53 组态图更新
Merge pull request !54 from zhitan-cloud/develop1.0
已添加37个文件
已修改13个文件
已删除1个文件
3416 ■■■■■ 文件已修改
zhitan-admin/src/main/java/com/zhitan/web/controller/basicSetup/SysEquipmentfileController.java 91 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zhitan-admin/src/main/java/com/zhitan/web/controller/energyMonitor/ElectricLoadController.java 58 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zhitan-admin/src/main/java/com/zhitan/web/controller/history/HistoryDataTrendController.java 224 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zhitan-admin/src/main/java/com/zhitan/web/controller/realtimedata/RealtimeTrendController.java 73 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zhitan-admin/src/main/java/com/zhitan/web/controller/statisticalAnalysis/StatisticalAnalysisController.java 129 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zhitan-common/src/main/java/com/zhitan/common/config/BaseConfig.java 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zhitan-common/src/main/java/com/zhitan/common/constant/TimeTypeConst.java 25 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zhitan-system/src/main/java/com/zhitan/basicSetup/mapper/SysEquipmentfileMapper.java 25 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zhitan-system/src/main/java/com/zhitan/basicSetup/service/ISysEquipmentfileService.java 33 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zhitan-system/src/main/java/com/zhitan/basicSetup/service/impl/SysEquipmentfileServiceImpl.java 59 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zhitan-system/src/main/java/com/zhitan/consumptionanalysis/service/impl/ConsumptionAnalysisServiceImpl.java 369 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zhitan-system/src/main/java/com/zhitan/dataitem/mapper/DataItemMapper.java 12 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zhitan-system/src/main/java/com/zhitan/dataitem/service/IDataItemService.java 11 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zhitan-system/src/main/java/com/zhitan/dataitem/service/impl/DataItemServiceImpl.java 14 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zhitan-system/src/main/java/com/zhitan/energyMonitor/domain/EnergyUnitToDevice.java 71 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zhitan-system/src/main/java/com/zhitan/energyMonitor/domain/vo/EnergyCalculateCalcTV.java 31 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zhitan-system/src/main/java/com/zhitan/energyMonitor/domain/vo/ListElectricityMeterVO.java 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zhitan-system/src/main/java/com/zhitan/energyMonitor/domain/vo/UnitToDeviceRelationVO.java 35 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zhitan-system/src/main/java/com/zhitan/energyMonitor/mapper/EnergyUnitToDeviceMapper.java 38 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zhitan-system/src/main/java/com/zhitan/energyMonitor/service/IEnergyUnitToDeviceService.java 100 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zhitan-system/src/main/java/com/zhitan/energyMonitor/service/impl/EnergyUnitToDeviceServiceImpl.java 232 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zhitan-system/src/main/java/com/zhitan/history/domain/dto/HistoricalDataDTO.java 63 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zhitan-system/src/main/java/com/zhitan/history/domain/vo/HistoricalDataExcel.java 70 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zhitan-system/src/main/java/com/zhitan/history/domain/vo/HistoricalDataVO.java 77 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zhitan-system/src/main/java/com/zhitan/model/domain/vo/ModelNodeIndexInfor.java 10 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zhitan-system/src/main/java/com/zhitan/realtimedata/data/RealtimeDatabaseManager.java 163 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zhitan-system/src/main/java/com/zhitan/realtimedata/domain/SysEquipmentFile.java 11 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zhitan-system/src/main/java/com/zhitan/realtimedata/domain/vo/EquipmentMeasuringPointParameters.java 30 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zhitan-system/src/main/java/com/zhitan/realtimedata/mapper/SvgTrendMapper.java 16 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zhitan-system/src/main/java/com/zhitan/realtimedata/service/ISvgTrendService.java 15 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zhitan-system/src/main/java/com/zhitan/realtimedata/service/RealtimeDatabaseService.java 14 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zhitan-system/src/main/java/com/zhitan/realtimedata/service/impl/RealtimeDatabaseServiceImpl.java 12 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zhitan-system/src/main/java/com/zhitan/realtimedata/service/impl/SvgTrendServicelmpl.java 26 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zhitan-system/src/main/java/com/zhitan/statisticalAnalysis/domain/dto/DataAnalysisMoMDTO.java 48 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zhitan-system/src/main/java/com/zhitan/statisticalAnalysis/domain/vo/DataAnalysisMoMExcel.java 47 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zhitan-system/src/main/java/com/zhitan/statisticalAnalysis/domain/vo/DataAnalysisMoMVO.java 42 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zhitan-system/src/main/java/com/zhitan/statisticalAnalysis/domain/vo/DataAnalysisYoYExcel.java 47 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zhitan-system/src/main/java/com/zhitan/statisticalAnalysis/domain/vo/DataAnalysisYoYVO.java 42 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zhitan-system/src/main/java/com/zhitan/statisticalAnalysis/service/IStatisticalAnalysisService.java 36 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zhitan-system/src/main/java/com/zhitan/statisticalAnalysis/service/impl/StatisticalAnalysisServiceImpl.java 293 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zhitan-system/src/main/resources/mapper/basicSetup/SysEquipmentfileMapper.xml 48 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zhitan-system/src/main/resources/mapper/dataitem/DataItemMapper.xml 24 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zhitan-system/src/main/resources/mapper/model/ModelNodeMapper.xml 3 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zhitan-system/src/main/resources/mapper/realtimedata/SvgTrendMapper.xml 37 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zhitan-vue/src/assets/images/font01.png 补丁 | 查看 | 原始文档 | blame | 历史
zhitan-vue/src/assets/images/img_logo.png 补丁 | 查看 | 原始文档 | blame | 历史
zhitan-vue/src/assets/images/login-background.jpg 补丁 | 查看 | 原始文档 | blame | 历史
zhitan-vue/src/assets/images/login-background.png 补丁 | 查看 | 原始文档 | blame | 历史
zhitan-vue/src/assets/images/logo.png 补丁 | 查看 | 原始文档 | blame | 历史
zhitan-vue/src/views/login copy.vue 293 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zhitan-vue/src/views/login.vue 295 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zhitan-admin/src/main/java/com/zhitan/web/controller/basicSetup/SysEquipmentfileController.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,91 @@
package com.zhitan.web.controller.basicSetup;
import com.zhitan.basicSetup.service.ISysEquipmentfileService;
import com.zhitan.common.annotation.Log;
import com.zhitan.common.config.BaseConfig;
import com.zhitan.common.core.controller.BaseController;
import com.zhitan.common.core.domain.AjaxResult;
import com.zhitan.common.enums.BusinessType;
import com.zhitan.common.utils.file.FileUploadUtils;
import com.zhitan.common.utils.uuid.UUID;
import com.zhitan.realtimedata.domain.SysEquipmentFile;
import com.zhitan.realtimedata.domain.SysSvgInfo;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import java.io.IOException;
import java.util.List;
/**
 * ç»„态图Controller
 *
 * @author sys
 * @date 2020-02-24
 */
@Slf4j
@RestController
@RequestMapping("/basicSetup/equipmentfile")
public class SysEquipmentfileController extends BaseController {
  private final ISysEquipmentfileService sysEquipmentfileService;
  public SysEquipmentfileController(
      ISysEquipmentfileService sysEquipmentfileService) {
    this.sysEquipmentfileService = sysEquipmentfileService;
  }
  @PostMapping(value = "/upload")
  @Log(title = "系统图", businessType = BusinessType.IMPORT)
  public AjaxResult upload(MultipartFile file) throws IOException {
    if (!file.isEmpty()) {
      String fileSuffix = FileUploadUtils.getExtension(file);
      if (StringUtils.containsIgnoreCase(".svg,.jpg,.png,.gif", fileSuffix)) {
        //文件最终保存的绝对路径
        String filePath = FileUploadUtils.upload(BaseConfig.getConfigurePath(), file);
        return AjaxResult.success(filePath);
      }
      return AjaxResult.error("文件格式错误");
    }
    return AjaxResult.error("系统图上传失败");
  }
  /**
   * ä¿®æ”¹ç»„态图
   */
  @Log(title = "系统图", businessType = BusinessType.UPDATE)
  @PutMapping
  public AjaxResult edit(@RequestBody SysEquipmentFile sysEquipmentfile) {
    try {
      sysEquipmentfileService.saveEquipmentFile(sysEquipmentfile);
      return AjaxResult.success();
    } catch (Exception ex) {
      log.error("组态图更新失败", ex);
      return AjaxResult.error();
    }
  }
  @PutMapping("/setting/{nodeId}")
  public AjaxResult saveSetting(@PathVariable("nodeId") String nodeId,
      @RequestBody List<SysSvgInfo> svgInfo) {
    try {
      svgInfo.forEach(info -> info.setId(UUID.fastUUID().toString()));
      sysEquipmentfileService.saveSettingInfo(nodeId, svgInfo);
      return AjaxResult.success("保存成功!");
    } catch (Exception ex) {
      return AjaxResult.error("保存失败!");
    }
  }
  @GetMapping("/configure/{nodeId}")
  public AjaxResult getConfigure(@PathVariable("nodeId") String nodeId) {
    try {
      SysEquipmentFile sysEquipmentfile = sysEquipmentfileService.getConfigure(nodeId);
      return AjaxResult.success(sysEquipmentfile);
    } catch (Exception ex) {
      return AjaxResult.error("查询失败!");
    }
  }
}
zhitan-admin/src/main/java/com/zhitan/web/controller/energyMonitor/ElectricLoadController.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,58 @@
package com.zhitan.web.controller.energyMonitor;
import com.zhitan.common.annotation.Log;
import com.zhitan.common.core.controller.BaseController;
import com.zhitan.common.core.domain.AjaxResult;
import com.zhitan.energyMonitor.service.IEnergyUnitToDeviceService;
import com.zhitan.model.service.IEnergyIndexService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
/**
 * @Description: è´Ÿè·åˆ†æž
 * @Author: yxw
 * @Date: 2022-04-24
 * @Version: V1.2
 */
@Api(tags = "负荷分析")
@RestController
@RequestMapping("/loadAnalysis")
@Slf4j
public class ElectricLoadController extends BaseController {
    @Autowired
    private IEnergyUnitToDeviceService energyUnitToDeviceService;
//    @Autowired
//    private IElectricLoadService electricLoadService;
    @Autowired
    private IEnergyIndexService energyIndexService;
    /**
     * æ ¹æ®ç”µè¡¨id获取负荷分析数据
     *
     * @param energyUnitId ç”¨èƒ½å•å…ƒid
     * @param meterId      ç”µè¡¨id
     * @param timeType     æ—¶é—´ç±»åž‹ DAY/MONTH/YEAR
     * @param timeCode     æ—¶é—´å€¼ ä¸Žæ—¶é—´ç±»åž‹å¯¹åº”:2022-03-21/2022-03/2022
     * @return
     */
    @Log(title = "根据电表id获取负荷分析数据")
    @ApiOperation(value = "根据电表id获取负荷分析数据", notes = "根据电表id获取负荷分析数据")
    @GetMapping(value = "/detail")
    public AjaxResult list(@RequestParam(name = "energyUnitId") String energyUnitId,
                           @RequestParam(name = "meterId") String meterId,
                           @RequestParam(name = "timeType") String timeType,
                           @RequestParam(name = "timeCode") String timeCode) {
//        EnergyIndex energyIndex = energyIndexService.getDeviceIndexByCode(energyUnitId, meterId, CommonConst.TAG_CODE_ZYGGL);
//
//        EnergyUnitToDevice energyUnitToDevice = energyUnitToDeviceService.getEnergyUnitToDeviceById(energyUnitId, meterId);
//        ListElectricLoadVO lsvo = electricLoadService.list(timeType, timeCode, energyIndex, energyUnitToDevice);
        return AjaxResult.success(null);
    }
}
zhitan-admin/src/main/java/com/zhitan/web/controller/history/HistoryDataTrendController.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,224 @@
package com.zhitan.web.controller.history;
import cn.hutool.core.date.DateUtil;
import com.zhitan.basicdata.domain.MeterImplement;
import com.zhitan.basicdata.services.IMeterImplementService;
import com.zhitan.common.annotation.Log;
import com.zhitan.common.core.controller.BaseController;
import com.zhitan.common.core.domain.AjaxResult;
import com.zhitan.common.enums.BusinessType;
import com.zhitan.common.enums.RetrievalModes;
import com.zhitan.common.utils.poi.ExcelUtil;
import com.zhitan.history.domain.dto.HistoricalDataDTO;
import com.zhitan.history.domain.vo.HistoricalDataExcel;
import com.zhitan.history.domain.vo.HistoricalDataVO;
import com.zhitan.model.domain.EnergyIndex;
import com.zhitan.model.service.IEnergyIndexService;
import com.zhitan.realtimedata.domain.TagValue;
import com.zhitan.realtimedata.service.RealtimeDatabaseService;
import org.apache.commons.lang3.ObjectUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
/**
 * è®¾å¤‡å¯åœå®žæ—¶ç›‘测Controller
 *
 * @author sys
 * @date 2020-03-30
 */
@RestController
@RequestMapping("/dataMonitoring/historyDataTrend")
public class HistoryDataTrendController extends BaseController {
    @Autowired
    private final IEnergyIndexService energyIndexService;
    @Autowired
    private final IMeterImplementService meterImplementService;
    @Autowired
    private final RealtimeDatabaseService realtimeDatabaseService;
    public HistoryDataTrendController(IEnergyIndexService energyIndexService,
                                      IMeterImplementService meterImplementService,
                                      RealtimeDatabaseService realtimeDatabaseService) {
        this.energyIndexService = energyIndexService;
        this.meterImplementService = meterImplementService;
        this.realtimeDatabaseService = realtimeDatabaseService;
    }
    @Log(title = "获取模型节点关联采集指标", businessType = BusinessType.UPDATE)
    @GetMapping("/energyIndex/list")
    public AjaxResult getSettingIndex(EnergyIndex energyIndex) {
        try {
            List<EnergyIndex> infoList = energyIndexService.selectEnergyIndexList(energyIndex);
//            List<String> codeList= infoList.stream().map(EnergyIndex::getCode).collect(Collectors.toList());
//            List<TagValue> valList = realtimeDatabaseService.retrieve(codeList);
//            List resultList = new ArrayList();
            return AjaxResult.success(infoList);
        } catch (Exception ex) {
            logger.error("获取关联采集指标出错!", ex);
            return AjaxResult.error("获取关联指标出错!");
        }
    }
    @Log(title = "根据时间与点位查询历史监测数据", businessType = BusinessType.UPDATE)
    @GetMapping("/getHistoricalDataByIndexId")
    public AjaxResult getHistoricalDataByIndexId(HistoricalDataDTO dto) {
        try {
            // èŽ·å–ç‚¹ä½ä¿¡æ¯
            EnergyIndex energyIndex = energyIndexService.selectEnergyIndexById(dto.getIndexId());
            if (ObjectUtils.isEmpty(energyIndex)) {
                return AjaxResult.error("未找到点位信息");
            }
            Date beginTime = dto.getDataTime();
            Date endTime;
            // æŸ¥è¯¢æ¡æ•°
            int count = 1440;
            if ("DAY".equals(dto.getTimeType())) {
                endTime = DateUtil.endOfDay(beginTime);
            } else {
                count = 3600;
                endTime = DateUtil.offsetSecond(DateUtil.offsetHour(beginTime, 1), -1);
            }
            // æŸ¥è¯¢è®¡é‡å™¨å…·
            MeterImplement info = meterImplementService.selectMeterImplementById(energyIndex.getMeterId());
            List<TagValue> tagValueList = realtimeDatabaseService.retrieve(energyIndex.getCode(), beginTime, endTime,
                    RetrievalModes.BestFit, count);
            List<HistoricalDataVO> voList = new ArrayList<>();
            Date date = DateUtil.date();
            for (int i = 0; i < count + 1; i++) {
                HistoricalDataVO vo = new HistoricalDataVO();
                vo.setIndexId(energyIndex.getIndexId());
                String indexName = energyIndex.getName();
                if (ObjectUtils.isNotEmpty(info)) {
                    indexName = info.getInstallactionLocation() + "_" + info.getMeterName() + "_" + indexName;
                }
                vo.setIndexName(indexName);
                // å–值
                String value = "--";
                String usedValue = "--";
                if (beginTime.getTime() <= date.getTime()) {
                    try {
                        TagValue tagValue = tagValueList.get(i);
                        BigDecimal cumulative = BigDecimal.valueOf(tagValue.getValue());
                        if ("SWWSDJ_SD".equals(energyIndex.getCode()) || "SWWSDJ_WD".equals(energyIndex.getCode())) {
                            cumulative = cumulative.multiply(BigDecimal.valueOf(0.1));
                        }
                        if (i > 0) {
                            TagValue previousTagValue = tagValueList.get(i - 1);
                            BigDecimal previousValue = BigDecimal.ZERO;
                            if (ObjectUtils.isNotEmpty(previousTagValue.getValue())) {
                                previousValue = BigDecimal.valueOf(previousTagValue.getValue());
                            }
                            if ("SWWSDJ_SD".equals(energyIndex.getCode()) || "SWWSDJ_WD".equals(energyIndex.getCode())) {
                                previousValue = previousValue.multiply(BigDecimal.valueOf(0.1));
                            }
                            usedValue = String.valueOf(cumulative.subtract(previousValue).setScale(2, RoundingMode.HALF_UP));
                        }
                        value = String.valueOf(cumulative.setScale(2, RoundingMode.HALF_UP));
                    } catch (Exception ignored) {
                    }
                }
                // æ—¶é—´
                String timeName = DateUtil.formatDateTime(beginTime);
                vo.setDataTime(timeName);
                if ("DAY".equals(dto.getTimeType())) {
                    beginTime = DateUtil.offsetMinute(beginTime, 1);
                } else {
                    beginTime = DateUtil.offsetSecond(beginTime, 1);
                }
                vo.setUsedValue(String.valueOf(usedValue));
                vo.setValue(String.valueOf(value));
                voList.add(vo);
            }
            return AjaxResult.success(voList);
        } catch (Exception ex) {
            logger.error("查询历史监测数据出错!", ex);
            return AjaxResult.error("查询历史监测数据出错!");
        }
    }
    @Log(title = "导出Excel", businessType = BusinessType.UPDATE)
    @GetMapping("/export")
    public AjaxResult export(HistoricalDataDTO dto) {
        try {
            // èŽ·å–ç‚¹ä½ä¿¡æ¯
            EnergyIndex energyIndex = energyIndexService.selectEnergyIndexById(dto.getIndexId());
            if (ObjectUtils.isEmpty(energyIndex)) {
                return AjaxResult.success("未找到点位信息");
            }
            Date beginTime = dto.getDataTime();
            Date endTime;
            // æŸ¥è¯¢æ¡æ•°
            int count = 23;
            if ("DAY".equals(dto.getTimeType())) {
                endTime = DateUtil.endOfDay(beginTime);
            } else {
                count = 19;
                endTime = DateUtil.offsetSecond(DateUtil.offsetHour(beginTime, 1), -1);
            }
            // æŸ¥è¯¢è®¡é‡å™¨å…·
            MeterImplement infor = meterImplementService.selectMeterImplementById(energyIndex.getMeterId());
            List<TagValue> tagValueList = realtimeDatabaseService.retrieve(energyIndex.getCode(), beginTime, endTime,
                    RetrievalModes.BestFit, count);
            List<HistoricalDataExcel> excelList = new ArrayList<>();
            Date date = DateUtil.date();
            for (int i = 0; i < count + 1; i++) {
                HistoricalDataExcel vo = new HistoricalDataExcel();
                String indexName = energyIndex.getName();
                if (ObjectUtils.isNotEmpty(infor)) {
                    indexName = infor.getInstallactionLocation() + "_" + infor.getMeterName() + "_" + indexName;
                }
                vo.setIndexName(indexName);
                // å–值
                String value = "--";
                String usedValue = "--";
                if (beginTime.getTime() <= date.getTime()) {
                    try {
                        TagValue tagValue = tagValueList.get(i);
                        BigDecimal cumulative = BigDecimal.valueOf(tagValue.getValue());
                        if (i > 0) {
                            TagValue previousTagValue = tagValueList.get(i - 1);
                            BigDecimal previousValue = BigDecimal.valueOf(previousTagValue.getValue());
                            usedValue = String.valueOf(cumulative.subtract(previousValue).setScale(2, RoundingMode.HALF_UP));
                        }
                        value = String.valueOf(cumulative.setScale(2, RoundingMode.HALF_UP));
                    } catch (Exception ignored) {
                    }
                }
                // æ—¶é—´
                String timeName = DateUtil.formatDateTime(beginTime);
                vo.setDataTime(timeName);
                if ("DAY".equals(dto.getTimeType())) {
                    beginTime = DateUtil.offsetHour(beginTime, 1);
                } else {
                    beginTime = DateUtil.offsetMinute(beginTime, 3);
                }
                vo.setValue(String.valueOf(value));
                vo.setUsedValue(String.valueOf(usedValue));
                excelList.add(vo);
            }
            ExcelUtil<HistoricalDataExcel> util = new ExcelUtil<>(HistoricalDataExcel.class);
            String sheetName = "历史数据统计" + DateUtil.formatDate(dto.getDataTime());
//            return util.exportRealTimeDataExcel(excelList, sheetName);
            return util.exportExcel(excelList, sheetName);
        } catch (Exception ex) {
            logger.error("导出Excel数据出错!", ex);
            return AjaxResult.error("导出Excel数据出错!");
        }
    }
}
zhitan-admin/src/main/java/com/zhitan/web/controller/realtimedata/RealtimeTrendController.java
@@ -5,9 +5,14 @@
import com.zhitan.common.core.domain.AjaxResult;
import com.zhitan.common.enums.BusinessType;
import com.zhitan.common.utils.poi.ExcelUtil;
import com.zhitan.model.domain.EnergyIndex;
import com.zhitan.realtimedata.domain.TagValue;
import com.zhitan.realtimedata.domain.dto.EnergyIndexMonitorDTO;
import com.zhitan.realtimedata.domain.vo.EquipmentMeasuringPointParameters;
import com.zhitan.realtimedata.domain.vo.EquipmentPointParametersExcel;
import com.zhitan.realtimedata.domain.vo.ExportrealtimeTrendVO;
import com.zhitan.realtimedata.service.ISvgTrendService;
import com.zhitan.realtimedata.service.RealtimeDatabaseService;
import com.zhitan.realtimedata.service.RealtimeTrendService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
@@ -15,14 +20,18 @@
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.stream.Collectors;
/**
 * @Description å®žæ—¶ç›‘测控制类
 *
 * @Author zhoubg
 * @date 2024-10-15
 * å®žæ—¶ç›‘测控制类
 **/
@RestController
@RequestMapping("rtdb/realtimeTrend")
@@ -31,11 +40,13 @@
    @Autowired
    private RealtimeTrendService realtimeTrendService;
    @Resource
    private ISvgTrendService svgTrendService;
    @Resource
    private RealtimeDatabaseService realtimeDatabaseService;
    /**
     * èŽ·å–æ¨¡åž‹èŠ‚ç‚¹å…³è”é‡‡é›†æŒ‡æ ‡
     *
     * @return
     */
    @GetMapping("/list")
    @ApiOperation(value = "获取模型节点关联采集指标")
@@ -45,9 +56,6 @@
    /**
     * èŽ·å–åŽ†å²æ¨¡åž‹èŠ‚ç‚¹å…³è”é‡‡é›†æŒ‡æ ‡æ•°æ®
     * @param tagCode
     * @param dataTime
     * @return
     */
    @Log(title = "获取历史模型节点关联采集指标数据", businessType = BusinessType.UPDATE)
    @GetMapping("/chartByDay")
@@ -58,7 +66,6 @@
    /**
     * å¯¼å‡ºå®žæ—¶ç›‘测Excel信息
     * @return
     */
    @Log(title = "导出实时监测Excel信息", businessType = BusinessType.EXPORT)
    @PostMapping("/export")
@@ -69,4 +76,50 @@
        util.exportExcel(response,list, "实时监测");
    }
    /**
     * èŽ·å–æ¨¡åž‹èŠ‚ç‚¹å…³è”é‡‡é›†æŒ‡æ ‡
     */
    @Log(title = "获取模型节点关联采集指标", businessType = BusinessType.UPDATE)
    @GetMapping("/svgTrendView/energyIndex/list")
    @ApiOperation(value = "获取模型节点关联采集指标")
    public AjaxResult getSvgTrendViewSettingIndex(EnergyIndex energyIndex) {
        try {
            List<EnergyIndex> infoList = svgTrendService.selectSvgList(energyIndex);
            if (infoList == null || infoList.isEmpty()){
                return AjaxResult.success(Collections.emptyList());
            }
            List<String> codeList = infoList.stream().map(EnergyIndex::getCode).collect(Collectors.toList());
            List<TagValue> valList = realtimeDatabaseService.retrieve(codeList);
            if (valList == null || valList.isEmpty()) {
                return AjaxResult.success(Collections.emptyList());
            }
            Map<String, List<TagValue>> tagValueMap = valList.stream().collect(Collectors.groupingBy(TagValue::getTagCode));
            List<EquipmentMeasuringPointParameters> resultList = infoList.stream().map(index -> {
                EquipmentMeasuringPointParameters item = new EquipmentMeasuringPointParameters();
                item.setCode(index.getCode());
                item.setIndexName(index.getName());
                item.setIndexUnit(index.getUnitId());
                item.setMeteName(index.getMeterName());
                item.setyValue("y0");
                List<TagValue> tagValueList = tagValueMap.getOrDefault(index.getCode(), Collections.emptyList());
                if (!tagValueList.isEmpty()){
                    Optional<Double> sumOptional = tagValueList.stream()
                            .map(TagValue::getValue)
                            .reduce(Double::sum);
                    sumOptional.ifPresent(sum -> item.setValue(BigDecimal.valueOf(sum)
                            .setScale(2, RoundingMode.HALF_UP).doubleValue()));
                }
                return item;
            }).collect(Collectors.toList());
            return AjaxResult.success(resultList);
        } catch (Exception ex) {
            logger.error("获取关联采集指标出错!", ex);
            return AjaxResult.error("获取关联指标出错!");
        }
    }
}
zhitan-admin/src/main/java/com/zhitan/web/controller/statisticalAnalysis/StatisticalAnalysisController.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,129 @@
package com.zhitan.web.controller.statisticalAnalysis;
import com.zhitan.common.core.controller.BaseController;
import com.zhitan.common.core.domain.AjaxResult;
import com.zhitan.common.utils.poi.ExcelUtil;
import com.zhitan.statisticalAnalysis.domain.dto.DataAnalysisMoMDTO;
import com.zhitan.statisticalAnalysis.domain.vo.DataAnalysisMoMExcel;
import com.zhitan.statisticalAnalysis.domain.vo.DataAnalysisMoMVO;
import com.zhitan.statisticalAnalysis.domain.vo.DataAnalysisYoYExcel;
import com.zhitan.statisticalAnalysis.domain.vo.DataAnalysisYoYVO;
import com.zhitan.statisticalAnalysis.service.IStatisticalAnalysisService;
import io.swagger.annotations.ApiOperation;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.ArrayList;
import java.util.List;
/**
 * ç»Ÿè®¡åˆ†æž æŽ§åˆ¶å±‚
 */
@RestController
@RequestMapping("/statisticalAnalysis")
public class StatisticalAnalysisController extends BaseController {
    @Autowired
    private IStatisticalAnalysisService analysisService;
    @PostMapping("/getElectricDataComparisonYoY")
    @ApiOperation(value = "获取电能耗同比数据", notes = "获取电能耗同比数据")
    public AjaxResult listElectricDataComparisonYoY(@RequestBody @Validated DataAnalysisMoMDTO dto) {
        List<DataAnalysisYoYVO> yoyList = analysisService.listElectricDataComparisonYoY(dto);
        return AjaxResult.success(yoyList);
    }
    @PostMapping("/getElectricDataComparisonMoM")
    @ApiOperation(value = "获取电能耗环比数据", notes = "获取电能耗环比数据")
    public AjaxResult listElectricDataComparisonMoM(@RequestBody @Validated DataAnalysisMoMDTO dto) {
        List<DataAnalysisMoMVO> momList = analysisService.listElectricDataComparisonMoM(dto);
        return AjaxResult.success(momList);
    }
    @PostMapping("/getWaterDataComparisonYoY")
    @ApiOperation(value = "获取水能耗同比数据", notes = "获取水能耗同比数据")
    public AjaxResult listWaterDataComparisonYoY(@RequestBody @Validated DataAnalysisMoMDTO dto) {
        List<DataAnalysisYoYVO> yoyList = analysisService.listWaterDataComparisonYoY(dto);
        return AjaxResult.success(yoyList);
    }
    @PostMapping("/getWaterDataComparisonMoM")
    @ApiOperation(value = "获取水能耗环比数据", notes = "获取水能耗环比数据")
    public AjaxResult listWaterDataComparisonMoM(@RequestBody @Validated DataAnalysisMoMDTO dto) {
        List<DataAnalysisMoMVO> momList = analysisService.listWaterDataComparisonMoM(dto);
        return AjaxResult.success(momList);
    }
    @PostMapping("/exportElectricYoY")
    @ApiOperation(value = "导出电能耗同比数据", notes = "导出电能耗同比数据")
    public AjaxResult exportElectricComparisonYoY(@RequestBody @Validated DataAnalysisMoMDTO dto) {
        List<DataAnalysisYoYExcel> yoYExcelsList = new ArrayList<>();
        List<DataAnalysisYoYVO> yoYList = analysisService.listElectricDataComparisonYoY(dto);
        if (CollectionUtils.isNotEmpty(yoYList)) {
            for (DataAnalysisYoYVO vo : yoYList) {
                DataAnalysisYoYExcel excel = new DataAnalysisYoYExcel();
                BeanUtils.copyProperties(vo, excel);
                yoYExcelsList.add(excel);
            }
        }
        ExcelUtil<DataAnalysisYoYExcel> util = new ExcelUtil<>(DataAnalysisYoYExcel.class);
        return util.exportExcel(yoYExcelsList, "电综合能耗同比信息");
    }
//    @PostMapping("/exportElectricMoM")
//    @ApiOperation(value = "导出电能耗环比数据", notes = "导出电能耗环比数据")
//    public AjaxResult exportElectricComparisonMoM(@RequestBody @Validated DataAnalysisMoMDTO dto) {
//        List<DataAnalysisMoMExcel> moMExcelsList = new ArrayList<>();
//        List<DataAnalysisMoMVO> moMList = analysisService.listElectricDataComparisonMoM(dto);
//        if (CollectionUtils.isNotEmpty(moMList)) {
//            for (DataAnalysisMoMVO vo : moMList) {
//                DataAnalysisMoMExcel excel = new DataAnalysisMoMExcel();
//                BeanUtils.copyProperties(vo, excel);
//                moMExcelsList.add(excel);
//            }
//        }
//        ExcelUtil<DataAnalysisMoMExcel> util = new ExcelUtil<>(DataAnalysisMoMExcel.class);
//        return util.exportRealTimeDataExcel(moMExcelsList, "电综合能耗环比信息");
//    }
    @PostMapping("/exportWaterYoY")
    @ApiOperation(value = "导出水耗同比数据", notes = "导出水耗同比数据")
    public AjaxResult exportWaterComparisonYoY(@RequestBody @Validated DataAnalysisMoMDTO dto) {
        List<DataAnalysisYoYExcel> yoYExcelsList = new ArrayList<>();
        List<DataAnalysisYoYVO> yoYList = analysisService.listWaterDataComparisonYoY(dto);
        if (CollectionUtils.isNotEmpty(yoYList)) {
            for (DataAnalysisYoYVO vo : yoYList) {
                DataAnalysisYoYExcel excel = new DataAnalysisYoYExcel();
                BeanUtils.copyProperties(vo, excel);
                yoYExcelsList.add(excel);
            }
        }
        ExcelUtil<DataAnalysisYoYExcel> util = new ExcelUtil<>(DataAnalysisYoYExcel.class);
        return util.exportExcel(yoYExcelsList, "水综合能耗耗同比信息");
    }
    @PostMapping("/exportWaterMoM")
    @ApiOperation(value = "导出水耗环比数据", notes = "导出水耗环比数据")
    public AjaxResult exportWaterComparisonMoM(@RequestBody @Validated DataAnalysisMoMDTO dto) {
        List<DataAnalysisMoMExcel> moMExcelsList = new ArrayList<>();
        List<DataAnalysisMoMVO> moMList = analysisService.listWaterDataComparisonMoM(dto);
        if (CollectionUtils.isNotEmpty(moMList)) {
            for (DataAnalysisMoMVO vo : moMList) {
                DataAnalysisMoMExcel excel = new DataAnalysisMoMExcel();
                BeanUtils.copyProperties(vo, excel);
                moMExcelsList.add(excel);
            }
        }
        ExcelUtil<DataAnalysisMoMExcel> util = new ExcelUtil<>(DataAnalysisMoMExcel.class);
        return util.exportExcel(moMExcelsList, "水综合能耗耗环比信息");
    }
}
zhitan-common/src/main/java/com/zhitan/common/config/BaseConfig.java
@@ -119,4 +119,8 @@
    {
        return getProfile() + "/upload";
    }
    public static String getConfigurePath() {
        return getProfile() + "/configure";
    }
}
zhitan-common/src/main/java/com/zhitan/common/constant/TimeTypeConst.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,25 @@
package com.zhitan.common.constant;
/**
 * @Description: å‘¨æœŸç±»åž‹
 * @author: yxw
 * @date: 2022å¹´03月17日 12:33
 */
public class TimeTypeConst {
    /**
     * å‘¨æœŸç±»åž‹ - å°æ—¶
     */
    public static final String TIME_TYPE_HOUR="HOUR";
    /**
     * å‘¨æœŸç±»åž‹ - æ—¥
     */
    public static final String TIME_TYPE_DAY="DAY";
    /**
     * å‘¨æœŸç±»åž‹ - æœˆ
     */
    public static final String TIME_TYPE_MONTH="MONTH";
    /**
     * å‘¨æœŸç±»åž‹ - å¹´
     */
    public static final String TIME_TYPE_YEAR="YEAR";
}
zhitan-system/src/main/java/com/zhitan/basicSetup/mapper/SysEquipmentfileMapper.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,25 @@
package com.zhitan.basicSetup.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.zhitan.realtimedata.domain.SysEquipmentFile;
import com.zhitan.realtimedata.domain.SysSvgInfo;
import org.apache.ibatis.annotations.Param;
import java.util.List;
/**
 * ç»„态图Mapper接口
 *
 * @author sys
 * @date 2020-02-24
 */
public interface SysEquipmentfileMapper extends BaseMapper<SysEquipmentFile> {
  void saveEquipmentFile(SysEquipmentFile sysEquipmentfile);
  void saveSettingInfo(@Param("nodeId") String nodeId, @Param("svgInfo") List<SysSvgInfo> svgInfo);
  SysEquipmentFile getConfigure(String nodeId);
  List<SysSvgInfo> getConfigureTag(String nodeId);
}
zhitan-system/src/main/java/com/zhitan/basicSetup/service/ISysEquipmentfileService.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,33 @@
package com.zhitan.basicSetup.service;
import com.zhitan.realtimedata.domain.SysEquipmentFile;
import com.zhitan.realtimedata.domain.SysSvgInfo;
import java.util.List;
/**
 * ç»„态图Service接口
 *
 * @author sys
 * @date 2020-02-24
 */
public interface ISysEquipmentfileService {
  void saveEquipmentFile(SysEquipmentFile sysEquipmentfile);
  void saveSettingInfo(String nodeId, List<SysSvgInfo> svgInfo);
  /**
   * èŽ·å–ç»„æ€å›¾é…ç½®ä¿¡æ¯
   * @param nodeId æ¨¡åž‹èŠ‚ç‚¹ id
   * @return
   */
  SysEquipmentFile getConfigure(String nodeId);
  /**
   * èŽ·å–ç»„æ€å›¾é…ç½®çš„ç‚¹ä½å·
   * @param nodeId æ¨¡åž‹èŠ‚ç‚¹ id
   * @return
   */
  List<SysSvgInfo> getConfigureTag(String nodeId);
}
zhitan-system/src/main/java/com/zhitan/basicSetup/service/impl/SysEquipmentfileServiceImpl.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,59 @@
package com.zhitan.basicSetup.service.impl;
import com.zhitan.basicSetup.mapper.SysEquipmentfileMapper;
import com.zhitan.basicSetup.service.ISysEquipmentfileService;
import com.zhitan.realtimedata.domain.SysEquipmentFile;
import com.zhitan.realtimedata.domain.SysSvgInfo;
import org.apache.commons.lang3.ObjectUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;
/**
 * ç»„态图Service业务层处理
 *
 * @author sys
 * @date 2020-02-24
 */
@Service
public class SysEquipmentfileServiceImpl implements ISysEquipmentfileService {
  @Autowired
  private SysEquipmentfileMapper equipmentfileMapper;
  @Override
  public void saveEquipmentFile(SysEquipmentFile sysEquipmentfile) {
    SysEquipmentFile sysEquipmentFile = equipmentfileMapper.selectById(sysEquipmentfile.getNodeId());
    if (ObjectUtils.isNotEmpty(sysEquipmentFile)){
      sysEquipmentFile.setFilePath(sysEquipmentfile.getFilePath());
      equipmentfileMapper.updateById(sysEquipmentFile);
    }else {
      SysEquipmentFile equipmentFile = new SysEquipmentFile();
      equipmentFile.setFilePath(sysEquipmentfile.getFilePath());
      equipmentFile.setNodeId(sysEquipmentfile.getNodeId());
      equipmentfileMapper.insert(equipmentFile);
    }
  }
  @Override
  public void saveSettingInfo(String nodeId, List<SysSvgInfo> svgInfo) {
    equipmentfileMapper.saveSettingInfo(nodeId, svgInfo);
  }
  @Override
  public SysEquipmentFile getConfigure(String nodeId) {
    SysEquipmentFile sysEquipmentfile = equipmentfileMapper.getConfigure(nodeId);
    List<SysSvgInfo> infos = getConfigureTag(nodeId);
    if (sysEquipmentfile != null) {
      sysEquipmentfile.setInfoList(infos);
    }
    return sysEquipmentfile;
  }
  @Override
  public List<SysSvgInfo> getConfigureTag(String nodeId) {
    return equipmentfileMapper.getConfigureTag(nodeId);
  }
}
zhitan-system/src/main/java/com/zhitan/consumptionanalysis/service/impl/ConsumptionAnalysisServiceImpl.java
@@ -44,20 +44,20 @@
    private final ModelNodeMapper modelNodeMapper;
    private final EnergyIndicatorsMapper energyIndicatorsMapper;
    private final ProductOutputMapper productOutputMapper;
    private final SysEnergyMapper sysEnergyMapper;
    private final IDataItemService dataItemService;
    private final IModelNodeService modelNodeService;
    @Override
    public ConsumptionAnalysisVO getByArea(ConsumptionAnalysisDTO dto) {
        List<ConsumptionAnalysisData> dataList = new ArrayList<>();
        List<ChartData> chartDataList = new ArrayList<>();
        ConsumptionAnalysisVO consumptionAnalysisVO = new ConsumptionAnalysisVO();
        final String analysisType = dto.getAnalysisType();
        final String nodeId = dto.getNodeId();
@@ -67,7 +67,7 @@
        /**
         * æŸ¥è¯¢ç‚¹ä½ä¸Žç”¨èƒ½å•元信息
         */
        List<ModelNodeIndexInfor> nodeIndexInforList = modelNodeMapper.getModelNodeIndexIdByNodeId(nodeId,energyType);
        List<ModelNodeIndexInfor> nodeIndexInforList = modelNodeMapper.getModelNodeIndexIdByNodeId(nodeId, energyType);
//        if (CollectionUtils.isEmpty(nodeIndexInforList)) {
//            return consumptionAnalysisVO;
@@ -88,7 +88,7 @@
                //同比分析,时间取去年的
                lastTime = DateUtil.offsetMonth(beginTime, -12);
                lastEndTime = DateUtil.offsetMonth(endTime, -12);
            }else {
            } else {
                //环比分析,时间取 æ˜¨å¤©
                lastTime = DateUtil.offsetDay(beginTime, -1);
                lastEndTime = DateUtil.offsetDay(endTime, -1);
@@ -103,7 +103,7 @@
                //同比分析,时间取去年的
                lastTime = DateUtil.offsetMonth(beginTime, -12);
                lastEndTime = DateUtil.offsetMonth(endTime, -12);
            }else {
            } else {
                //环比分析,时间取 æ˜¨å¤©
                lastTime = DateUtil.offsetMonth(beginTime, -1);
                lastEndTime = DateUtil.offsetMonth(endTime, -1);
@@ -118,18 +118,18 @@
                //同比分析,时间取去年的
                lastTime = DateUtil.offsetMonth(beginTime, -12);
                lastEndTime = DateUtil.offsetMonth(endTime, -12);
            }else {
            } else {
                //环比分析,时间取 æ˜¨å¤©
                lastTime = DateUtil.offsetMonth(beginTime,  -1);
                lastEndTime = DateUtil.offsetMonth(endTime,  -1);
                lastTime = DateUtil.offsetMonth(beginTime, -1);
                lastEndTime = DateUtil.offsetMonth(endTime, -1);
            }
            timeFormat = "yyyy-MM";
        }
        // æ ¹æ®indexId查询dataItem
        List<DataItem> dataItemList = new ArrayList<>();
        List<DataItem> lastDataItemList = new ArrayList<>();
        if(CollectionUtils.isNotEmpty(indexIds)) {
        if (CollectionUtils.isNotEmpty(indexIds)) {
            dataItemList = dataItemService.getDataItemTimeRangeInforByIndexIds(beginTime, endTime, shixuTimeType, indexIds);
            lastDataItemList = dataItemService.getDataItemTimeRangeInforByIndexIds(lastTime, lastEndTime, shixuTimeType, indexIds);
        }
@@ -144,11 +144,11 @@
            final String compareTime;
            DateTime dateTime;
            if (TimeType.DAY.name().equals(queryTimeType)) {
                if ("YOY".equals(analysisType)) {
                    //同比分析,时间取去年的
                    dateTime = DateUtil.offsetMonth(beginTime, -12);
                }else {
                } else {
                    //环比分析,时间取 æ˜¨å¤©
                    dateTime = DateUtil.offsetDay(beginTime, -1);
                }
@@ -158,7 +158,7 @@
                if ("YOY".equals(analysisType)) {
                    //同比分析,时间取去年的
                    dateTime = DateUtil.offsetMonth(beginTime, -12);
                }else {
                } else {
                    //环比分析,时间取 æ˜¨å¤©
                    dateTime = DateUtil.offsetMonth(beginTime, -1);
                }
@@ -168,25 +168,25 @@
                if ("YOY".equals(analysisType)) {
                    //同比分析,时间取去年的
                    dateTime = DateUtil.offsetMonth(beginTime, -12);
                }else {
                } else {
                    //环比分析,时间取 æ˜¨å¤©
                    dateTime = DateUtil.offsetMonth(beginTime,  -1);
                    dateTime = DateUtil.offsetMonth(beginTime, -1);
                }
                compareTime = DateUtil.format(dateTime, timeFormat);
            }
            final List<DataItem> dataItems = dataItemMap.get(currentTime);
            final List<DataItem> lastDataItems = lastDataItemMap.get(compareTime);
            BigDecimal sum = new BigDecimal(0);
            BigDecimal lastSum = new BigDecimal(0);
            if (CollectionUtils.isNotEmpty(dataItems)) {
                 // æ±‚å’Œ
                 sum = BigDecimal.valueOf(dataItems.stream()
                // æ±‚å’Œ
                sum = BigDecimal.valueOf(dataItems.stream()
                        .mapToDouble(DataItem::getValue).sum()).setScale(CommonConst.DIGIT_2, RoundingMode.HALF_UP);
            }
            if(CollectionUtils.isNotEmpty(lastDataItems)) {
            if (CollectionUtils.isNotEmpty(lastDataItems)) {
                lastSum = BigDecimal.valueOf(lastDataItems.stream()
                        .mapToDouble(DataItem::getValue).sum()).setScale(CommonConst.DIGIT_2, RoundingMode.HALF_UP);
            }
@@ -194,7 +194,7 @@
            data.setCompareValue(lastSum.doubleValue());
            data.setCurrentTime(currentTime);
            data.setCompareTime(compareTime);
            if ("YOY".equals(analysisType)) {
                //同比分析
@@ -238,7 +238,7 @@
            chartDataList.add(chartData);
        });
        consumptionAnalysisVO.setDataList(dataList);
        consumptionAnalysisVO.setChartDataList(chartDataList);
        return consumptionAnalysisVO;
@@ -252,32 +252,32 @@
        String queryTimeType = dto.getTimeType();
        // åˆ›å»ºä¸€ä¸ªMap来存储总和
        Map<String, BigDecimal> result = new HashMap<>();
        //根据模型名称查询modelCode
        final String parentId = dto.getNodeId();
        //根据总结点查询
        final List<ModelNodeIndexInfor> nodeIndexInforList = modelNodeMapper.getModelNodeByParentId(parentId);
        final List<String> eneryIdList = nodeIndexInforList.stream().map(ModelNodeIndexInfor::getEnergyId).distinct().collect(Collectors.toList());
        final LambdaQueryWrapper<SysEnergy> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.in(CollectionUtils.isNotEmpty(eneryIdList),SysEnergy::getEnersno,eneryIdList);
        queryWrapper.in(CollectionUtils.isNotEmpty(eneryIdList), SysEnergy::getEnersno, eneryIdList);
        final List<SysEnergy> sysEnergies = sysEnergyMapper.selectList(queryWrapper);
        final Map<String, String> energyNameMap = sysEnergies.stream().collect(Collectors.toMap(SysEnergy::getEnersno, SysEnergy::getEnername));
        final Map<String, String> nodeNameMap = new HashMap<>();
        nodeIndexInforList.forEach(n->{
        nodeIndexInforList.forEach(n -> {
            final String nodeId = n.getNodeId();
            final String name = n.getName();
            if(!nodeNameMap.containsKey(nodeId)){
                nodeNameMap.put(nodeId,name);
            if (!nodeNameMap.containsKey(nodeId)) {
                nodeNameMap.put(nodeId, name);
            }
        });
        // æŒ‰ç…§ç‚¹ä½è¿›è¡Œåˆ†ç»„
        Map<String, List<ModelNodeIndexInfor>> nodeIndexMap = nodeIndexInforList.stream().collect(
                Collectors.groupingBy(ModelNodeIndexInfor::getNodeId));
        // æ ¹æ®nodeId获取能源类型
        // æ‰€æœ‰ç‚¹ä½ä¿¡æ¯
        List<String> indexIds = nodeIndexInforList.stream().map(ModelNodeIndexInfor::getIndexId).distinct().collect(Collectors.toList());
@@ -300,27 +300,26 @@
            endTime = DateUtil.endOfYear(queryTime);
            shixuTimeType = TimeType.MONTH.name();
        }
        // æ ¹æ®indexId查询dataItem
        List<DataItem> dataItemList = new ArrayList<>();
        if(CollectionUtils.isNotEmpty(indexIds)) {
        if (CollectionUtils.isNotEmpty(indexIds)) {
            dataItemList = dataItemService.getDataItemTimeRangeInforByIndexIds(beginTime, endTime, shixuTimeType, indexIds);
        }
        final Map<String, List<DataItem>> dataItemMap = dataItemList.stream().collect(Collectors.groupingBy(DataItem::getIndexId));
        // æ ¹æ®ç‚¹ä½åˆ†ç»„,求和
        Map<String,BigDecimal> dataItemTotalMap = new HashMap<>();
        dataItemMap.forEach((key,value)->{
        Map<String, BigDecimal> dataItemTotalMap = new HashMap<>();
        dataItemMap.forEach((key, value) -> {
            BigDecimal sum = BigDecimal.valueOf(value.stream()
                    .mapToDouble(DataItem::getValue).sum()).setScale(CommonConst.DIGIT_2, RoundingMode.HALF_UP);
            dataItemTotalMap.put(key,sum);
            dataItemTotalMap.put(key, sum);
        });
        nodeIndexMap.forEach((nodeId,indexList)->{
            indexList.forEach(index->{
        nodeIndexMap.forEach((nodeId, indexList) -> {
            indexList.forEach(index -> {
                final String energyId = index.getEnergyId();
                final String indexId = index.getIndexId();
                final BigDecimal total = dataItemTotalMap.getOrDefault(indexId, BigDecimal.ZERO);
@@ -337,15 +336,15 @@
            String energyId = keys[1];
            BigDecimal totalEnergy = entry.getValue();
            chartData.setEnergyTypeNo(energyId);
            chartData.setEnergyTypeName(energyNameMap.getOrDefault(energyId,""));
            chartData.setNodeName(nodeNameMap.getOrDefault(nodeId,""));
            chartData.setEnergyTypeName(energyNameMap.getOrDefault(energyId, ""));
            chartData.setNodeName(nodeNameMap.getOrDefault(nodeId, ""));
            chartData.setEnergyConsumption(totalEnergy.doubleValue());
            chartData.setNodeId(nodeId);
            rankingEnergyData.add(chartData);
        }
        final Map<String, List<RankingEnergyData>> collect = rankingEnergyData.stream().collect(Collectors.groupingBy(RankingEnergyData::getNodeId));
        nodeNameMap.forEach((key,value)->{
        nodeNameMap.forEach((key, value) -> {
            final List<RankingEnergyData> rankingEnergyData1 = collect.get(key);
            RankingDataVO rankingDataVO = new RankingDataVO();
            rankingDataVO.setNodeId(key);
@@ -353,7 +352,7 @@
            rankingDataVO.setData(rankingEnergyData1);
            rankingDataVOArrayList.add(rankingDataVO);
        });
        return rankingDataVOArrayList;
    }
@@ -382,7 +381,7 @@
        List<EnergyProportion> energyProportionList = new ArrayList<>();
        ConsumptionAnalysisVO consumptionAnalysisVO = new ConsumptionAnalysisVO();
        //todo hmj ç»¼åˆèƒ½è€—先默认取同比
        final String analysisType = "YOY";
        final String nodeId = dto.getNodeId();
@@ -392,24 +391,25 @@
        /**
         * æŸ¥è¯¢ç‚¹ä½ä¸Žç”¨èƒ½å•元信息
         */
        List<ModelNodeIndexInfor> nodeIndexInforList = modelNodeMapper.getModelNodeIndexIdByNodeId(nodeId,energyType);
        List<ModelNodeIndexInfor> nodeIndexInforList = modelNodeMapper.getModelNodeIndexIdByNodeId(nodeId, energyType);
//        if (CollectionUtils.isEmpty(nodeIndexInforList)) {
//            return consumptionAnalysisVO;
//        }
        //修改过滤统计点位
        nodeIndexInforList = nodeIndexInforList.stream().filter(x -> "STATISTIC".equals(x.getIndexType())).collect(Collectors.toList());
        final List<String> eneryIdList = nodeIndexInforList.stream().map(ModelNodeIndexInfor::getEnergyId).distinct().collect(Collectors.toList());
        final LambdaQueryWrapper<SysEnergy> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.in(CollectionUtils.isNotEmpty(eneryIdList),SysEnergy::getEnersno,eneryIdList);
        queryWrapper.in(CollectionUtils.isNotEmpty(eneryIdList), SysEnergy::getEnersno, eneryIdList);
        final List<SysEnergy> sysEnergies = sysEnergyMapper.selectList(queryWrapper);
        final Map<String, BigDecimal> energyCoefficientMap = sysEnergies.stream().collect(Collectors.toMap(SysEnergy::getEnersno, SysEnergy::getCoefficient));
        final Map<String, String> energyNameMap = sysEnergies.stream().collect(Collectors.toMap(SysEnergy::getEnersno,SysEnergy::getEnername));
        final Map<String, String> energyNameMap = sysEnergies.stream().collect(Collectors.toMap(SysEnergy::getEnersno, SysEnergy::getEnername));
        final Map<String, String> indexIdEnergyIdMap = new HashMap<>();
        nodeIndexInforList.forEach(n->{
        nodeIndexInforList.forEach(n -> {
            final String indexId = n.getIndexId();
            final String energyId = n.getEnergyId();
            if(!indexIdEnergyIdMap.containsKey(indexId)){
                indexIdEnergyIdMap.put(indexId,energyId);
            if (!indexIdEnergyIdMap.containsKey(indexId)) {
                indexIdEnergyIdMap.put(indexId, energyId);
            }
        });
        List<String> indexIds = nodeIndexInforList.stream().map(ModelNodeIndexInfor::getIndexId).collect(Collectors.toList());
@@ -428,7 +428,7 @@
                //同比分析,时间取去年的
                lastTime = DateUtil.offsetMonth(beginTime, -12);
                lastEndTime = DateUtil.offsetMonth(endTime, -12);
            }else {
            } else {
                //环比分析,时间取 æ˜¨å¤©
                lastTime = DateUtil.offsetDay(beginTime, -1);
                lastEndTime = DateUtil.offsetDay(endTime, -1);
@@ -443,7 +443,7 @@
                //同比分析,时间取去年的
                lastTime = DateUtil.offsetMonth(beginTime, -12);
                lastEndTime = DateUtil.offsetMonth(endTime, -12);
            }else {
            } else {
                //环比分析,时间取 æ˜¨å¤©
                lastTime = DateUtil.offsetMonth(beginTime, -1);
                lastEndTime = DateUtil.offsetMonth(endTime, -1);
@@ -458,10 +458,10 @@
                //同比分析,时间取去年的
                lastTime = DateUtil.offsetMonth(beginTime, -12);
                lastEndTime = DateUtil.offsetMonth(endTime, -12);
            }else {
            } else {
                //环比分析,时间取 æ˜¨å¤©
                lastTime = DateUtil.offsetMonth(beginTime,  -1);
                lastEndTime = DateUtil.offsetMonth(endTime,  -1);
                lastTime = DateUtil.offsetMonth(beginTime, -1);
                lastEndTime = DateUtil.offsetMonth(endTime, -1);
            }
            timeFormat = "yyyy-MM";
@@ -469,7 +469,7 @@
        // æ ¹æ®indexId查询dataItem
        List<DataItem> dataItemList = new ArrayList<>();
        List<DataItem> lastDataItemList = new ArrayList<>();
        if(CollectionUtils.isNotEmpty(indexIds)) {
        if (CollectionUtils.isNotEmpty(indexIds)) {
            dataItemList = dataItemService.getDataItemTimeRangeInforByIndexIds(beginTime, endTime, shixuTimeType, indexIds);
            lastDataItemList = dataItemService.getDataItemTimeRangeInforByIndexIds(lastTime, lastEndTime, shixuTimeType, indexIds);
        }
@@ -478,7 +478,7 @@
        //  å€çއ
        BigDecimal multiple = BigDecimal.valueOf(CommonConst.DIGIT_100);
        Map<String,Double> energyProportionMap = new HashMap<>();
        Map<String, Double> energyProportionMap = new HashMap<>();
        while (!beginTime.after(endTime)) {
            ConsumptionAnalysisData data = new ConsumptionAnalysisData();
            final String currentTime = DateUtil.format(beginTime, timeFormat);
@@ -489,7 +489,7 @@
                if ("YOY".equals(analysisType)) {
                    //同比分析,时间取去年的
                    dateTime = DateUtil.offsetMonth(beginTime, -12);
                }else {
                } else {
                    //环比分析,时间取 æ˜¨å¤©
                    dateTime = DateUtil.offsetDay(beginTime, -1);
                }
@@ -499,7 +499,7 @@
                if ("YOY".equals(analysisType)) {
                    //同比分析,时间取去年的
                    dateTime = DateUtil.offsetMonth(beginTime, -12);
                }else {
                } else {
                    //环比分析,时间取 æ˜¨å¤©
                    dateTime = DateUtil.offsetMonth(beginTime, -1);
                }
@@ -509,9 +509,9 @@
                if ("YOY".equals(analysisType)) {
                    //同比分析,时间取去年的
                    dateTime = DateUtil.offsetMonth(beginTime, -12);
                }else {
                } else {
                    //环比分析,时间取 æ˜¨å¤©
                    dateTime = DateUtil.offsetMonth(beginTime,  -1);
                    dateTime = DateUtil.offsetMonth(beginTime, -1);
                }
                compareTime = DateUtil.format(dateTime, timeFormat);
            }
@@ -523,38 +523,40 @@
            BigDecimal lastSum = new BigDecimal(0);
            if (CollectionUtils.isNotEmpty(dataItems)) {
                // æ±‚å’Œ
                for (int i=0;i<dataItems.size(); i++){
                for (int i = 0; i < dataItems.size(); i++) {
                    final DataItem dataItem = dataItems.get(i);
                    final String indexId = dataItem.getIndexId();
                    final String energyId = indexIdEnergyIdMap.get(indexId);
                    final BigDecimal coefficient = energyCoefficientMap.get(energyId);
                    if(coefficient == null){
                    if (coefficient == null) {
                        throw new RuntimeException("能源类型" + energyId + "没有配置折标系数,无法计算");
                    }
                    sum = sum.add(new BigDecimal(dataItem.getValue()).multiply(coefficient)).setScale(2, RoundingMode.HALF_UP);;
                    sum = sum.add(new BigDecimal(dataItem.getValue()).multiply(coefficient)).setScale(2, RoundingMode.HALF_UP);
                    ;
//                    if(energyProportionMap.containsKey(energyId)) {
//                        energyProportionMap.put(energyId,energyProportionMap.get(energyId) + sum.doubleValue());
//                    }else {
//                        energyProportionMap.put(energyId, sum.doubleValue());
//                    }
                }
            }
            if(CollectionUtils.isNotEmpty(lastDataItems)) {
                for (int i=0;i<lastDataItems.size(); i++){
            if (CollectionUtils.isNotEmpty(lastDataItems)) {
                for (int i = 0; i < lastDataItems.size(); i++) {
                    final DataItem dataItem = lastDataItems.get(i);
                    final String indexId = dataItem.getIndexId();
                    final String energyId = indexIdEnergyIdMap.get(indexId);
                    final BigDecimal coefficient = energyCoefficientMap.get(energyId);
                    if(coefficient == null){
                    if (coefficient == null) {
                        throw new RuntimeException("能源类型" + energyId + "没有配置折标系数,无法计算");
                    }
                    lastSum = lastSum.add(new BigDecimal(dataItem.getValue()).multiply(coefficient)).setScale(2, RoundingMode.HALF_UP);;
                    lastSum = lastSum.add(new BigDecimal(dataItem.getValue()).multiply(coefficient)).setScale(2, RoundingMode.HALF_UP);
                    ;
                }
            }
            data.setCurrentValue(sum.doubleValue());
@@ -605,34 +607,34 @@
            chartDataList.add(chartData);
        });
        Double eneryTotal =  energyProportionMap.values().stream().mapToDouble(Double::doubleValue).sum();
        Double eneryTotal = energyProportionMap.values().stream().mapToDouble(Double::doubleValue).sum();
        Map<String, List<DataItem>> indexDataItemMap = dataItemList.stream().collect(Collectors.groupingBy(DataItem::getIndexId));
        indexDataItemMap.forEach((indexId,value)->{
        indexDataItemMap.forEach((indexId, value) -> {
            final String energyId = indexIdEnergyIdMap.get(indexId);
            final BigDecimal coefficient = energyCoefficientMap.get(energyId);
            if(coefficient == null){
            if (coefficient == null) {
                throw new RuntimeException("能源类型" + energyId + "没有配置折标系数,无法计算");
            }
            final double sum = value.stream().map(DataItem::getValue).mapToDouble(Double::doubleValue).sum();
            if(energyProportionMap.containsKey(energyId)) {
                energyProportionMap.put(energyId,energyProportionMap.get(energyId) + sum * coefficient.doubleValue());
            }else {
            if (energyProportionMap.containsKey(energyId)) {
                energyProportionMap.put(energyId, energyProportionMap.get(energyId) + sum * coefficient.doubleValue());
            } else {
                energyProportionMap.put(energyId, sum * coefficient.doubleValue());
            }
        });
        energyProportionMap.forEach((key,value)->{
        energyProportionMap.forEach((key, value) -> {
            EnergyProportion energyProportion = new EnergyProportion();
            energyProportion.setEnergyNo(key);
            energyProportion.setEnergyName(energyNameMap.getOrDefault(key,""));
            energyProportion.setEnergyName(energyNameMap.getOrDefault(key, ""));
            energyProportion.setCount(value);
            energyProportion.setPercentage(value/eneryTotal * 100);
            energyProportion.setPercentage(value / eneryTotal * 100);
            energyProportionList.add(energyProportion);
        });
@@ -660,50 +662,50 @@
        } else {
            timeFormat = "yyyy";
        }
        final Double currTotalEnergy = getTotalEnergy(dto);
        DateTime tongbiTime = DateUtil.offsetMonth(queryTime, -12);
        dto.setDataTime(tongbiTime);
        final Double tongbiTotalEnergy = getTotalEnergy(dto);
        DateTime huanbiTime = DateUtil.offsetMonth(queryTime, -1);
        dto.setDataTime(huanbiTime);
        final Double huanbiTotalEnergy = getTotalEnergy(dto);
        tongbi.setCurrentTime(DateUtil.format(queryTime,timeFormat));
        tongbi.setCompareTime(DateUtil.format(tongbiTime,timeFormat));
        tongbi.setCurrentTime(DateUtil.format(queryTime, timeFormat));
        tongbi.setCompareTime(DateUtil.format(tongbiTime, timeFormat));
        tongbi.setCurrentValue(currTotalEnergy);
        tongbi.setCompareValue(tongbiTotalEnergy);
        if(tongbiTotalEnergy != 0) {
        if (tongbiTotalEnergy != 0) {
            final double tongbiRatio = (currTotalEnergy - tongbiTotalEnergy) / tongbiTotalEnergy * 100;
            BigDecimal bd = new BigDecimal(tongbiRatio);
            bd = bd.setScale(2, RoundingMode.HALF_UP);
            tongbi.setRatio(bd.doubleValue());
        }else {
        } else {
            tongbi.setRatio(0);
        }
        huanbi.setCurrentTime(DateUtil.format(queryTime,timeFormat));
        huanbi.setCompareTime(DateUtil.format(huanbiTime,timeFormat));
        huanbi.setCurrentTime(DateUtil.format(queryTime, timeFormat));
        huanbi.setCompareTime(DateUtil.format(huanbiTime, timeFormat));
        huanbi.setCompareValue(huanbiTotalEnergy);
        huanbi.setCurrentValue(currTotalEnergy);
        if(huanbiTotalEnergy != 0) {
        if (huanbiTotalEnergy != 0) {
            final double huanbiRatio = (currTotalEnergy - huanbiTotalEnergy) / huanbiTotalEnergy * 100;
            BigDecimal bd = new BigDecimal(huanbiRatio);
            bd = bd.setScale(2, RoundingMode.HALF_UP);
            huanbi.setRatio(bd.doubleValue());
        }else {
        } else {
            huanbi.setRatio(0);
        }
        consumptionAnalysisVO.setTongbi(tongbi);
        consumptionAnalysisVO.setHuanbi(huanbi);
        return consumptionAnalysisVO;
    }
    public Double getTotalEnergy(ConsumptionAnalysisDTO dto){
    public Double getTotalEnergy(ConsumptionAnalysisDTO dto) {
        //todo hmj ç»¼åˆèƒ½è€—先默认取同比
        final String nodeId = dto.getNodeId();
        final String energyType = dto.getEnergyType();
@@ -712,23 +714,23 @@
        /**
         * æŸ¥è¯¢ç‚¹ä½ä¸Žç”¨èƒ½å•元信息
         */
        List<ModelNodeIndexInfor> nodeIndexInforList = modelNodeMapper.getModelNodeIndexIdByNodeId(nodeId,energyType);
        List<ModelNodeIndexInfor> nodeIndexInforList = modelNodeMapper.getModelNodeIndexIdByNodeId(nodeId, energyType);
//        if (CollectionUtils.isEmpty(nodeIndexInforList)) {
//            return consumptionAnalysisVO;
//        }
        nodeIndexInforList = nodeIndexInforList.stream().filter(x -> "STATISTIC".equals(x.getIndexType())).collect(Collectors.toList());
        final List<String> eneryIdList = nodeIndexInforList.stream().map(ModelNodeIndexInfor::getEnergyId).distinct().collect(Collectors.toList());
        final LambdaQueryWrapper<SysEnergy> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.in(CollectionUtils.isNotEmpty(eneryIdList),SysEnergy::getEnersno,eneryIdList);
        queryWrapper.in(CollectionUtils.isNotEmpty(eneryIdList), SysEnergy::getEnersno, eneryIdList);
        final List<SysEnergy> sysEnergies = sysEnergyMapper.selectList(queryWrapper);
        final Map<String, BigDecimal> energyCoefficientMap = sysEnergies.stream().collect(Collectors.toMap(SysEnergy::getEnersno, SysEnergy::getCoefficient));
        final Map<String, String> indexIdEnergyIdMap = new HashMap<>();
        nodeIndexInforList.forEach(n->{
        nodeIndexInforList.forEach(n -> {
            final String indexId = n.getIndexId();
            final String energyId = n.getEnergyId();
            if(!indexIdEnergyIdMap.containsKey(indexId)){
                indexIdEnergyIdMap.put(indexId,energyId);
            if (!indexIdEnergyIdMap.containsKey(indexId)) {
                indexIdEnergyIdMap.put(indexId, energyId);
            }
        });
        List<String> indexIds = nodeIndexInforList.stream().map(ModelNodeIndexInfor::getIndexId).collect(Collectors.toList());
@@ -757,12 +759,12 @@
        }
        // æ ¹æ®indexId查询dataItem
        List<DataItem> dataItemList = new ArrayList<>();
        if(CollectionUtils.isNotEmpty(indexIds)) {
        if (CollectionUtils.isNotEmpty(indexIds)) {
            dataItemList = dataItemService.getDataItemTimeRangeInforByIndexIds(beginTime, endTime, shixuTimeType, indexIds);
        }
        Map<String, List<DataItem>> dataItemMap = dataItemList.stream().collect(Collectors.groupingBy(li -> DateUtil.format(li.getDataTime(), timeFormat)));
        Map<String,Double> energyProportionMap = new HashMap<>();
        Map<String, Double> energyProportionMap = new HashMap<>();
        while (!beginTime.after(endTime)) {
            final String currentTime = DateUtil.format(beginTime, timeFormat);
@@ -770,17 +772,18 @@
            BigDecimal sum = new BigDecimal(0);
            if (CollectionUtils.isNotEmpty(dataItems)) {
                // æ±‚å’Œ
                for (int i=0;i<dataItems.size(); i++){
                for (int i = 0; i < dataItems.size(); i++) {
                    final DataItem dataItem = dataItems.get(i);
                    final String indexId = dataItem.getIndexId();
                    final String energyId = indexIdEnergyIdMap.get(indexId);
                    final BigDecimal coefficient = energyCoefficientMap.get(energyId);
                    if(coefficient == null){
                    if (coefficient == null) {
                        throw new RuntimeException("能源类型" + energyId + "没有配置折标系数,无法计算");
                    }
                    sum = sum.add(new BigDecimal(dataItem.getValue()).multiply(coefficient)).setScale(2, RoundingMode.HALF_UP);;
                    sum = sum.add(new BigDecimal(dataItem.getValue()).multiply(coefficient)).setScale(2, RoundingMode.HALF_UP);
                    ;
//                    if(energyProportionMap.containsKey(energyId)) {
//                        energyProportionMap.put(energyId,energyProportionMap.get(energyId) + sum.doubleValue());
//                    }else {
@@ -804,26 +807,24 @@
        }
        Map<String, List<DataItem>> indexDataItemMap = dataItemList.stream().collect(Collectors.groupingBy(DataItem::getIndexId));
        indexDataItemMap.forEach((indexId,value)->{
        indexDataItemMap.forEach((indexId, value) -> {
            final String energyId = indexIdEnergyIdMap.get(indexId);
            final BigDecimal coefficient = energyCoefficientMap.get(energyId);
            if(coefficient == null){
            if (coefficient == null) {
                throw new RuntimeException("能源类型" + energyId + "没有配置折标系数,无法计算");
            }
            final double sum = value.stream().map(DataItem::getValue).mapToDouble(Double::doubleValue).sum();
            if(energyProportionMap.containsKey(energyId)) {
                energyProportionMap.put(energyId,energyProportionMap.get(energyId) + sum * coefficient.doubleValue());
            }else {
            if (energyProportionMap.containsKey(energyId)) {
                energyProportionMap.put(energyId, energyProportionMap.get(energyId) + sum * coefficient.doubleValue());
            } else {
                energyProportionMap.put(energyId, sum * coefficient.doubleValue());
            }
        });
        Double eneryTotal =  energyProportionMap.values().stream().mapToDouble(Double::doubleValue).sum();
        Double eneryTotal = energyProportionMap.values().stream().mapToDouble(Double::doubleValue).sum();
        return eneryTotal.doubleValue();
    }
@@ -839,11 +840,11 @@
         */
        List<ModelNodeIndexInfor> nodeIndexInforList = modelNodeMapper.getModelNodeByParentId(nodeId);
        final Map<String, String> nodeNameMap = new HashMap<>();
        nodeIndexInforList.forEach(n->{
        nodeIndexInforList.forEach(n -> {
            final String id = n.getNodeId();
            final String name = n.getName();
            if(!nodeNameMap.containsKey(id)){
                nodeNameMap.put(id,name);
            if (!nodeNameMap.containsKey(id)) {
                nodeNameMap.put(id, name);
            }
        });
        // æŒ‰ç…§ç‚¹ä½è¿›è¡Œåˆ†ç»„
@@ -851,17 +852,17 @@
                Collectors.groupingBy(ModelNodeIndexInfor::getNodeId));
        final List<String> eneryIdList = nodeIndexInforList.stream().map(ModelNodeIndexInfor::getEnergyId).distinct().collect(Collectors.toList());
        final LambdaQueryWrapper<SysEnergy> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.in(CollectionUtils.isNotEmpty(eneryIdList),SysEnergy::getEnersno,eneryIdList);
        queryWrapper.in(CollectionUtils.isNotEmpty(eneryIdList), SysEnergy::getEnersno, eneryIdList);
        final List<SysEnergy> sysEnergies = sysEnergyMapper.selectList(queryWrapper);
        //能源编号和能源折标系数
        final Map<String, BigDecimal> energyCoefficientMap = sysEnergies.stream().collect(Collectors.toMap(SysEnergy::getEnersno, SysEnergy::getCoefficient));
        //index和能源
        final Map<String, String> indexIdEnergyIdMap = new HashMap<>();
        nodeIndexInforList.forEach(n->{
        nodeIndexInforList.forEach(n -> {
            final String indexId = n.getIndexId();
            final String energyId = n.getEnergyId();
            if(!indexIdEnergyIdMap.containsKey(indexId)){
                indexIdEnergyIdMap.put(indexId,energyId);
            if (!indexIdEnergyIdMap.containsKey(indexId)) {
                indexIdEnergyIdMap.put(indexId, energyId);
            }
        });
        List<String> indexIds = nodeIndexInforList.stream().map(ModelNodeIndexInfor::getIndexId).collect(Collectors.toList());
@@ -886,22 +887,22 @@
        }
        // æ ¹æ®indexId查询dataItem
        List<DataItem> dataItemList = new ArrayList<>();
        if(CollectionUtils.isNotEmpty(indexIds)) {
        if (CollectionUtils.isNotEmpty(indexIds)) {
            dataItemList = dataItemService.getDataItemTimeRangeInforByIndexIds(beginTime, endTime, shixuTimeType, indexIds);
        }
        Map<String, List<DataItem>> dataItemMap = dataItemList.stream().collect(Collectors.groupingBy(DataItem::getIndexId));
        Map<String,BigDecimal> resultMap = new HashMap<>();
        Map<String, BigDecimal> resultMap = new HashMap<>();
        nodeIndexMap.forEach((key, value) -> {
            // æ‰¾å‡ºindexIds
            List<String> indexIdList = value.stream().map(ModelNodeIndexInfor::getIndexId).collect(Collectors.toList());
            indexIdList.forEach(indexId->{
            indexIdList.forEach(indexId -> {
                final List<DataItem> dataItems = dataItemMap.get(indexId);
                final String energyId = indexIdEnergyIdMap.get(indexId);
                final BigDecimal coefficient = energyCoefficientMap.get(energyId);
                if(CollectionUtils.isNotEmpty(dataItems) ){
                if (CollectionUtils.isNotEmpty(dataItems)) {
                    BigDecimal sum = BigDecimal.valueOf(dataItems.stream()
                            .mapToDouble(DataItem::getValue).sum()).setScale(CommonConst.DIGIT_2, RoundingMode.HALF_UP).multiply(coefficient);
@@ -914,7 +915,7 @@
            });
        });
        resultMap.forEach((key,value)->{
        resultMap.forEach((key, value) -> {
            RankingEnergyData rankingEnergyData = new RankingEnergyData();
            rankingEnergyData.setNodeId(key);
            rankingEnergyData.setNodeName(nodeNameMap.get(key));
@@ -950,30 +951,30 @@
        }
        LambdaQueryWrapper<EnergyIndicators> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(EnergyIndicators::getTimeType,queryTimeType);
        queryWrapper.eq(EnergyIndicators::getDataTime,DateUtil.format(dto.getDataTime(),timeFormat));
        queryWrapper.eq(EnergyIndicators::getNodeId,dto.getNodeId());
        queryWrapper.eq(EnergyIndicators::getEnergyType,dto.getEnergyType());
        queryWrapper.eq(EnergyIndicators::getTimeType, queryTimeType);
        queryWrapper.eq(EnergyIndicators::getDataTime, DateUtil.format(dto.getDataTime(), timeFormat));
        queryWrapper.eq(EnergyIndicators::getNodeId, dto.getNodeId());
        queryWrapper.eq(EnergyIndicators::getEnergyType, dto.getEnergyType());
        // 0 æ˜¯è®¡åˆ’量
        queryWrapper.eq(EnergyIndicators::getIndicatorsType,"0");
        queryWrapper.eq(EnergyIndicators::getIndicatorsType, "0");
        final EnergyIndicators plan = energyIndicatorsMapper.selectOne(queryWrapper);
        if(null != plan && null!= plan.getNumber()) {
        if (null != plan && null != plan.getNumber()) {
            consumptionAnalysisVO.setPlanCount(plan.getNumber().divide(new BigDecimal(between), CommonConst.DIGIT_2, RoundingMode.HALF_UP).doubleValue());
        }else {
        } else {
            consumptionAnalysisVO.setPlanCount(0D);
        }
        queryWrapper.clear();
        queryWrapper.eq(EnergyIndicators::getTimeType,queryTimeType);
        queryWrapper.eq(EnergyIndicators::getDataTime,DateUtil.format(dto.getDataTime(),timeFormat));
        queryWrapper.eq(EnergyIndicators::getNodeId,dto.getNodeId());
        queryWrapper.eq(EnergyIndicators::getEnergyType,dto.getEnergyType());
        queryWrapper.eq(EnergyIndicators::getIndicatorsType,"1");
        queryWrapper.eq(EnergyIndicators::getTimeType, queryTimeType);
        queryWrapper.eq(EnergyIndicators::getDataTime, DateUtil.format(dto.getDataTime(), timeFormat));
        queryWrapper.eq(EnergyIndicators::getNodeId, dto.getNodeId());
        queryWrapper.eq(EnergyIndicators::getEnergyType, dto.getEnergyType());
        queryWrapper.eq(EnergyIndicators::getIndicatorsType, "1");
        final EnergyIndicators prod = energyIndicatorsMapper.selectOne(queryWrapper);
        if(null != prod && null!= prod.getNumber()) {
        if (null != prod && null != prod.getNumber()) {
            consumptionAnalysisVO.setPlanCount(prod.getNumber().divide(new BigDecimal(between), CommonConst.DIGIT_2, RoundingMode.HALF_UP).doubleValue());
        }else {
        } else {
            consumptionAnalysisVO.setProdCount(0D);
        }
        return consumptionAnalysisVO;
@@ -993,19 +994,19 @@
        /**
         * æŸ¥è¯¢ç‚¹ä½ä¸Žç”¨èƒ½å•元信息
         */
        List<ModelNodeIndexInfor> nodeIndexInforList = modelNodeMapper.getModelNodeIndexIdByNodeId(nodeId,energyType);
        List<ModelNodeIndexInfor> nodeIndexInforList = modelNodeMapper.getModelNodeIndexIdByNodeId(nodeId, energyType);
        final List<String> eneryIdList = nodeIndexInforList.stream().map(ModelNodeIndexInfor::getEnergyId).distinct().collect(Collectors.toList());
        final LambdaQueryWrapper<SysEnergy> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.in(CollectionUtils.isNotEmpty(eneryIdList),SysEnergy::getEnersno,eneryIdList);
        queryWrapper.in(CollectionUtils.isNotEmpty(eneryIdList), SysEnergy::getEnersno, eneryIdList);
        final List<SysEnergy> sysEnergies = sysEnergyMapper.selectList(queryWrapper);
        final Map<String, BigDecimal> energyCoefficientMap = sysEnergies.stream().collect(Collectors.toMap(SysEnergy::getEnersno, SysEnergy::getCoefficient));
        final Map<String, String> indexIdEnergyIdMap = new HashMap<>();
        nodeIndexInforList.forEach(n->{
        nodeIndexInforList.forEach(n -> {
            final String indexId = n.getIndexId();
            final String energyId = n.getEnergyId();
            if(!indexIdEnergyIdMap.containsKey(indexId)){
                indexIdEnergyIdMap.put(indexId,energyId);
            if (!indexIdEnergyIdMap.containsKey(indexId)) {
                indexIdEnergyIdMap.put(indexId, energyId);
            }
        });
        List<String> indexIds = nodeIndexInforList.stream().map(ModelNodeIndexInfor::getIndexId).collect(Collectors.toList());
@@ -1032,12 +1033,11 @@
            shixuTimeType = TimeType.MONTH.name();
            timeFormat = "yyyy-MM";
        }
        // æ ¹æ®indexId查询dataItem
        List<DataItem> dataItemList = new ArrayList<>();
        if(CollectionUtils.isNotEmpty(indexIds)) {
        if (CollectionUtils.isNotEmpty(indexIds)) {
            dataItemList = dataItemService.getDataItemTimeRangeInforByIndexIds(beginTime, endTime, shixuTimeType, indexIds);
        }
        Map<String, List<DataItem>> dataItemMap = dataItemList.stream().collect(Collectors.groupingBy(li -> DateUtil.format(li.getDataTime(), timeFormat)));
@@ -1045,12 +1045,12 @@
        while (!beginTime.after(endTime)) {
            //查询开始时间和结束时间之间的产量
            LambdaQueryWrapper<ProductOutput> indicatorsWrapper = new LambdaQueryWrapper<>();
            indicatorsWrapper.eq(ProductOutput::getTimeType,shixuTimeType);
            indicatorsWrapper.eq(ProductOutput::getNodeId,dto.getNodeId());
            indicatorsWrapper.eq(ProductOutput::getDataTime,DateUtil.format(beginTime,timeFormat));
            indicatorsWrapper.eq(ProductOutput::getTimeType, shixuTimeType);
            indicatorsWrapper.eq(ProductOutput::getNodeId, dto.getNodeId());
            indicatorsWrapper.eq(ProductOutput::getDataTime, DateUtil.format(beginTime, timeFormat));
            List<ProductOutput> energyIndicators = productOutputMapper.selectList(indicatorsWrapper);
            prodCountMap.put(DateUtil.format(beginTime,timeFormat),energyIndicators);
            prodCountMap.put(DateUtil.format(beginTime, timeFormat), energyIndicators);
            ConsumptionAnalysisData data = new ConsumptionAnalysisData();
            final String currentTime = DateUtil.format(beginTime, timeFormat);
@@ -1058,17 +1058,18 @@
            BigDecimal sum = new BigDecimal(0);
            if (CollectionUtils.isNotEmpty(dataItems)) {
                // æ±‚å’Œ
                for (int i=0;i<dataItems.size(); i++){
                for (int i = 0; i < dataItems.size(); i++) {
                    final DataItem dataItem = dataItems.get(i);
                    final String indexId = dataItem.getIndexId();
                    final String energyId = indexIdEnergyIdMap.get(indexId);
                    final BigDecimal coefficient = energyCoefficientMap.get(energyId);
                    if(coefficient == null){
                    if (coefficient == null) {
                        throw new RuntimeException("能源类型" + energyId + "没有配置折标系数,无法计算");
                    }
                    sum = sum.add(new BigDecimal(dataItem.getValue()).multiply(coefficient)).setScale(2, RoundingMode.HALF_UP);;
                    sum = sum.add(new BigDecimal(dataItem.getValue()).multiply(coefficient)).setScale(2, RoundingMode.HALF_UP);
                    ;
                }
            }
@@ -1090,18 +1091,18 @@
                    break;
            }
        }
        dataList.forEach(d->{
        dataList.forEach(d -> {
            ProductEnergyAnalysisData productEnergyAnalysisData = new ProductEnergyAnalysisData();
            final String currentTime = d.getCurrentTime();
            productEnergyAnalysisData.setDateTime(currentTime);
            final List<ProductOutput> productOutputs = prodCountMap.get(currentTime);
            if(StringUtils.isEmpty(dto.getProdType())){
            if (StringUtils.isEmpty(dto.getProdType())) {
                productEnergyAnalysisData.setEnergyCount(format2Double(d.getCurrentValue()));
                final double sum = productOutputs.stream().map(ProductOutput::getNumber).mapToDouble(BigDecimal::doubleValue).sum();
                productEnergyAnalysisData.setProductCount(format2Double(sum));
                if(sum != 0) {
                if (sum != 0) {
                    final double averageEnergy = productEnergyAnalysisData.getEnergyCount() / productEnergyAnalysisData.getProductCount();
                    // åˆ›å»ºDecimalFormat对象,设置保留两位小数
                    DecimalFormat df = new DecimalFormat("#.00");
@@ -1109,15 +1110,15 @@
                    // æ ¼å¼åŒ–结果
                    String formattedResult = df.format(averageEnergy);
                    productEnergyAnalysisData.setAverage(Double.valueOf(formattedResult));
                }else {
                } else {
                    productEnergyAnalysisData.setAverage(0);
                }
            }else {
                if(CollectionUtils.isNotEmpty(productOutputs)) {
            } else {
                if (CollectionUtils.isNotEmpty(productOutputs)) {
                    final Map<String, List<ProductOutput>> productTypeMap = productOutputs.stream().collect(Collectors.groupingBy(ProductOutput::getProductType));
                    final double sum = productOutputs.stream().map(ProductOutput::getNumber).mapToDouble(BigDecimal::doubleValue).sum();
                    final List<ProductOutput> outputList = productTypeMap.get(dto.getProdType());
                    if(CollectionUtils.isNotEmpty(outputList)) {
                    if (CollectionUtils.isNotEmpty(outputList)) {
                        final double enengyProd = outputList.stream().map(ProductOutput::getNumber).mapToDouble(BigDecimal::doubleValue).sum();
                        productEnergyAnalysisData.setProductCount(format2Double(enengyProd));
                        productEnergyAnalysisData.setEnergyCount(format2Double(d.getCurrentValue() * enengyProd / sum));
@@ -1128,19 +1129,19 @@
                        } else {
                            productEnergyAnalysisData.setAverage(0);
                        }
                    }else {
                    } else {
                        productEnergyAnalysisData.setProductCount(0);
                        productEnergyAnalysisData.setEnergyCount(d.getCurrentValue());
                        productEnergyAnalysisData.setAverage(0);
                    }
                }else {
                } else {
                    productEnergyAnalysisData.setProductCount(0);
                    productEnergyAnalysisData.setEnergyCount(d.getCurrentValue());
                    productEnergyAnalysisData.setAverage(0);
                }
            }
            chart.add(productEnergyAnalysisData);
        });
@@ -1149,9 +1150,9 @@
        final double totalProd = chart.stream().map(ProductEnergyAnalysisData::getProductCount).mapToDouble(Double::doubleValue).sum();
        productEnergyAnalysisVO.setTotalEnergy(format2Double(totalEnergy));
        productEnergyAnalysisVO.setTotalProduct(format2Double(totalProd));
        if(totalProd != 0) {
        if (totalProd != 0) {
            productEnergyAnalysisVO.setAverageEnergy(format2Double(totalEnergy / totalProd));
        }else {
        } else {
            productEnergyAnalysisVO.setAverageEnergy(0D);
        }
        return productEnergyAnalysisVO;
zhitan-system/src/main/java/com/zhitan/dataitem/mapper/DataItemMapper.java
@@ -110,4 +110,16 @@
     */
    List<CarbonEmission> getDownCarbonEmission(@Param("beginTime") Date beginTime, @Param("endTime") Date endTime,
                                             @Param("timeType") String timeType, @Param("indexId") String indexId);
    /**
     * æ ¹æ®indexId与时间范围查询小时的dataitem信息
     *
     * @param beginTime å¼€å§‹æ—¶é—´
     * @param endTime   æˆªæ­¢æ—¶é—´
     * @param timeType  æ—¶é—´ç±»åž‹
     * @param indexIds  ç‚¹ä½é›†åˆ
     * @return
     */
    List<DataItem> getDataItemHourInforByIndexIds(@Param("beginTime") Date beginTime, @Param("endTime") Date endTime,
                                                  @Param("timeType") String timeType, @Param("indexIds") List<String> indexIds);
}
zhitan-system/src/main/java/com/zhitan/dataitem/service/IDataItemService.java
@@ -77,4 +77,15 @@
     * @return
     */
    BigDecimal getDataItemValueByIndexIds(String timeCode, List<String> indexIds);
    /**
     * æ ¹æ®indexId与时间范围查询小时的dataitem信息
     *
     * @param beginTime å¼€å§‹æ—¶é—´
     * @param endTime   æˆªæ­¢æ—¶é—´
     * @param timeType  æ—¶é—´ç±»åž‹
     * @param indexIds  ç‚¹ä½é›†åˆ
     * @return
     */
    List<DataItem> getDataItemHourInforByIndexIds(Date beginTime, Date endTime, String timeType, List<String> indexIds);
}
zhitan-system/src/main/java/com/zhitan/dataitem/service/impl/DataItemServiceImpl.java
@@ -103,4 +103,18 @@
    public BigDecimal getDataItemValueByIndexIds(String timeCode, List<String> indexIds) {
        return dataItemMapper.getDataItemValueByIndexIds(timeCode, indexIds);
    }
    /**
     * æ ¹æ®indexId与时间范围查询小时的dataitem信息
     *
     * @param beginTime å¼€å§‹æ—¶é—´
     * @param endTime   æˆªæ­¢æ—¶é—´
     * @param timeType  æ—¶é—´ç±»åž‹
     * @param indexIds  ç‚¹ä½é›†åˆ
     * @return
     */
    @Override
    public List<DataItem> getDataItemHourInforByIndexIds(Date beginTime, Date endTime, String timeType, List<String> indexIds) {
        return dataItemMapper.getDataItemHourInforByIndexIds(beginTime, endTime, timeType, indexIds);
    }
}
zhitan-system/src/main/java/com/zhitan/energyMonitor/domain/EnergyUnitToDevice.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,71 @@
package com.zhitan.energyMonitor.domain;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import com.zhitan.common.annotation.Excel;
import com.zhitan.common.core.domain.BaseEntity;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors;
import java.math.BigDecimal;
/**
 * @Description: ç”¨èƒ½å•元关联的平台模板中仪表的界面逻辑关系 ä¸å«æœ‰ é‡‡é›†ã€è®¡ç®—信息
 * @Author: jeecg-boot
 * @Date:   2022-01-26
 * @Version: V1.0
 */
@Data
@TableName("energy_unit_to_device")
@Accessors(chain = true)
@EqualsAndHashCode(callSuper = false)
@ApiModel(value="energy_unit_to_device对象", description="用能单元关联的平台模板中仪表的界面逻辑关系 ä¸å«æœ‰ é‡‡é›†ã€è®¡ç®—信息")
public class EnergyUnitToDevice extends BaseEntity {
    private static final long serialVersionUID = 1L;
    @ApiModelProperty(value = "新主键")
    @TableId(type = IdType.ASSIGN_ID)
    private String newId;
    /**主键*/
    @ApiModelProperty(value = "主键")
    private String id;
    /**关联仪表名称*/
    @Excel(name = "关联仪表名称", width = 15)
    @ApiModelProperty(value = "关联仪表名称")
    private String name;
    /**关联仪表编码*/
    @Excel(name = "关联仪表编码", width = 15)
    @ApiModelProperty(value = "关联仪表编码")
    private String code;
    /**能源类型(水表、电表、气表等)*/
    @Excel(name = "能源类型(水表、电表、气表等)", width = 15)
    @ApiModelProperty(value = "能源类型(水表、电表、气表等)")
    private String deviceType;
    /**用能单元主键*/
    @Excel(name = "用能单元主键", width = 15)
    @ApiModelProperty(value = "用能单元主键")
    private String energyUnitId;
    /**租户主键*/
    @Excel(name = "租户主键", width = 15)
    @ApiModelProperty(value = "租户主键")
    private Integer tenantId;
    @ApiModelProperty(value = "参与计量")
    private String partMeasurement;
    @ApiModelProperty(value = "安装位置")
    private String installPosition;
    @ApiModelProperty(value = "分摊比例")
    private BigDecimal shareRatio;
}
zhitan-system/src/main/java/com/zhitan/energyMonitor/domain/vo/EnergyCalculateCalcTV.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,31 @@
package com.zhitan.energyMonitor.domain.vo;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
/**
 * è®¡ç®—点位对应的计算公式
 * @author  zhw
 */
@Data
@ApiModel(value="计算点位对应的计算公式", description="计算点位对应的计算公式")
public class EnergyCalculateCalcTV {
    private static final long serialVersionUID = 1L;
    @ApiModelProperty(value = "计算点位主键")
    private String  calculateIndexId;
    @ApiModelProperty(value = "仪表设备主键")
    private String deviceId;
    @ApiModelProperty(value = "仪表名称")
    private String name;
    @ApiModelProperty(value = "计算点位包含的采集点位主键")
    private String collectIndexId;
    @ApiModelProperty(value = "采集点位对应操作符号")
    private String operator;
}
zhitan-system/src/main/java/com/zhitan/energyMonitor/domain/vo/ListElectricityMeterVO.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,20 @@
package com.zhitan.energyMonitor.domain.vo;
import lombok.Data;
/**
 * @Description: TODO
 * @author: yxw
 * @date: 2022å¹´04月24日 16:07
 */
@Data
public class ListElectricityMeterVO {
    /**
     * ç”µè¡¨åç§°
     */
    private String label;
    /**
     * ç”µè¡¨id
     */
    private String code;
}
zhitan-system/src/main/java/com/zhitan/energyMonitor/domain/vo/UnitToDeviceRelationVO.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,35 @@
package com.zhitan.energyMonitor.domain.vo;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
/**
 * ç”¨èƒ½å•元与计量器具关系vo
 *
 * @Author: Zhujw
 * @Date: 2023/4/4
 */
@Data
@ApiModel(value = "用能单元与计量器具关系vo-返回vo", description = "用能单元与计量器具关系vo-返回vo")
public class UnitToDeviceRelationVO {
    /**
     * ç”¨èƒ½å•å…ƒid
     */
    @ApiModelProperty(value = "用能单元id")
    private String unitId;
    /**
     * è®¡é‡å™¨å…·id
     */
    @ApiModelProperty(value = "计量器具id")
    private String deviceId;
    /**
     * è®¡é‡å™¨å…·åç§°
     */
    @ApiModelProperty(value = "计量器具名称")
    private String deviceName;
}
zhitan-system/src/main/java/com/zhitan/energyMonitor/mapper/EnergyUnitToDeviceMapper.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,38 @@
package com.zhitan.energyMonitor.mapper;
import com.baomidou.mybatisplus.annotation.InterceptorIgnore;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.zhitan.energyMonitor.domain.EnergyUnitToDevice;
import com.zhitan.energyMonitor.domain.vo.EnergyCalculateCalcTV;
import org.apache.ibatis.annotations.Param;
import java.util.List;
/**
 * @Description: ç”¨èƒ½å•元关联的平台模板中仪表的界面逻辑关系 ä¸å«æœ‰ é‡‡é›†ã€è®¡ç®—信息
 * @Author: jeecg-boot
 * @Date: 2022-01-26
 * @Version: V1.0
 */
public interface EnergyUnitToDeviceMapper extends BaseMapper<EnergyUnitToDevice> {
    /**
     * æ ¹æ®è®¡ç®—点位主键和用能单元主键 æŸ¥è¯¢ ä½¿ç”¨çš„ é‡‡é›†ç‚¹åŠä»ªè¡¨ä¿¡æ¯
     *
     * @param calculateIndexId
     * @param energyUnitId
     * @return
     */
    public List<EnergyCalculateCalcTV> getCalculateDevices(@Param("calculateIndexId") String calculateIndexId,
                                                           @Param("energyUnitId") String energyUnitId,
                                                           @Param("tenantId") String tenantId);
    /**
     * ä¸­ç§‘-根据租户id集合查询计量器具id
     *
     * @param unitIds
     * @return
     */
    @InterceptorIgnore(tenantLine = "true")
    List<String> listDeviceByTenantIds(@Param("unitIds") List<String> unitIds);
}
zhitan-system/src/main/java/com/zhitan/energyMonitor/service/IEnergyUnitToDeviceService.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,100 @@
package com.zhitan.energyMonitor.service;
import com.baomidou.mybatisplus.extension.service.IService;
import com.zhitan.energyMonitor.domain.EnergyUnitToDevice;
import com.zhitan.energyMonitor.domain.vo.ListElectricityMeterVO;
import com.zhitan.energyMonitor.domain.vo.UnitToDeviceRelationVO;
import java.util.List;
/**
 * @Description: ç”¨èƒ½å•元关联的平台模板中仪表的界面逻辑关系 ä¸å«æœ‰ é‡‡é›†ã€è®¡ç®—信息
 * @Author: jeecg-boot
 * @Date:   2022-01-26
 * @Version: V1.0
 */
public interface IEnergyUnitToDeviceService extends IService<EnergyUnitToDevice> {
    /**
     * æ ¹æ®ç”¨èƒ½å•å…ƒID获取租户下有效的仪表集合
     * @param unitId
     * @return
     */
    List<EnergyUnitToDevice> queryTenantUnitDeviceByUnitId(String unitId);
    /**
     * æ ¹æ®ç”¨èƒ½å•å…ƒID获取租户下所有有效的实体表集合
     * @param unitId
     * @return
     */
    List<EnergyUnitToDevice> queryTenantEntityMeterByUnitId(String unitId);
    /**
     * æ ¹æ®ç”¨èƒ½å•å…ƒid获取租户下有效的仪表id集合
     *
     * @param unitId ç”¨èƒ½å•å…ƒid
     * @return ä»ªè¡¨id集合
     */
    List<String> getEnergyUnitDeviceIdByUnitId(String unitId);
    /**
     * æ ¹æ®ç”¨èƒ½å•å…ƒid集合获取租户下有效的仪表id集合
     *
     * @param unitIds ç”¨èƒ½å•å…ƒid
     */
    List<String> getEnergyUnitDeviceIdByUnitIds(List<String> unitIds);
    /**
     * æ ¹æ®ç”¨èƒ½å•å…ƒid集合+能源类型获取租户下有效的仪表id集合
     *
     * @param unitIds    ç”¨èƒ½å•å…ƒid集合
     * @return
     */
    List<String> getDeviceIdByUnitIds(List<String> unitIds);
    /**
     * æ›´æ–°èƒ½å•å…ƒid获取租户下有效的仪表id集合
     *
     * @param unitId ç”¨èƒ½å•å…ƒid
     * @return ä»ªè¡¨id集合
     */
    List<String> updateEnergyUnitDeviceIdByUnitId(String unitId);
    /**
     * åˆ é™¤èƒ½å•å…ƒid获取租户下有效的仪表id集合
     * @param unitId    ç”¨èƒ½å•å…ƒid
     * @return  ä»ªè¡¨id集合
     */
    void deleteEnergyUnitDeviceIdByUnitId(String unitId);
    /**
     * æ ¹æ®ç”¨èƒ½å•å…ƒID获取租户下有效的电表集合
     * @param unitId
     * @return
     */
    List<ListElectricityMeterVO> listElectricityMeter(String unitId);
    /**
     * èŽ·å–ç§Ÿæˆ·ä¸‹æœ‰æ•ˆçš„è¡¨é›†åˆ
     * @return
     */
    List<EnergyUnitToDevice> listAllMeter();
    /**
     * æ ¹æ®è®¡é‡å™¨å…·id和用能单元id查询表关系
     *
     * @param unitId ç”¨èƒ½å•å…ƒid
     * @param id     id
     * @return EnergyUnitToDevice实体
     */
    EnergyUnitToDevice getEnergyUnitToDeviceById(String unitId, String id);
    /**
     * æ ¹æ®è®¡é‡å™¨å…·id集合查询与用能的关系
     *
     * @param unitIds
     * @return
     */
    List<UnitToDeviceRelationVO> listDeviceByUnitIds(List<String> unitIds);
}
zhitan-system/src/main/java/com/zhitan/energyMonitor/service/impl/EnergyUnitToDeviceServiceImpl.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,232 @@
package com.zhitan.energyMonitor.service.impl;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.zhitan.common.constant.CommonConst;
import com.zhitan.energyMonitor.domain.EnergyUnitToDevice;
import com.zhitan.energyMonitor.domain.vo.ListElectricityMeterVO;
import com.zhitan.energyMonitor.domain.vo.UnitToDeviceRelationVO;
import com.zhitan.energyMonitor.mapper.EnergyUnitToDeviceMapper;
import com.zhitan.energyMonitor.service.IEnergyUnitToDeviceService;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.stream.Collectors;
/**
 * @Description: ç”¨èƒ½å•元关联的平台模板中仪表的界面逻辑关系 ä¸å«æœ‰ é‡‡é›†ã€è®¡ç®—信息
 * @Author: jeecg-boot
 * @Date: 2022-01-26
 * @Version: V1.0
 */
@Service
public class EnergyUnitToDeviceServiceImpl extends ServiceImpl<EnergyUnitToDeviceMapper, EnergyUnitToDevice>
        implements IEnergyUnitToDeviceService {
//    @Autowired
//    private IMeasuringInstrumentsService meterService;
    /**
     * æ ¹æ®ç”¨èƒ½å•å…ƒid获取租户下的其下的仪表列表
     *
     * @param unitId
     * @return
     */
    @Override
    public List<EnergyUnitToDevice> queryTenantUnitDeviceByUnitId(String unitId) {
        QueryWrapper<EnergyUnitToDevice> queryWrapper = new QueryWrapper<EnergyUnitToDevice>();
//                .eq(TableColumnConst.TABLE_COLUMN_ENERGY_UNIT_ID, unitId);
        return baseMapper.selectList(queryWrapper);
    }
    /**
     * æ ¹æ®ç”¨èƒ½å•å…ƒID获取租户下所有有效的实体表集合
     *
     * @param unitId
     * @return
     */
    @Override
    public List<EnergyUnitToDevice> queryTenantEntityMeterByUnitId(String unitId) {
        List<EnergyUnitToDevice> unitToDeviceList = baseMapper.selectList(Wrappers.<EnergyUnitToDevice>lambdaQuery()
                .eq(EnergyUnitToDevice::getEnergyUnitId, unitId)
        );
//        if (CollectionUtils.isNotEmpty(unitToDeviceList)) {
//            List<String> meterIds = unitToDeviceList.stream().map(EnergyUnitToDevice::getId).collect(Collectors.toList());
//            // è¿‡æ»¤å‡ºå®žä½“表
//            Integer applianceType = EquipmentInformationEnum.MEASURING_INSTRUMENT_TYPE.ENTITY.getValue();
//            List<Meter> meterList = meterService.list(Wrappers.<Meter>lambdaQuery()
//                    .select(Meter::getId).in(Meter::getId, meterIds)
//                    .eq(Meter::getApplianceType, applianceType)
//            );
//            List<String> newMeterIds = meterList.stream().map(Meter::getId).collect(Collectors.toList());
//            unitToDeviceList = unitToDeviceList.stream().filter(li -> newMeterIds.contains(li.getId())).collect(Collectors.toList());
//        }
        return unitToDeviceList;
    }
    /**
     * æ ¹æ®ç”¨èƒ½å•å…ƒid获取租户下有效的仪表id集合
     *
     * @param unitId ç”¨èƒ½å•å…ƒid
     * @return ä»ªè¡¨id集合
     */
    @Override
//    @Cacheable(value = CacheConstant.ENERGY_UNIT_DEVICE_ID_CACHE, key = "#unitId", unless = "#result == null")
    public List<String> getEnergyUnitDeviceIdByUnitId(String unitId) {
        if (StringUtils.isEmpty(unitId)) {
            return Collections.emptyList();
        }
        List<EnergyUnitToDevice> energyUnitToDevices = baseMapper.selectList(Wrappers.<EnergyUnitToDevice>lambdaQuery()
                .select(EnergyUnitToDevice::getId).eq(EnergyUnitToDevice::getEnergyUnitId, unitId)
        );
        if (CollectionUtils.isEmpty(energyUnitToDevices)) {
            return Collections.emptyList();
        }
        return energyUnitToDevices.stream().map(EnergyUnitToDevice::getId).collect(Collectors.toList());
    }
    /**
     * æ ¹æ®ç”¨èƒ½å•å…ƒid集合获取租户下有效的仪表id集合
     *
     * @param unitIds ç”¨èƒ½å•å…ƒid
     */
    @Override
    public List<String> getEnergyUnitDeviceIdByUnitIds(List<String> unitIds) {
        if (CollectionUtils.isEmpty(unitIds)) {
            return Collections.emptyList();
        }
        List<String> deviceIdList = new ArrayList<>();
        for (String unitId : unitIds) {
            List<String> unitDeviceIdByUnitId = this.getEnergyUnitDeviceIdByUnitId(unitId);
            if (CollectionUtils.isNotEmpty(unitDeviceIdByUnitId)) {
                deviceIdList.addAll(unitDeviceIdByUnitId);
            }
        }
        return deviceIdList;
    }
    /**
     * æ ¹æ®ç”¨èƒ½å•å…ƒid集合+能源类型获取租户下有效的仪表id集合
     *
     * @param unitIds ç”¨èƒ½å•å…ƒid集合
     * @return
     */
    @Override
    public List<String> getDeviceIdByUnitIds(List<String> unitIds) {
        if (CollectionUtils.isEmpty(unitIds)) {
            return Collections.emptyList();
        }
        return baseMapper.listDeviceByTenantIds(unitIds);
    }
    /**
     * æ›´æ–°èƒ½å•å…ƒid获取租户下有效的仪表id集合
     *
     * @param unitId ç”¨èƒ½å•å…ƒid
     * @return ä»ªè¡¨id集合
     */
    @Override
//    @CachePut(value = CacheConstant.ENERGY_UNIT_DEVICE_ID_CACHE, key = "#unitId", unless = "#result == null")
    public List<String> updateEnergyUnitDeviceIdByUnitId(String unitId) {
        if (StringUtils.isEmpty(unitId)) {
            return Collections.emptyList();
        }
        List<EnergyUnitToDevice> energyUnitToDevices = baseMapper.selectList(Wrappers.<EnergyUnitToDevice>lambdaQuery()
                .select(EnergyUnitToDevice::getId).eq(EnergyUnitToDevice::getEnergyUnitId, unitId)
        );
        if (CollectionUtils.isEmpty(energyUnitToDevices)) {
            return Collections.emptyList();
        }
        return energyUnitToDevices.stream().map(EnergyUnitToDevice::getId).collect(Collectors.toList());
    }
    /**
     * åˆ é™¤èƒ½å•å…ƒid获取租户下有效的仪表id集合
     *
     * @param unitId ç”¨èƒ½å•å…ƒid
     */
    @Override
//    @CacheEvict(value = CacheConstant.ENERGY_UNIT_DEVICE_ID_CACHE, key = "#unitId")
    public void deleteEnergyUnitDeviceIdByUnitId(String unitId) {
    }
    @Override
    public List<ListElectricityMeterVO> listElectricityMeter(String unitId) {
        LambdaQueryWrapper<EnergyUnitToDevice> queryWrapper = new LambdaQueryWrapper<EnergyUnitToDevice>()
                .eq(EnergyUnitToDevice::getEnergyUnitId, unitId);
//                .eq(EnergyUnitToDevice::getDeviceType, EnergyTypeConst.ELECTRICITY);
        List<EnergyUnitToDevice> models = baseMapper.selectList(queryWrapper);
        List<ListElectricityMeterVO> resultList = new ArrayList<>();
        for (EnergyUnitToDevice model : models) {
            ListElectricityMeterVO temp = new ListElectricityMeterVO();
            temp.setCode(model.getId());
            temp.setLabel(model.getName());
            resultList.add(temp);
        }
        return resultList;
    }
    @Override
    public List<EnergyUnitToDevice> listAllMeter() {
        QueryWrapper<EnergyUnitToDevice> queryWrapper = new QueryWrapper<EnergyUnitToDevice>();
        return baseMapper.selectList(queryWrapper);
    }
    @Override
    public EnergyUnitToDevice getEnergyUnitToDeviceById(String unitId, String id) {
        if (StringUtils.isEmpty(id)) {
            return null;
        }
        LambdaQueryWrapper<EnergyUnitToDevice> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.eq(EnergyUnitToDevice::getEnergyUnitId, unitId);
        lambdaQueryWrapper.eq(EnergyUnitToDevice::getId, id);
        List<EnergyUnitToDevice> energyUnitToDevices = baseMapper.selectList(lambdaQueryWrapper);
        if (CollectionUtils.isNotEmpty(energyUnitToDevices)) {
            return energyUnitToDevices.get(CommonConst.DIGIT_0);
        }
        return null;
    }
    /**
     * æ ¹æ®è®¡é‡å™¨å…·id集合查询与用能的关系
     *
     * @param unitIds
     * @return
     */
    @Override
    public List<UnitToDeviceRelationVO> listDeviceByUnitIds(List<String> unitIds) {
        List<UnitToDeviceRelationVO> relationList = new ArrayList<>();
        if (CollectionUtils.isEmpty(unitIds)) {
            return relationList;
        }
        List<EnergyUnitToDevice> unitToDeviceList = baseMapper.selectList(Wrappers.<EnergyUnitToDevice>lambdaQuery()
                .select(EnergyUnitToDevice::getId, EnergyUnitToDevice::getEnergyUnitId, EnergyUnitToDevice::getName)
                .in(EnergyUnitToDevice::getEnergyUnitId, unitIds)
        );
        if (CollectionUtils.isNotEmpty(unitToDeviceList)) {
            unitToDeviceList.forEach(li -> {
                UnitToDeviceRelationVO vo = new UnitToDeviceRelationVO();
                vo.setDeviceId(li.getId());
                vo.setUnitId(li.getEnergyUnitId());
                vo.setDeviceName(li.getName());
                relationList.add(vo);
            });
        }
        return relationList;
    }
}
zhitan-system/src/main/java/com/zhitan/history/domain/dto/HistoricalDataDTO.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,63 @@
package com.zhitan.history.domain.dto;
import com.fasterxml.jackson.annotation.JsonFormat;
import org.springframework.format.annotation.DateTimeFormat;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull;
import java.util.Date;
/**
 * åŽ†å²ç›‘æµ‹æ•°æ®è¯·æ±‚ DTO
 *
 * @Author: Zhujw
 * @Date: 2023/3/7
 */
public class HistoricalDataDTO {
    /**
     * ç‚¹ä½id
     */
    @NotBlank(message = "未找到点位信息")
    private String indexId;
    /**
     * æ—¶é—´ç±»åž‹
     */
    @NotBlank(message = "未找到时间类型")
    private String timeType;
    /**
     * æŸ¥è¯¢æ—¶é—´
     */
    @JsonFormat(timezone = "GMT+8",pattern = "yyyy-MM-dd HH:mm:ss")
    @DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss")
    @NotNull(message = "未找到时间信息")
    private Date dataTime;
    public String getIndexId() {
        return indexId;
    }
    public void setIndexId(String indexId) {
        this.indexId = indexId;
    }
    public String getTimeType() {
        return timeType;
    }
    public void setTimeType(String timeType) {
        this.timeType = timeType;
    }
    public Date getDataTime() {
        return dataTime;
    }
    public void setDataTime(Date dataTime) {
        this.dataTime = dataTime;
    }
}
zhitan-system/src/main/java/com/zhitan/history/domain/vo/HistoricalDataExcel.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,70 @@
package com.zhitan.history.domain.vo;
import com.zhitan.common.annotation.Excel;
/**
 * åŽ†å²ç›‘æµ‹æ•°æ®è¿”å›ž Excel
 *
 * @Author: Zhujw
 * @Date: 2023/3/7
 */
public class HistoricalDataExcel {
    /**
     * ç‚¹ä½åç§°
     */
    @Excel(name = "点位名称")
    private String indexName;
    /**
     * å€¼
     */
    @Excel(name = "值")
    private String value;
    /**
     * ä½¿ç”¨é‡
     */
    @Excel(name = "使用量")
    private String usedValue;
    /**
     * æ—¶é—´
     */
    @Excel(name = "时间")
    private String dataTime;
    public String getIndexName() {
        return indexName;
    }
    public void setIndexName(String indexName) {
        this.indexName = indexName;
    }
    public String getDataTime() {
        return dataTime;
    }
    public void setDataTime(String dataTime) {
        this.dataTime = dataTime;
    }
    public String getValue() {
        return value;
    }
    public void setValue(String value) {
        this.value = value;
    }
    public String getUsedValue() {
        return usedValue;
    }
    public void setUsedValue(String usedValue) {
        this.usedValue = usedValue;
    }
}
zhitan-system/src/main/java/com/zhitan/history/domain/vo/HistoricalDataVO.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,77 @@
package com.zhitan.history.domain.vo;
/**
 * åŽ†å²ç›‘æµ‹æ•°æ®è¿”å›ž VO
 *
 * @Author: Zhujw
 * @Date: 2023/3/7
 */
public class HistoricalDataVO {
    /**
     * ç‚¹ä½id
     */
    private String indexId;
    /**
     * ç‚¹ä½åç§°
     */
    private String indexName;
    /**
     * æ—¶é—´
     */
    private String dataTime;
    /**
     * å€¼
     */
    private String value;
    /**
     * ä½¿ç”¨é‡
     */
    private String usedValue;
    public String getIndexId() {
        return indexId;
    }
    public void setIndexId(String indexId) {
        this.indexId = indexId;
    }
    public String getIndexName() {
        return indexName;
    }
    public void setIndexName(String indexName) {
        this.indexName = indexName;
    }
    public String getDataTime() {
        return dataTime;
    }
    public void setDataTime(String dataTime) {
        this.dataTime = dataTime;
    }
    public String getValue() {
        return value;
    }
    public void setValue(String value) {
        this.value = value;
    }
    public String getUsedValue() {
        return usedValue;
    }
    public void setUsedValue(String usedValue) {
        this.usedValue = usedValue;
    }
}
zhitan-system/src/main/java/com/zhitan/model/domain/vo/ModelNodeIndexInfor.java
@@ -32,6 +32,8 @@
   */
  private String energyId;
  private String indexType;
  public String getNodeId() {
    return nodeId;
  }
@@ -63,4 +65,12 @@
  public void setEnergyId(String energyId) {
    this.energyId = energyId;
  }
  public String getIndexType() {
    return indexType;
  }
  public void setIndexType(String indexType) {
    this.indexType = indexType;
  }
}
zhitan-system/src/main/java/com/zhitan/realtimedata/data/RealtimeDatabaseManager.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,163 @@
package com.zhitan.realtimedata.data;
import com.influxdb.client.InfluxDBClient;
import com.influxdb.client.InfluxDBClientFactory;
import com.influxdb.client.domain.HealthCheck;
import com.zhitan.common.enums.CollectionModes;
import com.zhitan.common.enums.RetrievalModes;
import com.zhitan.realtimedata.config.RtdbConfig;
import com.zhitan.realtimedata.domain.TagValue;
import com.zhitan.realtimedata.service.RealtimeDatabase;
import org.apache.commons.lang3.StringUtils;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.springframework.stereotype.Component;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Optional;
/**
 * @author èŒƒæ–°å¯Œ å®žæ—¶æ•°æ®åº“访问管理.
 */
@Component
public class RealtimeDatabaseManager {
    private final RealtimeDatabase connection;
    private final Logger logger = LogManager.getLogger(RealtimeDatabaseManager.class);
    public RealtimeDatabaseManager(RtdbConfig config) {
    connection = new VirtualRtdb();
        try {
            InfluxDBClient influxDBClient = InfluxDBClientFactory.create(config.getHost(),
                    config.getToken().toCharArray(), config.getOrg(), config.getBucket());
            logger.error("--------------------实时库连接成功--------------------");
            HealthCheck health = influxDBClient.health();
            if (health.getStatus() == HealthCheck.StatusEnum.FAIL) {
                influxDBClient.close();
            }
        } catch (Exception e) {
            logger.error(e);
        }
    }
    public TagValue retrieve(String tagCode) {
        List<String> tagCodes = new ArrayList<>();
        tagCodes.add(tagCode);
        List<TagValue> tagValues = retrieve(tagCodes);
        if (!tagValues.isEmpty()) {
            return tagValues.get(0);
        }
        return null;
    }
    public List<TagValue> retrieve(List<String> tagCodes) {
        List<TagValue> tagValues = new ArrayList<>();
        try {
            tagValues = connection.retrieve(tagCodes);
        } catch (Exception e) {
            logger.error(e);
        }
        return tagValues;
    }
    public TagValue retrieve(String tagCode, Date dataTime, String timeCode) {
        List<String> tagCodes = new ArrayList<>();
        tagCodes.add(tagCode);
        List<TagValue> tagValues = retrieve(tagCodes, dataTime, timeCode);
        if (!tagValues.isEmpty()) {
            return tagValues.get(0);
        }
        return null;
    }
    public List<TagValue> retrieve(List<String> tagCodes, Date dataTime, String timeCode) {
        List<TagValue> tagValues = new ArrayList<>();
        try {
            List<TagValue> tmp = connection.retrieve(tagCodes, dataTime, timeCode);
            for (String tagCode : tagCodes) {
                Optional<TagValue> tagValue = tmp.stream()
                        .filter(f -> StringUtils.equalsIgnoreCase(f.getTagCode(), tagCode)).findAny();
                TagValue value;
                if (!tagValue.isPresent()) {
                    value = new TagValue();
                    value.setTagCode(tagCode);
                    value.setDataTime(dataTime);
                } else {
                    value = tagValue.get();
                }
                tagValues.add(value);
            }
        } catch (Exception e1) {
            logger.error(e1);
        }
        return tagValues;
    }
    public List<TagValue> retrieve(String tagCode, Date beginTime, Date endTime,
                                   RetrievalModes retrievalModes, int pointCount) {
        List<String> tagCodes = new ArrayList<>();
        tagCodes.add(tagCode);
        return retrieve(tagCodes, beginTime, endTime, retrievalModes, pointCount);
    }
    public List<TagValue> retrieve(List<String> tagCodes, Date beginTime, Date endTime,
                                   RetrievalModes retrievalModes, int pointCount) {
        List<TagValue> tagValues = new ArrayList<>();
        try {
            tagValues = connection.retrieve(tagCodes, beginTime, endTime, retrievalModes, pointCount);
        } catch (Exception e1) {
            logger.error(e1);
        }
        return tagValues;
    }
    public TagValue statistics(String tagCode, Date beginTime, Date endTime,
                               CollectionModes collectionModes) {
        List<String> tagCodes = new ArrayList<>();
        tagCodes.add(tagCode);
        List<TagValue> tagValues = statistics(tagCodes, beginTime, endTime, collectionModes);
        if (!tagValues.isEmpty()) {
            return tagValues.get(0);
        }
        return null;
    }
    public List<TagValue> statistics(List<String> tagCodes, Date beginTime, Date endTime,
                                     CollectionModes collectionModes) {
        List<TagValue> tagValues = new ArrayList<>();
        try {
            tagValues = connection.statistics(tagCodes, beginTime, endTime, collectionModes);
        } catch (Exception e1) {
            logger.error(e1);
        }
        return tagValues;
    }
    public void storeData(List<TagValue> tagValues) {
        try {
            connection.storeData(tagValues);
        } catch (Exception e1) {
            logger.error(e1);
        }
    }
    public void insertData(List<TagValue> tagValues) {
        try {
            connection.insertData(tagValues);
        } catch (Exception e1) {
            logger.error(e1);
        }
    }
}
zhitan-system/src/main/java/com/zhitan/realtimedata/domain/SysEquipmentFile.java
@@ -1,5 +1,8 @@
package com.zhitan.realtimedata.domain;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;
import java.util.List;
@@ -9,10 +12,18 @@
 *
 */
@Data
@TableName("sys_equipmentfile")
public class SysEquipmentFile {
  @TableId
  private String nodeId;
  @TableField(value = "filepath")
  private String filePath;
  @TableField(exist = false)
  private String svgType;
  @TableField(exist = false)
  private List<SysSvgInfo> infoList;
}
zhitan-system/src/main/java/com/zhitan/realtimedata/domain/vo/EquipmentMeasuringPointParameters.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,30 @@
package com.zhitan.realtimedata.domain.vo;
import lombok.Data;
/**
 * è®¾å¤‡ç›‘测参数列表对象
 */
@Data
public class EquipmentMeasuringPointParameters {
    private String code;
    private String indexName;
    private String indexUnit;
    private Double value;
    private String yValue;
    private String meteName;
    public String getyValue() {
        return yValue;
    }
    public void setyValue(String yValue) {
        this.yValue = yValue;
    }
}
zhitan-system/src/main/java/com/zhitan/realtimedata/mapper/SvgTrendMapper.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,16 @@
package com.zhitan.realtimedata.mapper;
import com.zhitan.model.domain.EnergyIndex;
import java.util.List;
public interface SvgTrendMapper {
    /**
     * å®žæ—¶æ£€æµ‹ åŠŸèƒ½ çš„多 sheet页  å±•示 ç»„态图  æµ‹ç‚¹ æŠ¥è­¦ä¿¡æ¯
     *
     * @param energyIndex
     * @return
     */
    List<EnergyIndex> selectSvgTrendList(EnergyIndex energyIndex);
}
zhitan-system/src/main/java/com/zhitan/realtimedata/service/ISvgTrendService.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,15 @@
package com.zhitan.realtimedata.service;
import com.zhitan.model.domain.EnergyIndex;
import java.util.List;
public interface ISvgTrendService {
    /**
     * å®žæ—¶æ£€æµ‹ åŠŸèƒ½ çš„多 sheet页  å±•示趋势图
     * @param energyIndex
     * @return
     */
    List<EnergyIndex> selectSvgList(EnergyIndex energyIndex);
}
zhitan-system/src/main/java/com/zhitan/realtimedata/service/RealtimeDatabaseService.java
@@ -2,6 +2,7 @@
import com.zhitan.common.enums.CollectionModes;
import com.zhitan.common.enums.RetrievalModes;
import com.zhitan.realtimedata.domain.TagValue;
import java.util.Date;
@@ -105,4 +106,17 @@
     * @param tagValues æµ‹ç‚¹åŽ†å²æ—¶åˆ»æ•°æ®
     */
    void insertData(List<TagValue> tagValues);
    /**
     * èŽ·å–ä¸€æ®µæ—¶é—´å†…æµ‹ç‚¹çš„åŽ†å²æ•°æ®.
     *
     * @param tagCode        æµ‹ç‚¹ç¼–号
     * @param beginTime      å¼€å§‹æ—¶é—´
     * @param endTime        ç»“束时间
     * @param retrievalModes æŸ¥è¯¢æ•°æ®æ–¹å¼
     * @param pointCount     æµ‹ç‚¹å¾—到的数据个数
     * @return æµ‹ç‚¹åŽ†å²æ•°æ®
     */
    List<TagValue> retrieve(String tagCode, Date beginTime, Date endTime,
                            RetrievalModes retrievalModes, int pointCount);
}
zhitan-system/src/main/java/com/zhitan/realtimedata/service/impl/RealtimeDatabaseServiceImpl.java
@@ -2,6 +2,8 @@
import com.google.common.collect.Lists;
import com.zhitan.common.enums.CollectionModes;
import com.zhitan.common.enums.RetrievalModes;
import com.zhitan.realtimedata.data.RealtimeDatabaseManager;
import com.zhitan.realtimedata.data.influxdb.InfluxDBRepository;
import com.zhitan.realtimedata.domain.TagValue;
import com.zhitan.realtimedata.service.RealtimeDatabaseService;
@@ -20,8 +22,11 @@
    private final InfluxDBRepository repository;
    public RealtimeDatabaseServiceImpl(InfluxDBRepository repository) {
    private final RealtimeDatabaseManager realtimeDatabaseManager;
    public RealtimeDatabaseServiceImpl(InfluxDBRepository repository, RealtimeDatabaseManager realtimeDatabaseManager) {
        this.repository = repository;
        this.realtimeDatabaseManager = realtimeDatabaseManager;
    }
    /**
@@ -146,4 +151,9 @@
        repository.store(tagValues);
    }
    @Override
    public List<TagValue> retrieve(String tagCode, Date beginTime, Date endTime,
                                   RetrievalModes retrievalModes, int pointCount) {
        return realtimeDatabaseManager.retrieve(tagCode, beginTime, endTime, retrievalModes, pointCount);
    }
}
zhitan-system/src/main/java/com/zhitan/realtimedata/service/impl/SvgTrendServicelmpl.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,26 @@
package com.zhitan.realtimedata.service.impl;
import com.zhitan.model.domain.EnergyIndex;
import com.zhitan.realtimedata.mapper.SvgTrendMapper;
import com.zhitan.realtimedata.service.ISvgTrendService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;
@Service
public class SvgTrendServicelmpl implements ISvgTrendService {
    @Autowired
    private SvgTrendMapper svgTrendMapper;
    /**
     * æŸ¥è¯¢æŒ‡æ ‡ä¿¡æ¯
     *
     * @param energyIndex æŒ‡æ ‡ä¿¡æ¯ID
     * @return æŒ‡æ ‡ä¿¡æ¯
     */
    @Override
    public List<EnergyIndex> selectSvgList(EnergyIndex energyIndex) {
        return svgTrendMapper.selectSvgTrendList(energyIndex);
    }
}
zhitan-system/src/main/java/com/zhitan/statisticalAnalysis/domain/dto/DataAnalysisMoMDTO.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,48 @@
package com.zhitan.statisticalAnalysis.domain.dto;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.zhitan.common.annotation.Excel;
import lombok.Data;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull;
import java.util.Date;
/**
 * æ•°æ®åˆ†æžçŽ¯æ¯” è¯·æ±‚参数
 *
 * @Author: Zhujw
 * @Date: 2023/3/3
 */
@Data
public class DataAnalysisMoMDTO {
    /**
     * ç»Ÿè®¡å¼€å§‹æ—¶é—´
     */
    @NotNull(message = "请维护查询时间")
    @JsonFormat(pattern="yyyy-MM-dd HH:mm:ss")
    @Excel(name = "报警开始时间", dateFormat = "yyyy-MM-dd HH:mm:ss")
    private Date beginTime;
    /**
     * ç»Ÿè®¡å¼€å§‹æ—¶é—´
     */
    @JsonFormat(pattern="yyyy-MM-dd HH:mm:ss")
    @Excel(name = "报警开始时间", dateFormat = "yyyy-MM-dd HH:mm:ss")
    @NotNull(message = "请维护查询时间")
    private Date endTime;
    /**
     * æ—¶é—´ç±»åž‹
     */
    @NotBlank(message = "未找到时间类型")
    private String timeType;
    /**
     * æ¨¡åž‹èŠ‚ç‚¹id
     */
    @NotBlank(message = "未找到模型节点信息")
    private String nodeId;
}
zhitan-system/src/main/java/com/zhitan/statisticalAnalysis/domain/vo/DataAnalysisMoMExcel.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,47 @@
package com.zhitan.statisticalAnalysis.domain.vo;
import com.zhitan.common.annotation.Excel;
import lombok.Data;
import java.math.BigDecimal;
/**
 * æ•°æ®åˆ†æžçŽ¯æ¯” å¯¼å‡ºExcel
 *
 * @Author: Zhujw
 * @Date: 2023/3/3
 */
@Data
public class DataAnalysisMoMExcel {
    /**
     * ç”¨èƒ½å•元名称
     */
    @Excel(name = "用能单元")
    private String energyUnitName;
    /**
     * æœ¬æœŸå€¼
     */
    @Excel(name = "本期值")
    private BigDecimal currentValue;
    /**
     * åŒæœŸå€¼
     */
    @Excel(name = "同期值")
    private BigDecimal oldValue;
    /**
     * åŒæ¯”值
     */
    @Excel(name = "同比值")
    private BigDecimal ratio;
    /**
     * å•位
     */
    @Excel(name = "单位")
    private String unit;
}
zhitan-system/src/main/java/com/zhitan/statisticalAnalysis/domain/vo/DataAnalysisMoMVO.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,42 @@
package com.zhitan.statisticalAnalysis.domain.vo;
import lombok.Data;
import java.math.BigDecimal;
/**
 * æ•°æ®åˆ†æžçŽ¯æ¯” è¿”回vo
 *
 * @Author: Zhujw
 * @Date: 2023/3/3
 */
@Data
public class DataAnalysisMoMVO {
    /**
     * å•位
     */
    private String unit;
    /**
     * ç”¨èƒ½å•元名称
     */
    private String energyUnitName;
    /**
     * æœ¬æœŸå€¼
     */
    private BigDecimal currentValue;
    /**
     * åŒæœŸå€¼
     */
    private BigDecimal oldValue;
    /**
     * åŒæ¯”值
     */
    private BigDecimal ratio;
}
zhitan-system/src/main/java/com/zhitan/statisticalAnalysis/domain/vo/DataAnalysisYoYExcel.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,47 @@
package com.zhitan.statisticalAnalysis.domain.vo;
import com.zhitan.common.annotation.Excel;
import lombok.Data;
import java.math.BigDecimal;
/**
 * æ•°æ®åˆ†æžåŒæ¯” å¯¼å‡ºExcel
 *
 * @Author: Zhujw
 * @Date: 2023/3/3
 */
@Data
public class DataAnalysisYoYExcel {
    /**
     * ç”¨èƒ½å•元名称
     */
    @Excel(name = "用能单元名称")
    private String energyUnitName;
    /**
     * æœ¬æœŸå€¼
     */
    @Excel(name = "本期值")
    private BigDecimal currentValue;
    /**
     * åŒæœŸå€¼
     */
    @Excel(name = "同期值")
    private BigDecimal oldValue;
    /**
     * åŒæ¯”值
     */
    @Excel(name = "同比值")
    private BigDecimal ratio;
    /**
     * å•位
     */
    @Excel(name = "单位")
    private String unit;
}
zhitan-system/src/main/java/com/zhitan/statisticalAnalysis/domain/vo/DataAnalysisYoYVO.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,42 @@
package com.zhitan.statisticalAnalysis.domain.vo;
import lombok.Data;
import java.math.BigDecimal;
/**
 * æ•°æ®åˆ†æžåŒæ¯” è¿”回vo
 *
 * @Author: Zhujw
 * @Date: 2023/3/3
 */
@Data
public class DataAnalysisYoYVO {
    /**
     * å•位
     */
    private String unit;
    /**
     * ç”¨èƒ½å•元名称
     */
    private String energyUnitName;
    /**
     * æœ¬æœŸå€¼
     */
    private BigDecimal currentValue;
    /**
     * åŒæœŸå€¼
     */
    private BigDecimal oldValue;
    /**
     * åŒæ¯”值
     */
    private BigDecimal ratio;
}
zhitan-system/src/main/java/com/zhitan/statisticalAnalysis/service/IStatisticalAnalysisService.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,36 @@
package com.zhitan.statisticalAnalysis.service;
import com.zhitan.statisticalAnalysis.domain.dto.DataAnalysisMoMDTO;
import com.zhitan.statisticalAnalysis.domain.vo.DataAnalysisMoMVO;
import com.zhitan.statisticalAnalysis.domain.vo.DataAnalysisYoYVO;
import java.util.List;
/**
 * ç»Ÿè®¡åˆ†æž  æŽ¥å£å±‚
 *
 * @Author: Zhujw
 * @Date: 2023/3/1
 */
public interface IStatisticalAnalysisService {
    /**
     * èŽ·å–ç”µèƒ½è€—åŒæ¯”æ•°æ®
     */
    List<DataAnalysisYoYVO> listElectricDataComparisonYoY(DataAnalysisMoMDTO dto);
    /**
     * èŽ·å–ç”µèƒ½è€—çŽ¯æ¯”æ•°æ®
     */
    List<DataAnalysisMoMVO> listElectricDataComparisonMoM(DataAnalysisMoMDTO dto);
    /**
     * èŽ·å–èƒ½è€—åŒæ¯”æ•°æ®
     */
    List<DataAnalysisYoYVO> listWaterDataComparisonYoY(DataAnalysisMoMDTO dto);
    /**
     * èŽ·å–èƒ½è€—çŽ¯æ¯”æ•°æ®
     */
    List<DataAnalysisMoMVO> listWaterDataComparisonMoM(DataAnalysisMoMDTO dto);
}
zhitan-system/src/main/java/com/zhitan/statisticalAnalysis/service/impl/StatisticalAnalysisServiceImpl.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,293 @@
package com.zhitan.statisticalAnalysis.service.impl;
import cn.hutool.core.date.DateField;
import cn.hutool.core.date.DateUtil;
import com.zhitan.common.constant.CommonConst;
import com.zhitan.common.constant.TimeTypeConst;
import com.zhitan.common.enums.TimeType;
import com.zhitan.dataitem.service.IDataItemService;
import com.zhitan.model.domain.vo.ModelNodeIndexInfor;
import com.zhitan.model.service.IModelNodeService;
import com.zhitan.realtimedata.domain.DataItem;
import com.zhitan.statisticalAnalysis.domain.dto.DataAnalysisMoMDTO;
import com.zhitan.statisticalAnalysis.domain.vo.DataAnalysisMoMVO;
import com.zhitan.statisticalAnalysis.domain.vo.DataAnalysisYoYVO;
import com.zhitan.statisticalAnalysis.service.IStatisticalAnalysisService;
import lombok.AllArgsConstructor;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.stereotype.Service;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.*;
import java.util.stream.Collectors;
/**
 * ç»Ÿè®¡åˆ†æž  æŽ¥å£å±‚实现层
 */
@Service
@AllArgsConstructor
public class StatisticalAnalysisServiceImpl implements IStatisticalAnalysisService {
    private final IDataItemService dataItemService;
    private final IModelNodeService modelNodeService;
    /**
     * èŽ·å–ç”µèƒ½è€—åŒæ¯”æ•°æ®
     */
    @Override
    public List<DataAnalysisYoYVO> listElectricDataComparisonYoY(DataAnalysisMoMDTO dto) {
        List<DataAnalysisYoYVO> yoyList = new ArrayList<>();
        // æŸ¥è¯¢ç‚¹ä½ä¸Žç”¨èƒ½å•元信息
        List<ModelNodeIndexInfor> nodeInforList = listModelNodeIndexIdRelationInfor(dto.getNodeId());
        if (CollectionUtils.isEmpty(nodeInforList)) {
            return yoyList;
        }
        List<String> indexIds = nodeInforList.stream().map(ModelNodeIndexInfor::getIndexId).collect(Collectors.toList());
        // æŒ‰ç…§ç‚¹ä½è¿›è¡Œåˆ†ç»„
        Map<String, List<ModelNodeIndexInfor>> nodeIndexMap = nodeInforList.stream().collect(
                Collectors.groupingBy(ModelNodeIndexInfor::getNodeId));
        // èŽ·å–æŸ¥è¯¢æ—¶é—´
        Date beginTime = dto.getBeginTime();
        Date endTime = dto.getEndTime();
        // åŒæ¯”æ—¶é—´
        Date lastTime = DateUtil.offset(beginTime, DateField.YEAR, CommonConst.DIGIT_MINUS_1);
        Date lastEndTime = DateUtil.offset(endTime, DateField.YEAR, CommonConst.DIGIT_MINUS_1);
        // æŸ¥è¯¢å¯¹åº”indexIds,找到对应dataItem信息
        List<DataItem> dataItemList = dataItemService.getDataItemHourInforByIndexIds(beginTime, endTime, TimeType.HOUR.name(), indexIds);
        List<DataItem> lastDataItemList = dataItemService.getDataItemHourInforByIndexIds(lastTime, lastEndTime, TimeType.HOUR.name(), indexIds);
        //  å€çއ
        BigDecimal multiple = BigDecimal.valueOf(CommonConst.DIGIT_100);
        nodeIndexMap.forEach((key, value) -> {
            DataAnalysisYoYVO yoyVO = new DataAnalysisYoYVO();
            Optional<ModelNodeIndexInfor> first = value.stream().findFirst();
            first.ifPresent(modelNodeIndexInfor -> yoyVO.setEnergyUnitName(modelNodeIndexInfor.getName()));
            // èµ‹å€¼å•位
            yoyVO.setUnit("kWh");
            // æ‰¾å‡ºindexIds
            List<String> indexIdList = value.stream().map(ModelNodeIndexInfor::getIndexId).collect(Collectors.toList());
            // æ±‚å’Œ
            BigDecimal sum = BigDecimal.valueOf(dataItemList.stream().filter(li -> indexIdList.contains(li.getIndexId()))
                    .mapToDouble(DataItem::getValue).sum()).setScale(CommonConst.DIGIT_2, RoundingMode.HALF_UP);
            BigDecimal lastSum = BigDecimal.valueOf(lastDataItemList.stream().filter(li -> indexIdList.contains(li.getIndexId()))
                    .mapToDouble(DataItem::getValue).sum()).setScale(CommonConst.DIGIT_2, RoundingMode.HALF_UP);
            yoyVO.setCurrentValue(sum);
            yoyVO.setOldValue(lastSum);
            //  åŒæ¯”值
            BigDecimal ratio = BigDecimal.ZERO;
            if (lastSum.compareTo(BigDecimal.ZERO) != 0) {
                ratio = sum.subtract(lastSum).divide(lastSum, CommonConst.DIGIT_2, RoundingMode.HALF_UP).multiply(multiple);
            }
            yoyVO.setRatio(ratio);
            yoyList.add(yoyVO);
        });
        return yoyList;
    }
    /**
     * èŽ·å–ç”µèƒ½è€—çŽ¯æ¯”æ•°æ®
     */
    @Override
    public List<DataAnalysisMoMVO> listElectricDataComparisonMoM(DataAnalysisMoMDTO dto) {
        List<DataAnalysisMoMVO> momList = new ArrayList<>();
        // æ ¹æ®id查询点位信息
        List<ModelNodeIndexInfor> nodeIndexInforList = listModelNodeIndexIdRelationInfor(dto.getNodeId());
        if (CollectionUtils.isEmpty(nodeIndexInforList)) {
            return momList;
        }
        List<String> indexIds = nodeIndexInforList.stream().map(ModelNodeIndexInfor::getIndexId).collect(Collectors.toList());
        Date beginTime = dto.getBeginTime();
        Date endTime = dto.getEndTime();
        Date lastTime;
        Date lastEndTime;
        String queryTimeType = dto.getTimeType();
        // å°æ—¶
        if (TimeTypeConst.TIME_TYPE_HOUR.equals(queryTimeType)) {
            lastTime = DateUtil.offsetHour(beginTime, CommonConst.DIGIT_MINUS_1);
            lastEndTime = DateUtil.offsetHour(endTime, CommonConst.DIGIT_MINUS_1);
            // å¤©
        } else if (TimeTypeConst.TIME_TYPE_DAY.equals(queryTimeType)) {
            lastTime = DateUtil.offsetDay(beginTime, CommonConst.DIGIT_MINUS_1);
            lastEndTime = DateUtil.offsetDay(endTime, CommonConst.DIGIT_MINUS_1);
            // æœˆ
        } else if (TimeTypeConst.TIME_TYPE_MONTH.equals(queryTimeType)) {
            lastTime = DateUtil.offsetMonth(beginTime, CommonConst.DIGIT_MINUS_1);
            lastEndTime = DateUtil.offsetMonth(endTime, CommonConst.DIGIT_MINUS_1);
            // å¹´
        } else {
            lastTime = DateUtil.offset(beginTime, DateField.YEAR, CommonConst.DIGIT_MINUS_1);
            lastEndTime = DateUtil.offset(endTime, DateField.YEAR, CommonConst.DIGIT_MINUS_1);
        }
        // æŒ‰ç…§ç‚¹ä½è¿›è¡Œåˆ†ç»„
        Map<String, List<ModelNodeIndexInfor>> nodeIndexMap = nodeIndexInforList.stream().collect(
                Collectors.groupingBy(ModelNodeIndexInfor::getNodeId));
        // æ ¹æ®indexId查询dataItem
        List<DataItem> dataItemList = dataItemService.getDataItemHourInforByIndexIds(beginTime, endTime, TimeType.HOUR.name(), indexIds);
        List<DataItem> lastDataItemList = dataItemService.getDataItemHourInforByIndexIds(lastTime, lastEndTime, TimeType.HOUR.name(), indexIds);
        //  å€çއ
        BigDecimal multiple = BigDecimal.valueOf(CommonConst.DIGIT_100);
        nodeIndexMap.forEach((key, value) -> {
            DataAnalysisMoMVO momVO = new DataAnalysisMoMVO();
            Optional<ModelNodeIndexInfor> first = value.stream().findFirst();
            first.ifPresent(modelNodeIndexInfor -> momVO.setEnergyUnitName(modelNodeIndexInfor.getName()));
            // èµ‹å€¼å•位
            momVO.setUnit("kWh");
            // æ‰¾å‡ºindexIds
            List<String> indexIdList = value.stream().map(ModelNodeIndexInfor::getIndexId).collect(Collectors.toList());
            // æ±‚å’Œ
            BigDecimal sum = BigDecimal.valueOf(dataItemList.stream().filter(li -> indexIdList.contains(li.getIndexId()))
                    .mapToDouble(DataItem::getValue).sum()).setScale(CommonConst.DIGIT_2, RoundingMode.HALF_UP);
            BigDecimal lastSum = BigDecimal.valueOf(lastDataItemList.stream().filter(li -> indexIdList.contains(li.getIndexId()))
                    .mapToDouble(DataItem::getValue).sum()).setScale(CommonConst.DIGIT_2, RoundingMode.HALF_UP);
            momVO.setCurrentValue(sum);
            momVO.setOldValue(lastSum);
            //  åŒæ¯”值
            BigDecimal ratio = BigDecimal.ZERO;
            if (lastSum.compareTo(BigDecimal.ZERO) != 0) {
                ratio = sum.subtract(lastSum).divide(lastSum, CommonConst.DIGIT_2, RoundingMode.HALF_UP).multiply(multiple);
            }
            momVO.setRatio(ratio);
            momList.add(momVO);
        });
        return momList;
    }
    /**
     * èŽ·å–èƒ½è€—åŒæ¯”æ•°æ®
     */
    @Override
    public List<DataAnalysisYoYVO> listWaterDataComparisonYoY(DataAnalysisMoMDTO dto) {
        List<DataAnalysisYoYVO> yoyList = new ArrayList<>();
        // æŸ¥è¯¢ç‚¹ä½ä¸Žç”¨èƒ½å•元信息
        List<ModelNodeIndexInfor> nodeInforList = listModelNodeIndexIdRelationInfor(dto.getNodeId());
        if (CollectionUtils.isEmpty(nodeInforList)) {
            return yoyList;
        }
        List<String> indexIds = nodeInforList.stream().map(ModelNodeIndexInfor::getIndexId).collect(Collectors.toList());
        // æŒ‰ç…§ç‚¹ä½è¿›è¡Œåˆ†ç»„
        Map<String, List<ModelNodeIndexInfor>> nodeIndexMap = nodeInforList.stream().collect(
                Collectors.groupingBy(ModelNodeIndexInfor::getNodeId));
        // æ—¶é—´ç±»åž‹
        // èŽ·å–æŸ¥è¯¢æ—¶é—´
        Date beginTime = dto.getBeginTime();
        Date endTime = dto.getEndTime();
        // åŒæ¯”æ—¶é—´
        Date lastTime = DateUtil.offset(beginTime, DateField.YEAR, CommonConst.DIGIT_MINUS_1);
        Date lastEndTime = DateUtil.offset(endTime, DateField.YEAR, CommonConst.DIGIT_MINUS_1);
        // æŸ¥è¯¢å¯¹åº”indexIds,找到对应dataItem信息
        List<DataItem> dataItemList = dataItemService.getDataItemHourInforByIndexIds(beginTime, endTime, TimeType.HOUR.name(), indexIds);
        List<DataItem> lastDataItemList = dataItemService.getDataItemHourInforByIndexIds(lastTime, lastEndTime, TimeType.HOUR.name(), indexIds);
        //  å€çއ
        BigDecimal multiple = BigDecimal.valueOf(CommonConst.DIGIT_100);
        nodeIndexMap.forEach((key, value) -> {
            DataAnalysisYoYVO yoyVO = new DataAnalysisYoYVO();
            Optional<ModelNodeIndexInfor> first = value.stream().findFirst();
            first.ifPresent(modelNodeIndexInfor -> yoyVO.setEnergyUnitName(modelNodeIndexInfor.getName()));
            // èµ‹å€¼å•位
            yoyVO.setUnit("m³");
            // æ‰¾å‡ºindexIds
            List<String> indexIdList = value.stream().map(ModelNodeIndexInfor::getIndexId).collect(Collectors.toList());
            // æ±‚å’Œ
            BigDecimal sum = BigDecimal.valueOf(dataItemList.stream().filter(li -> indexIdList.contains(li.getIndexId()))
                    .mapToDouble(DataItem::getValue).sum()).setScale(CommonConst.DIGIT_2, RoundingMode.HALF_UP);
            BigDecimal lastSum = BigDecimal.valueOf(lastDataItemList.stream().filter(li -> indexIdList.contains(li.getIndexId()))
                    .mapToDouble(DataItem::getValue).sum()).setScale(CommonConst.DIGIT_2, RoundingMode.HALF_UP);
            yoyVO.setCurrentValue(sum);
            yoyVO.setOldValue(lastSum);
            //  åŒæ¯”值
            BigDecimal ratio = BigDecimal.ZERO;
            if (lastSum.compareTo(BigDecimal.ZERO) != 0) {
                ratio = sum.subtract(lastSum).divide(lastSum, CommonConst.DIGIT_2, RoundingMode.HALF_UP).multiply(multiple);
            }
            yoyVO.setRatio(ratio);
            yoyList.add(yoyVO);
        });
        return yoyList;
    }
    /**
     * èŽ·å–èƒ½è€—çŽ¯æ¯”æ•°æ®
     */
    @Override
    public List<DataAnalysisMoMVO> listWaterDataComparisonMoM(DataAnalysisMoMDTO dto) {
        List<DataAnalysisMoMVO> momList = new ArrayList<>();
        // æ ¹æ®id查询点位信息
        List<ModelNodeIndexInfor> nodeIndexInforList = listModelNodeIndexIdRelationInfor(dto.getNodeId());
        if (CollectionUtils.isEmpty(nodeIndexInforList)) {
            return momList;
        }
        List<String> indexIds = nodeIndexInforList.stream().map(ModelNodeIndexInfor::getIndexId).collect(Collectors.toList());
        Date beginTime = dto.getBeginTime();
        Date endTime = dto.getEndTime();
        Date lastTime;
        Date lastEndTime;
        String queryTimeType = dto.getTimeType();
        // å°æ—¶
        if (TimeTypeConst.TIME_TYPE_HOUR.equals(queryTimeType)) {
            lastTime = DateUtil.offsetHour(beginTime, CommonConst.DIGIT_MINUS_1);
            lastEndTime = DateUtil.offsetHour(endTime, CommonConst.DIGIT_MINUS_1);
            // å¤©
        } else if (TimeTypeConst.TIME_TYPE_DAY.equals(queryTimeType)) {
            lastTime = DateUtil.offsetDay(beginTime, CommonConst.DIGIT_MINUS_1);
            lastEndTime = DateUtil.offsetDay(endTime, CommonConst.DIGIT_MINUS_1);
            // æœˆ
        } else if (TimeTypeConst.TIME_TYPE_MONTH.equals(queryTimeType)) {
            lastTime = DateUtil.offsetMonth(beginTime, CommonConst.DIGIT_MINUS_1);
            lastEndTime = DateUtil.offsetMonth(endTime, CommonConst.DIGIT_MINUS_1);
            // å¹´
        } else {
            lastTime = DateUtil.offset(beginTime, DateField.YEAR, CommonConst.DIGIT_MINUS_1);
            lastEndTime = DateUtil.offset(endTime, DateField.YEAR, CommonConst.DIGIT_MINUS_1);
        }
        // æŒ‰ç…§ç‚¹ä½è¿›è¡Œåˆ†ç»„
        Map<String, List<ModelNodeIndexInfor>> nodeIndexMap = nodeIndexInforList.stream().collect(
                Collectors.groupingBy(ModelNodeIndexInfor::getNodeId));
        // æŸ¥è¯¢å¯¹åº”indexIds,找到对应dataItem信息
        List<DataItem> dataItemList = dataItemService.getDataItemHourInforByIndexIds(beginTime, endTime, TimeType.HOUR.name(), indexIds);
        List<DataItem> lastDataItemList = dataItemService.getDataItemHourInforByIndexIds(lastTime, lastEndTime, TimeType.HOUR.name(), indexIds);
        //  å€çއ
        BigDecimal multiple = BigDecimal.valueOf(CommonConst.DIGIT_100);
        nodeIndexMap.forEach((key, value) -> {
            DataAnalysisMoMVO momVO = new DataAnalysisMoMVO();
            Optional<ModelNodeIndexInfor> first = value.stream().findFirst();
            first.ifPresent(modelNodeIndexInfor -> momVO.setEnergyUnitName(modelNodeIndexInfor.getName()));
            // èµ‹å€¼å•位
            momVO.setUnit("m³");
            // æ‰¾å‡ºindexIds
            List<String> indexIdList = value.stream().map(ModelNodeIndexInfor::getIndexId).collect(Collectors.toList());
            // æ±‚å’Œ
            BigDecimal sum = BigDecimal.valueOf(dataItemList.stream().filter(li -> indexIdList.contains(li.getIndexId()))
                    .mapToDouble(DataItem::getValue).sum()).setScale(CommonConst.DIGIT_2, RoundingMode.HALF_UP);
            BigDecimal lastSum = BigDecimal.valueOf(lastDataItemList.stream().filter(li -> indexIdList.contains(li.getIndexId()))
                    .mapToDouble(DataItem::getValue).sum()).setScale(CommonConst.DIGIT_2, RoundingMode.HALF_UP);
            momVO.setCurrentValue(sum);
            momVO.setOldValue(lastSum);
            //  åŒæ¯”值
            BigDecimal ratio = BigDecimal.ZERO;
            if (lastSum.compareTo(BigDecimal.ZERO) != 0) {
                ratio = sum.subtract(lastSum).divide(lastSum, CommonConst.DIGIT_2, RoundingMode.HALF_UP).multiply(multiple);
            }
            momVO.setRatio(ratio);
            momList.add(momVO);
        });
        return momList;
    }
    /**
     * æŸ¥è¯¢ç‚¹ä½ä¸Žç”¨èƒ½å•元信息
     */
    private List<ModelNodeIndexInfor> listModelNodeIndexIdRelationInfor(String nodeId) {
        List<ModelNodeIndexInfor> nodeInforList = modelNodeService.listModelNodeIndexIdRelationInforByParentId(nodeId);
        // å¦‚果是空存在两种情况,1:id有问题,2:最底层
        if (CollectionUtils.isEmpty(nodeInforList)) {
            List<ModelNodeIndexInfor> inforList = modelNodeService.getModelNodeIndexIdRelationInforByNodeId(nodeId);
            if (CollectionUtils.isNotEmpty(inforList)) {
                nodeInforList.addAll(inforList);
            }
        }
        return nodeInforList;
    }
}
zhitan-system/src/main/resources/mapper/basicSetup/SysEquipmentfileMapper.xml
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,48 @@
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.zhitan.basicSetup.mapper.SysEquipmentfileMapper">
    <resultMap id="SysEquipmentFile"
               type="com.zhitan.realtimedata.domain.SysEquipmentFile">
        <result property="nodeId" column="node_id"/>
        <result property="filePath" column="filepath"/>
    </resultMap>
    <resultMap id="SysSvgInfo"
               type="com.zhitan.realtimedata.domain.SysSvgInfo">
        <result property="id" column="id"/>
        <result property="param" column="param"/>
        <result property="tag" column="tag"/>
    </resultMap>
    <insert id="saveSettingInfo">
        delete
        from sys_svg_info
        where node_id = #{nodeId};
        <foreach collection="svgInfo" item="info" separator=";">
            insert into sys_svg_info (id, node_id, param, tag)
            values (#{info.id}, #{nodeId}, #{info.param}, #{info.tag});
        </foreach>
    </insert>
  <update id="saveEquipmentFile">
    INSERT INTO sys_equipmentfile (node_id, filepath)
    VALUES(#{nodeId}, #{filePath}) ON CONFLICT (node_id) DO
    UPDATE
    SET filepath = excluded.filepath
  </update>
    <select id="getConfigure" resultMap="SysEquipmentFile">
        select node_id, filepath
        from sys_equipmentfile
        where node_id = #{nodeId};
    </select>
    <select id="getConfigureTag" resultMap="SysSvgInfo">
        select id, param, tag
        from sys_svg_info
        where node_id = #{nodeId}
    </select>
</mapper>
zhitan-system/src/main/resources/mapper/dataitem/DataItemMapper.xml
@@ -3,7 +3,7 @@
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.zhitan.dataitem.mapper.DataItemMapper">
    <resultMap type="StagseDataEntry" id="stagseDataEntryResult">
    <resultMap type="com.zhitan.dataitem.domain.StagseDataEntry" id="stagseDataEntryResult">
        <result property="code" column="code"/>
        <result property="name" column="name"/>
        <result property="indexId" column="index_id"/>
@@ -15,7 +15,7 @@
        <result property="dataTime" column="data_time"/>
    </resultMap>
    <select id="getSettingIndex" parameterType="StagseDataEntry" resultMap="stagseDataEntryResult">
    <select id="getSettingIndex" parameterType="com.zhitan.dataitem.domain.StagseDataEntry" resultMap="stagseDataEntryResult">
        SELECT
        ei.index_id,
@@ -33,7 +33,7 @@
        and si.time_type = #{timeType}
        AND si.calc_type = #{calcType}
   </select>
    <select id="getSettingEdit" parameterType="StagseDataEntry" resultMap="stagseDataEntryResult">
    <select id="getSettingEdit" parameterType="com.zhitan.dataitem.domain.StagseDataEntry" resultMap="stagseDataEntryResult">
        SELECT
            ei.index_id,
            code,
@@ -54,7 +54,7 @@
            AND data_time &gt;= #{beginTime}
            AND data_time &lt;= #{endTime}
    </select>
    <select id="stagseDataByCode" parameterType="StagseDataEntry" resultMap="stagseDataEntryResult">
    <select id="stagseDataByCode" parameterType="com.zhitan.dataitem.domain.StagseDataEntry" resultMap="stagseDataEntryResult">
        SELECT
            ei.index_id,
            code,
@@ -199,4 +199,20 @@
        AND di.data_time BETWEEN   #{beginTime}  AND  #{endTime}
        AND di.time_type =  #{timeType}
    </select>
    <select id="getDataItemHourInforByIndexIds" resultType="com.zhitan.realtimedata.domain.DataItem">
        SELECT
        index_id indexId,
        data_time dataTime,
        "value"
        FROM
        "data_item"
        WHERE
        index_id IN
        <foreach collection="indexIds" item="indexId" open="(" separator="," close=")">
            #{indexId}
        </foreach>
        AND ( begin_time BETWEEN #{beginTime} AND #{endTime} )
        AND time_type = #{timeType}
    </select>
</mapper>
zhitan-system/src/main/resources/mapper/model/ModelNodeMapper.xml
@@ -382,7 +382,8 @@
        SELECT mn.node_id  nodeId,
               mn."name"   "name",
               ni.index_id indexId,
               ei.energy_id energyId
               ei.energy_id energyId,
               ei.index_type indexType
        FROM "model_node" mn
        LEFT JOIN "node_index" ni ON mn.node_id = ni.node_id
        LEFT JOIN energy_index ei on ni.index_id = ei.index_id
zhitan-system/src/main/resources/mapper/realtimedata/SvgTrendMapper.xml
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,37 @@
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.zhitan.realtimedata.mapper.SvgTrendMapper">
    <resultMap type="com.zhitan.model.domain.EnergyIndex" id="EnergyIndexResult">
        <result property="indexId" column="index_id"/>
        <result property="name" column="name"/>
        <result property="code" column="code"/>
        <result property="indexType" column="index_type"/>
        <result property="indexCategory" column="index_category"/>
        <result property="remark" column="remark"/>
        <result property="unitId" column="unit_id"/>
        <result property="meterId" column="meter_id"/>
        <result property="meterName" column="meter_name"/>
    </resultMap>
    <select id="selectSvgTrendList" parameterType="com.zhitan.model.domain.EnergyIndex" resultMap="EnergyIndexResult">
        select ei.index_id, name, ei.code, index_type, ei.remark, ei.unit_id, index_category,meter_name
        from
        energy_index ei,
        sys_svg_info svg,
        meter_implement as me
        <where>
            ei.code = svg.tag
            and ei.meter_id = me.id
            <if test="name != null  and name != ''">and name like concat('%', #{name}, '%')</if>
            <if test="code != null  and code != ''">and ei.code like concat('%', #{code}, '%')</if>
            <if test="indexType != null">and index_type = #{indexType}</if>
            <if test="nodeId != null  and nodeId != ''">and svg.node_id = #{nodeId}</if>
            <if test="indexCategory != null  and indexCategory != ''">and index_category =
                #{indexCategory}
            </if>
        </where>
    </select>
</mapper>
zhitan-vue/src/assets/images/font01.png
zhitan-vue/src/assets/images/img_logo.png
zhitan-vue/src/assets/images/login-background.jpg
Binary files differ
zhitan-vue/src/assets/images/login-background.png
zhitan-vue/src/assets/images/logo.png
zhitan-vue/src/views/login copy.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,293 @@
<template>
  <div class="login">
    <!-- <div
      class="login-logo-bg"
      v-if="systemInfo && systemInfo.homeLogo"
      :style="{ backgroundImage: 'url(' + systemInfo.homeLogo + ')', backgroundSize: '100% 100%' }"
    ></div> -->
    <img v-if="systemInfo && systemInfo.homeLogo" :src="systemInfo.homeLogo" alt="" class="login-logo-img" />
    <div class="login-font" v-else>{{ systemInfo.systemName || "能源管理系统" }}</div>
    <el-form ref="loginRef" :model="loginForm" :rules="loginRules" class="login-form">
      <!-- <h3 class="title">充电桩后台管理系统</h3> -->
      <el-form-item prop="username">
        <el-input v-model="loginForm.username" type="text" size="large" auto-complete="off" placeholder="账号">
          <template #prefix><svg-icon icon-class="user" class="el-input__icon input-icon" /></template>
        </el-input>
      </el-form-item>
      <el-form-item prop="password">
        <el-input
          v-model="loginForm.password"
          type="password"
          size="large"
          auto-complete="off"
          placeholder="密码"
          show-password
          @keyup.enter="handleLogin"
        >
          <template #prefix><svg-icon icon-class="password" class="el-input__icon input-icon" /></template>
        </el-input>
      </el-form-item>
      <el-form-item prop="code" v-if="captchaEnabled">
        <el-input
          v-model="loginForm.code"
          size="large"
          auto-complete="off"
          placeholder="验证码"
          style="width: 63%"
          @keyup.enter="handleLogin"
        >
          <template #prefix><svg-icon icon-class="validCode" class="el-input__icon input-icon" /></template>
        </el-input>
        <div class="login-code">
          <img :src="codeUrl" @click="getCode" class="login-code-img" />
        </div>
      </el-form-item>
      <el-checkbox v-model="loginForm.rememberMe" style="margin: 0px 0px 25px 0px">记住密码</el-checkbox>
      <el-form-item style="width: 100%">
        <el-button
          :loading="loading"
          size="large"
          type="primary"
          style="width: 100%"
          color="#626aef"
          :dark="isDark"
          @click.prevent="handleLogin"
        >
          <span v-if="!loading">登 å½•</span>
          <span v-else>登 å½• ä¸­...</span>
        </el-button>
      </el-form-item>
    </el-form>
    <!--  åº•部  -->
    <div class="el-login-footer">
      <!-- <span>Copyright Â© 2021-2024 ZhiTanCloud All Rights Reserved.</span> -->
      <span>{{ systemInfo.copyRight || "Copyright Â© 2017-2024 ZhiTanCloud All Rights Reserved." }}</span>
    </div>
  </div>
</template>
<script setup>
import { getCodeImg } from "@/api/login"
import Cookies from "js-cookie"
import { encrypt, decrypt } from "@/utils/jsencrypt"
import useUserStore from "@/store/modules/user"
const userStore = useUserStore()
const route = useRoute()
const router = useRouter()
const { proxy } = getCurrentInstance()
const systemInfo1 = JSON.parse(Cookies.get("SystemInfo") || "{}")
const systemInfo = {
  ...systemInfo1,
  homeLogo: systemInfo1.homeLogo
    ? systemInfo1.homeLogo.includes("http")
      ? systemInfo1.homeLogo
      : "https://demo-ems.zhitancloud.com" + systemInfo1.homeLogo
    : "",
}
console.log(systemInfo)
const loginForm = ref({
  username: "admin",
  password: "admin123",
  rememberMe: false,
  code: "",
  uuid: "",
})
const loginRules = {
  username: [{ required: true, trigger: "blur", message: "请输入您的账号" }],
  password: [{ required: true, trigger: "blur", message: "请输入您的密码" }],
  code: [{ required: true, trigger: "change", message: "请输入验证码" }],
}
const codeUrl = ref("")
const loading = ref(false)
// éªŒè¯ç å¼€å…³
const captchaEnabled = ref(true)
// æ³¨å†Œå¼€å…³
const register = ref(false)
const redirect = ref(undefined)
watch(
  route,
  (newRoute) => {
    redirect.value = newRoute.query && newRoute.query.redirect
  },
  { immediate: true }
)
function handleLogin() {
  proxy.$refs.loginRef.validate((valid) => {
    if (valid) {
      loading.value = true
      // å‹¾é€‰äº†éœ€è¦è®°ä½å¯†ç è®¾ç½®åœ¨ cookie ä¸­è®¾ç½®è®°ä½ç”¨æˆ·åå’Œå¯†ç 
      if (loginForm.value.rememberMe) {
        Cookies.set("username", loginForm.value.username, { expires: 30 })
        Cookies.set("password", encrypt(loginForm.value.password), { expires: 30 })
        Cookies.set("rememberMe", loginForm.value.rememberMe, { expires: 30 })
      } else {
        // å¦åˆ™ç§»é™¤
        Cookies.remove("username")
        Cookies.remove("password")
        Cookies.remove("rememberMe")
      }
      // è°ƒç”¨action的登录方法
      userStore
        .login(loginForm.value)
        .then(() => {
          const query = route.query
          const otherQueryParams = Object.keys(query).reduce((acc, cur) => {
            if (cur !== "redirect") {
              acc[cur] = query[cur]
            }
            return acc
          }, {})
          router.push({ path: redirect.value || "/", query: otherQueryParams })
        })
        .catch(() => {
          loading.value = false
          // é‡æ–°èŽ·å–éªŒè¯ç 
          if (captchaEnabled.value) {
            getCode()
          }
        })
    }
  })
}
function getCode() {
  getCodeImg().then((res) => {
    captchaEnabled.value = res.captchaEnabled === undefined ? true : res.captchaEnabled
    if (captchaEnabled.value) {
      codeUrl.value = "data:image/gif;base64," + res.img
      loginForm.value.uuid = res.uuid
    }
  })
}
function getCookie() {
  const username = Cookies.get("username")
  const password = Cookies.get("password")
  const rememberMe = Cookies.get("rememberMe")
  loginForm.value = {
    username: username === undefined ? loginForm.value.username : username,
    password: password === undefined ? loginForm.value.password : decrypt(password),
    rememberMe: rememberMe === undefined ? false : Boolean(rememberMe),
  }
}
getCode()
getCookie()
</script>
<style lang="scss" scoped>
.login {
  display: flex;
  align-items: center;
  height: 100%;
  background-image: url("@/assets/images/login-bg.jpg");
  background-size: 100% 100%;
  flex-direction: column;
  position: relative;
  min-width: 700px;
  min-height: 700px;
}
.title {
  margin: 0px auto 30px auto;
  text-align: center;
  color: #707070;
}
.login-form {
  position: absolute;
  left: 50%;
  top: 60%;
  transform: translate(-50%, -50%);
  border-radius: 6px;
  // background: #ffffff;
  width: 400px;
  padding: 25px 25px 5px 25px;
  .el-input {
    height: 40px;
    input {
      height: 40px;
    }
  }
  .input-icon {
    height: 39px;
    width: 14px;
    margin-left: 0px;
  }
}
.login-tip {
  font-size: 13px;
  text-align: center;
  color: #bfbfbf;
}
.login-code {
  width: 33%;
  height: 40px;
  float: right;
  img {
    cursor: pointer;
    vertical-align: middle;
  }
}
.el-login-footer {
  height: 40px;
  line-height: 40px;
  position: fixed;
  bottom: 0;
  width: 100%;
  text-align: center;
  color: #fff;
  font-family: Arial;
  font-size: 12px;
  letter-spacing: 1px;
}
.login-code-img {
  height: 40px;
  padding-left: 12px;
}
.login-logo-bg {
  width: 514px;
  height: 177px;
  // background-image: url('@/assets/images/login-logo.png');
  // background-size: 100% 100%;
  position: absolute;
  left: 50%;
  top: 22%;
  transform: translate(-50%, -50%);
}
.login-logo-img {
  // width: 100%;
  // height: 100%;
  // transform: translate(-50%, -50%);
  max-height: 200px;
  margin: 0 auto;
  position: absolute;
  top: 17%;
}
.login-font {
  font-size: 50px;
  color: #fff;
  top: 32%;
  position: absolute;
  left: 50%;
  width: 514px;
  text-align: center;
  transform: translate(-50%, -50%);
}
</style>
zhitan-vue/src/views/login.vue
@@ -1,67 +1,83 @@
<template>
  <div class="login">
    <!-- <div
      class="login-logo-bg"
      v-if="systemInfo && systemInfo.homeLogo"
      :style="{ backgroundImage: 'url(' + systemInfo.homeLogo + ')', backgroundSize: '100% 100%' }"
    ></div> -->
    <img v-if="systemInfo && systemInfo.homeLogo" :src="systemInfo.homeLogo" alt="" class="login-logo-img" />
    <div class="login-font" v-else>{{ systemInfo.systemName || "能源管理系统" }}</div>
    <el-form ref="loginRef" :model="loginForm" :rules="loginRules" class="login-form">
      <!-- <h3 class="title">充电桩后台管理系统</h3> -->
      <el-form-item prop="username">
        <el-input v-model="loginForm.username" type="text" size="large" auto-complete="off" placeholder="账号">
          <template #prefix><svg-icon icon-class="user" class="el-input__icon input-icon" /></template>
        </el-input>
      </el-form-item>
      <el-form-item prop="password">
        <el-input
          v-model="loginForm.password"
          type="password"
          size="large"
          auto-complete="off"
          placeholder="密码"
          show-password
          @keyup.enter="handleLogin"
        >
          <template #prefix><svg-icon icon-class="password" class="el-input__icon input-icon" /></template>
        </el-input>
      </el-form-item>
      <el-form-item prop="code" v-if="captchaEnabled">
        <el-input
          v-model="loginForm.code"
          size="large"
          auto-complete="off"
          placeholder="验证码"
          style="width: 63%"
          @keyup.enter="handleLogin"
        >
          <template #prefix><svg-icon icon-class="validCode" class="el-input__icon input-icon" /></template>
        </el-input>
        <div class="login-code">
          <img :src="codeUrl" @click="getCode" class="login-code-img" />
    <!-- <img v-if="systemInfo && systemInfo.homeLogo" :src="systemInfo.homeLogo" alt="" class="login-logo-img" />
    <div class="login-font" v-else>{{ systemInfo.systemName || "能源管理系统" }}</div> -->
    <!-- å·¦ä¸Šè§’logo -->
    <div>
      <img v-if="systemInfo && systemInfo.homeLogo" :src="systemInfo.homeLogo" alt="" class="login-logo-img" />
    </div>
    <!-- ä¸­é—´éƒ¨åˆ†form -->
    <div class="middle-view">
      <div class="left-wrapper">
        <div class="login-font">{{ systemInfo.systemName || "" }}</div>
        <img src="@/assets/images/font01.png" alt="" style="width: 406px" />
        <img src="@/assets/images/img_logo.png" alt="" style="width: 200px; margin-top: 20px" />
      </div>
      <div class="right-wrapper">
        <div class="header">
          <span>账号登录</span>
        </div>
      </el-form-item>
      <el-checkbox v-model="loginForm.rememberMe" style="margin: 0px 0px 25px 0px">记住密码</el-checkbox>
      <el-form-item style="width: 100%">
        <el-button
          :loading="loading"
          size="large"
          type="primary"
          style="width: 100%"
          color="#626aef"
          :dark="isDark"
          @click.prevent="handleLogin"
        >
          <span v-if="!loading">登 å½•</span>
          <span v-else>登 å½• ä¸­...</span>
        </el-button>
      </el-form-item>
    </el-form>
        <div class="bottom-block"></div>
        <el-form ref="loginRef" :model="loginForm" :rules="loginRules" class="login-form" :label-position="'top'">
          <el-form-item prop="username" label="账号">
            <el-input v-model="loginForm.username" type="text" size="large" auto-complete="off" placeholder="账号">
              <!-- <template #prefix><svg-icon icon-class="user" class="el-input__icon input-icon" /></template> -->
            </el-input>
          </el-form-item>
          <el-form-item prop="password" label="密码">
            <el-input
              v-model="loginForm.password"
              type="password"
              size="large"
              auto-complete="off"
              placeholder="密码"
              show-password
              @keyup.enter="handleLogin"
            >
              <!-- <template #prefix><svg-icon icon-class="password" class="el-input__icon input-icon" /></template> -->
            </el-input>
          </el-form-item>
          <el-form-item prop="code" v-if="captchaEnabled" label="验证码">
            <el-input
              v-model="loginForm.code"
              size="large"
              auto-complete="off"
              placeholder="验证码"
              style="width: 266px"
              @keyup.enter="handleLogin"
            >
              <!-- <template #prefix><svg-icon icon-class="validCode" class="el-input__icon input-icon" /></template> -->
            </el-input>
            <div class="login-code">
              <img :src="codeUrl" @click="getCode" class="login-code-img" />
            </div>
          </el-form-item>
          <el-checkbox v-model="loginForm.rememberMe" style="margin: 0px 0px 25px 0px">记住密码</el-checkbox>
          <el-form-item style="width: 100%">
            <el-button
              :loading="loading"
              size="large"
              type="primary"
              style="width: 100%"
              color="#626aef"
              :dark="isDark"
              @click.prevent="handleLogin"
              class="submit-btn"
            >
              <span v-if="!loading">登 å½•</span>
              <span v-else>登 å½• ä¸­...</span>
            </el-button>
          </el-form-item>
        </el-form>
      </div>
    </div>
    <!--  åº•部  -->
    <div class="el-login-footer">
      <!-- <span>Copyright Â© 2021-2024 ZhiTanCloud All Rights Reserved.</span> -->
      <span>{{ systemInfo.copyRight || "Copyright Â© 2017-2024 ZhiTanCloud All Rights Reserved." }}</span>
      <span>{{
        systemInfo.copyRight || "Copyright Â© 2017-" + new Date().getFullYear() + " ZhiTanCloud All Rights Reserved."
      }}</span>
    </div>
  </div>
</template>
@@ -76,12 +92,20 @@
const route = useRoute()
const router = useRouter()
const { proxy } = getCurrentInstance()
const systemInfo = JSON.parse(Cookies.get("SystemInfo") || "{}")
const systemInfo1 = JSON.parse(Cookies.get("SystemInfo") || "{}")
const systemInfo = {
  ...systemInfo1,
  homeLogo: systemInfo1.homeLogo
    ? systemInfo1.homeLogo.includes("http")
      ? systemInfo1.homeLogo
      : "https://demo-ems.zhitancloud.com" + systemInfo1.homeLogo
    : "",
}
console.log(systemInfo)
const loginForm = ref({
  username: "admin",
  password: "admin123",
  username: "guestUser",
  password: "guest@123456",
  rememberMe: false,
  code: "",
  uuid: "",
@@ -178,29 +202,93 @@
  display: flex;
  align-items: center;
  height: 100%;
  background-image: url("@/assets/images/login-bg.jpg");
  background-size: 100% 100%;
  background-image: url("@/assets/images/login-background.png");
  background-repeat: no-repeat;
  background-size: cover;
  flex-direction: column;
  position: relative;
  min-width: 700px;
  min-height: 700px;
}
.title {
  margin: 0px auto 30px auto;
  text-align: center;
  color: #707070;
.middle-view {
  display: flex;
  align-items: center;
  justify-content: space-around;
  height: 100%;
  width: 1200px;
  .left-wrapper {
    width: 420px;
    display: flex;
    flex-direction: column;
  }
  .login-font {
    font-size: 34px;
    font-weight: 700;
    color: #d5f8ff;
    margin-bottom: 12px;
  }
}
.right-wrapper {
  border-radius: 23px;
  background: #ffffff;
  width: 480px;
  position: relative;
  .header {
    height: 70px;
    line-height: 70px;
    border-bottom: 1px solid #f1f1f1;
    color: #3b3b3b;
    font-size: 22px;
    margin-bottom: 22px;
    span {
      display: inline-block;
      height: 70px;
      line-height: 70px;
      border-bottom: 6px solid #3a83fc;
      margin-left: 50px;
    }
  }
}
:deep(.el-input__wrapper) {
  background-color: #f7f8fa !important;
  border: none;
}
:deep(.el-input__inner) {
  color: #3b3b3b;
}
:deep(.el-form-item__label) {
  color: #3b3b3b !important;
}
:deep(.el-checkbox__label) {
  color: #2e2e2e;
}
.bottom-block {
  height: 140px;
  width: 90%;
  background-color: rgba(255, 255, 255, 0.3);
  position: absolute;
  left: 5%;
  bottom: -20px;
  border-radius: 20px;
}
.login-form {
  position: absolute;
  left: 50%;
  top: 60%;
  transform: translate(-50%, -50%);
  border-radius: 6px;
  // background: #ffffff;
  width: 400px;
  padding: 25px 25px 5px 25px;
  padding: 0 50px 30px;
  .submit-btn {
    width: 382px;
    height: 54px;
    background: #3a83fc;
    border-radius: 3px;
    font-size: 20px;
    box-shadow: 1px 2px 5px #3a83fc;
    border: none;
    border-radius: 6px;
  }
  .el-input {
    height: 40px;
@@ -224,7 +312,7 @@
}
.login-code {
  width: 33%;
  // width: 120px;
  height: 40px;
  float: right;
@@ -232,54 +320,29 @@
    cursor: pointer;
    vertical-align: middle;
  }
  .login-code-img {
    height: 40px;
    // padding-left: 12px;
  }
}
.login-logo-img {
  max-height: 100px;
  margin: 0 auto;
  position: absolute;
  top: 35px;
  left: 65px;
}
.el-login-footer {
  height: 40px;
  line-height: 40px;
  height: 60px;
  line-height: 60px;
  position: fixed;
  bottom: 0;
  width: 100%;
  text-align: center;
  color: #fff;
  font-family: Arial;
  font-size: 12px;
  font-size: 16px;
  letter-spacing: 1px;
}
.login-code-img {
  height: 40px;
  padding-left: 12px;
}
.login-logo-bg {
  width: 514px;
  height: 177px;
  // background-image: url('@/assets/images/login-logo.png');
  // background-size: 100% 100%;
  position: absolute;
  left: 50%;
  top: 22%;
  transform: translate(-50%, -50%);
}
.login-logo-img {
  // width: 100%;
  // height: 100%;
  // transform: translate(-50%, -50%);
  max-height: 200px;
  margin: 0 auto;
  position: absolute;
  top: 17%;
}
.login-font {
  font-size: 50px;
  color: #fff;
  top: 32%;
  position: absolute;
  left: 50%;
  width: 514px;
  text-align: center;
  transform: translate(-50%, -50%);
}
</style>