VVT789
2025-02-10 6c5150dfdd69a9c1d5db9c9780f721759b0e0e9c
Merge branch 'develop1.0' into wt_from_develop1.0
已添加25个文件
已删除1个文件
已修改9个文件
3138 ■■■■ 文件已修改
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-common/src/main/java/com/zhitan/common/config/BaseConfig.java 4 ●●●● 补丁 | 查看 | 原始文档 | 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/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/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/service/RealtimeDatabaseService.java 14 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zhitan-system/src/main/java/com/zhitan/realtimedata/service/impl/RealtimeDatabaseServiceImpl.java 12 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zhitan-system/src/main/resources/mapper/basicSetup/SysEquipmentfileMapper.xml 48 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zhitan-vue/index.html 385 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zhitan-vue/package.json 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
zhitan-vue/public/logo.png 补丁 | 查看 | 原始文档 | blame | 历史
zhitan-vue/src/api/svg/equipmentfile.js 40 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zhitan-vue/src/assets/images/login-background.jpg 补丁 | 查看 | 原始文档 | blame | 历史
zhitan-vue/src/components/FileUpload/index.vue 12 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zhitan-vue/src/views/index.vue 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zhitan-vue/src/views/login copy.vue 293 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zhitan-vue/src/views/login.vue 38 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zhitan-vue/src/views/svg/components/configure.vue 204 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zhitan-vue/src/views/svg/components/configureView.vue 124 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zhitan-vue/src/views/svg/equipmentfile/chartView.vue 314 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zhitan-vue/src/views/svg/equipmentfile/index.vue 243 ●●●●● 补丁 | 查看 | 原始文档 | 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-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-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/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/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/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/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-vue/index.html
@@ -1,215 +1,214 @@
<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
  <meta name="renderer" content="webkit">
  <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no">
  <link rel="icon" href="/favicon.ico">
  <title>管理系统</title>
  <!--[if lt IE 11]><script>window.location.href='/html/ie.html';</script><![endif]-->
  <style>
    html,
    body,
    #app {
      height: 100%;
      margin: 0px;
      padding: 0px;
    }
    .chromeframe {
      margin: 0.2em 0;
      background: #ccc;
      color: #000;
      padding: 0.2em 0;
    }
    #loader-wrapper {
      position: fixed;
      top: 0;
      left: 0;
      width: 100%;
      height: 100%;
      z-index: 999999;
    }
    #loader {
      display: block;
      position: relative;
      left: 50%;
      top: 50%;
      width: 150px;
      height: 150px;
      margin: -75px 0 0 -75px;
      border-radius: 50%;
      border: 3px solid transparent;
      border-top-color: #FFF;
      -webkit-animation: spin 2s linear infinite;
      -ms-animation: spin 2s linear infinite;
      -moz-animation: spin 2s linear infinite;
      -o-animation: spin 2s linear infinite;
      animation: spin 2s linear infinite;
      z-index: 1001;
    }
    #loader:before {
      content: "";
      position: absolute;
      top: 5px;
      left: 5px;
      right: 5px;
      bottom: 5px;
      border-radius: 50%;
      border: 3px solid transparent;
      border-top-color: #FFF;
      -webkit-animation: spin 3s linear infinite;
      -moz-animation: spin 3s linear infinite;
      -o-animation: spin 3s linear infinite;
      -ms-animation: spin 3s linear infinite;
      animation: spin 3s linear infinite;
    }
    #loader:after {
      content: "";
      position: absolute;
      top: 15px;
      left: 15px;
      right: 15px;
      bottom: 15px;
      border-radius: 50%;
      border: 3px solid transparent;
      border-top-color: #FFF;
      -moz-animation: spin 1.5s linear infinite;
      -o-animation: spin 1.5s linear infinite;
      -ms-animation: spin 1.5s linear infinite;
      -webkit-animation: spin 1.5s linear infinite;
      animation: spin 1.5s linear infinite;
    }
    @-webkit-keyframes spin {
      0% {
        -webkit-transform: rotate(0deg);
        -ms-transform: rotate(0deg);
        transform: rotate(0deg);
  <head>
    <meta charset="utf-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1" />
    <meta name="renderer" content="webkit" />
    <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no" />
    <link rel="icon" href="/logo.png" />
    <title>管理系统</title>
    <!--[if lt IE 11
      ]><script>
        window.location.href = "/html/ie.html"
      </script><!
    [endif]-->
    <style>
      html,
      body,
      #app {
        height: 100%;
        margin: 0px;
        padding: 0px;
      }
      100% {
        -webkit-transform: rotate(360deg);
        -ms-transform: rotate(360deg);
        transform: rotate(360deg);
      }
    }
    @keyframes spin {
      0% {
        -webkit-transform: rotate(0deg);
        -ms-transform: rotate(0deg);
        transform: rotate(0deg);
      .chromeframe {
        margin: 0.2em 0;
        background: #ccc;
        color: #000;
        padding: 0.2em 0;
      }
      100% {
        -webkit-transform: rotate(360deg);
        -ms-transform: rotate(360deg);
        transform: rotate(360deg);
      #loader-wrapper {
        position: fixed;
        top: 0;
        left: 0;
        width: 100%;
        height: 100%;
        z-index: 999999;
      }
    }
      #loader {
        display: block;
        position: relative;
        left: 50%;
        top: 50%;
        width: 150px;
        height: 150px;
        margin: -75px 0 0 -75px;
        border-radius: 50%;
        border: 3px solid transparent;
        border-top-color: #fff;
        -webkit-animation: spin 2s linear infinite;
        -ms-animation: spin 2s linear infinite;
        -moz-animation: spin 2s linear infinite;
        -o-animation: spin 2s linear infinite;
        animation: spin 2s linear infinite;
        z-index: 1001;
      }
    #loader-wrapper .loader-section {
      position: fixed;
      top: 0;
      width: 51%;
      height: 100%;
      background: #7171C6;
      z-index: 1000;
      -webkit-transform: translateX(0);
      -ms-transform: translateX(0);
      transform: translateX(0);
    }
      #loader:before {
        content: "";
        position: absolute;
        top: 5px;
        left: 5px;
        right: 5px;
        bottom: 5px;
        border-radius: 50%;
        border: 3px solid transparent;
        border-top-color: #fff;
        -webkit-animation: spin 3s linear infinite;
        -moz-animation: spin 3s linear infinite;
        -o-animation: spin 3s linear infinite;
        -ms-animation: spin 3s linear infinite;
        animation: spin 3s linear infinite;
      }
    #loader-wrapper .loader-section.section-left {
      left: 0;
    }
      #loader:after {
        content: "";
        position: absolute;
        top: 15px;
        left: 15px;
        right: 15px;
        bottom: 15px;
        border-radius: 50%;
        border: 3px solid transparent;
        border-top-color: #fff;
        -moz-animation: spin 1.5s linear infinite;
        -o-animation: spin 1.5s linear infinite;
        -ms-animation: spin 1.5s linear infinite;
        -webkit-animation: spin 1.5s linear infinite;
        animation: spin 1.5s linear infinite;
      }
    #loader-wrapper .loader-section.section-right {
      right: 0;
    }
      @-webkit-keyframes spin {
        0% {
          -webkit-transform: rotate(0deg);
          -ms-transform: rotate(0deg);
          transform: rotate(0deg);
        }
        100% {
          -webkit-transform: rotate(360deg);
          -ms-transform: rotate(360deg);
          transform: rotate(360deg);
        }
      }
    .loaded #loader-wrapper .loader-section.section-left {
      -webkit-transform: translateX(-100%);
      -ms-transform: translateX(-100%);
      transform: translateX(-100%);
      -webkit-transition: all 0.7s 0.3s cubic-bezier(0.645, 0.045, 0.355, 1.000);
      transition: all 0.7s 0.3s cubic-bezier(0.645, 0.045, 0.355, 1.000);
    }
      @keyframes spin {
        0% {
          -webkit-transform: rotate(0deg);
          -ms-transform: rotate(0deg);
          transform: rotate(0deg);
        }
    .loaded #loader-wrapper .loader-section.section-right {
      -webkit-transform: translateX(100%);
      -ms-transform: translateX(100%);
      transform: translateX(100%);
      -webkit-transition: all 0.7s 0.3s cubic-bezier(0.645, 0.045, 0.355, 1.000);
      transition: all 0.7s 0.3s cubic-bezier(0.645, 0.045, 0.355, 1.000);
    }
        100% {
          -webkit-transform: rotate(360deg);
          -ms-transform: rotate(360deg);
          transform: rotate(360deg);
        }
      }
    .loaded #loader {
      opacity: 0;
      -webkit-transition: all 0.3s ease-out;
      transition: all 0.3s ease-out;
    }
      #loader-wrapper .loader-section {
        position: fixed;
        top: 0;
        width: 51%;
        height: 100%;
        background: #7171c6;
        z-index: 1000;
        -webkit-transform: translateX(0);
        -ms-transform: translateX(0);
        transform: translateX(0);
      }
    .loaded #loader-wrapper {
      visibility: hidden;
      -webkit-transform: translateY(-100%);
      -ms-transform: translateY(-100%);
      transform: translateY(-100%);
      -webkit-transition: all 0.3s 1s ease-out;
      transition: all 0.3s 1s ease-out;
    }
      #loader-wrapper .loader-section.section-left {
        left: 0;
      }
    .no-js #loader-wrapper {
      display: none;
    }
      #loader-wrapper .loader-section.section-right {
        right: 0;
      }
    .no-js h1 {
      color: #222222;
    }
      .loaded #loader-wrapper .loader-section.section-left {
        -webkit-transform: translateX(-100%);
        -ms-transform: translateX(-100%);
        transform: translateX(-100%);
        -webkit-transition: all 0.7s 0.3s cubic-bezier(0.645, 0.045, 0.355, 1);
        transition: all 0.7s 0.3s cubic-bezier(0.645, 0.045, 0.355, 1);
      }
    #loader-wrapper .load_title {
      font-family: 'Open Sans';
      color: #FFF;
      font-size: 19px;
      width: 100%;
      text-align: center;
      z-index: 9999999999999;
      position: absolute;
      top: 60%;
      opacity: 1;
      line-height: 30px;
    }
      .loaded #loader-wrapper .loader-section.section-right {
        -webkit-transform: translateX(100%);
        -ms-transform: translateX(100%);
        transform: translateX(100%);
        -webkit-transition: all 0.7s 0.3s cubic-bezier(0.645, 0.045, 0.355, 1);
        transition: all 0.7s 0.3s cubic-bezier(0.645, 0.045, 0.355, 1);
      }
    #loader-wrapper .load_title span {
      font-weight: normal;
      font-style: italic;
      font-size: 13px;
      color: #FFF;
      opacity: 0.5;
    }
  </style>
</head>
      .loaded #loader {
        opacity: 0;
        -webkit-transition: all 0.3s ease-out;
        transition: all 0.3s ease-out;
      }
<body>
  <div id="app">
    <div id="loader-wrapper">
      <div id="loader"></div>
      <div class="loader-section section-left"></div>
      <div class="loader-section section-right"></div>
      <div class="load_title">正在加载,请耐心等待</div>
      .loaded #loader-wrapper {
        visibility: hidden;
        -webkit-transform: translateY(-100%);
        -ms-transform: translateY(-100%);
        transform: translateY(-100%);
        -webkit-transition: all 0.3s 1s ease-out;
        transition: all 0.3s 1s ease-out;
      }
      .no-js #loader-wrapper {
        display: none;
      }
      .no-js h1 {
        color: #222222;
      }
      #loader-wrapper .load_title {
        font-family: "Open Sans";
        color: #fff;
        font-size: 19px;
        width: 100%;
        text-align: center;
        z-index: 9999999999999;
        position: absolute;
        top: 60%;
        opacity: 1;
        line-height: 30px;
      }
      #loader-wrapper .load_title span {
        font-weight: normal;
        font-style: italic;
        font-size: 13px;
        color: #fff;
        opacity: 0.5;
      }
    </style>
  </head>
  <body>
    <div id="app">
      <div id="loader-wrapper">
        <div id="loader"></div>
        <div class="loader-section section-left"></div>
        <div class="loader-section section-right"></div>
        <div class="load_title">正在加载,请耐心等待</div>
      </div>
    </div>
  </div>
  <script type="module" src="/src/main.js"></script>
</body>
</html>
    <script type="module" src="/src/main.js"></script>
  </body>
</html>
zhitan-vue/package.json
@@ -7,7 +7,7 @@
  "type": "module",
  "scripts": {
    "dev": "vite",
    "build:prod": "vite build",
    "build": "vite build",
    "build:stage": "vite build --mode staging",
    "preview": "vite preview"
  },
zhitan-vue/public/logo.png
zhitan-vue/src/api/svg/equipmentfile.js
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,40 @@
import request from "@/utils/request"
// ä¿®æ”¹ç»„态图
export function updateEquipmentfile(data) {
  return request({
    url: "/basicSetup/equipmentfile",
    method: "put",
    data: data,
  })
}
export function getAllCollectTag(data) {
  return request({
    url: "/basicsetting/energyindex/filter",
    method: "get",
    params: data,
  })
}
export function saveSettingApi(nodeId, data) {
  return request({
    url: "/basicSetup/equipmentfile/setting/" + nodeId,
    method: "put",
    data: data,
  })
}
export function getConfigure(nodeId) {
  return request({
    url: "/basicSetup/equipmentfile/configure/" + nodeId,
    method: "get",
  })
}
export function getLiveData(tagCodes) {
  return request({
    url: "/rtdb/retrieve/" + tagCodes,
    method: "get",
  })
}
zhitan-vue/src/assets/images/login-background.jpg
zhitan-vue/src/components/FileUpload/index.vue
@@ -13,9 +13,14 @@
      :headers="headers"
      class="upload-file-uploader"
      ref="fileUpload"
      :drag="draggable"
    >
      <!-- ä¸Šä¼ æŒ‰é’® -->
      <el-button type="primary">选取文件</el-button>
      <el-button v-if="!draggable" type="primary">选取文件</el-button>
      <div v-else>
        <el-icon class="el-icon--upload"><upload-filled /></el-icon>
        <div class="el-upload__text">将文件拖到此处,或<em>点击上传</em></div>
      </div>
    </el-upload>
    <!-- ä¸Šä¼ æç¤º -->
    <div class="el-upload__tip" v-if="showTip">
@@ -66,6 +71,11 @@
    type: Boolean,
    default: true,
  },
  // æ˜¯å¦æ‹–拽上传
  draggable: {
    type: Boolean,
    default: false,
  },
})
const { proxy } = getCurrentInstance()
zhitan-vue/src/views/index.vue
@@ -379,7 +379,7 @@
            right: "5%",
            itemWidth: 14,
            itemHeight: 14,
            itemGap: 60,
            itemGap: 16,
            textStyle: {
              align: "left",
              verticalAlign: "middle",
@@ -777,7 +777,7 @@
            right: "10%",
            itemWidth: 14,
            itemHeight: 14,
            itemGap: 50,
            itemGap: 16,
            textStyle: {
              align: "left",
              verticalAlign: "middle",
zhitan-vue/src/views/login copy.vue
ÎļþÒÑɾ³ý
zhitan-vue/src/views/login.vue
@@ -11,8 +11,8 @@
    <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" />
        <img src="@/assets/images/font01.png" alt="" style="width: 380px" />
        <img src="@/assets/images/img_logo.png" alt="" style="width: 180px; margin-top: 20px" />
      </div>
      <div class="right-wrapper">
        <div class="header">
@@ -44,7 +44,7 @@
              size="large"
              auto-complete="off"
              placeholder="验证码"
              style="width: 266px"
              style="width: 230px"
              @keyup.enter="handleLogin"
            >
              <!-- <template #prefix><svg-icon icon-class="validCode" class="el-input__icon input-icon" /></template> -->
@@ -202,7 +202,7 @@
  display: flex;
  align-items: center;
  height: 100%;
  background-image: url("@/assets/images/login-background.png");
  background-image: url("@/assets/images/login-background.jpg");
  background-repeat: no-repeat;
  background-size: cover;
  flex-direction: column;
@@ -223,31 +223,31 @@
    flex-direction: column;
  }
  .login-font {
    font-size: 34px;
    font-size: 32px;
    font-weight: 700;
    color: #d5f8ff;
    margin-bottom: 12px;
    margin-bottom: 10px;
  }
}
.right-wrapper {
  border-radius: 23px;
  background: #ffffff;
  width: 480px;
  width: 410px;
  position: relative;
  .header {
    height: 70px;
    line-height: 70px;
    height: 56px;
    line-height: 56px;
    border-bottom: 1px solid #f1f1f1;
    color: #3b3b3b;
    font-size: 22px;
    font-size: 18px;
    margin-bottom: 22px;
    span {
      display: inline-block;
      height: 70px;
      line-height: 70px;
      border-bottom: 6px solid #3a83fc;
      margin-left: 50px;
      height: 56px;
      line-height: 62px;
      border-bottom: 4px solid #3a83fc;
      margin-left: 32px;
    }
  }
}
@@ -277,14 +277,14 @@
}
.login-form {
  padding: 0 50px 30px;
  padding: 0 32px 20px;
  .submit-btn {
    width: 382px;
    height: 54px;
    width: 360px;
    height: 44px;
    background: #3a83fc;
    border-radius: 3px;
    font-size: 20px;
    font-size: 18px;
    box-shadow: 1px 2px 5px #3a83fc;
    border: none;
    border-radius: 6px;
@@ -342,7 +342,7 @@
  text-align: center;
  color: #fff;
  font-family: Arial;
  font-size: 16px;
  font-size: 14px;
  letter-spacing: 1px;
}
</style>
zhitan-vue/src/views/svg/components/configure.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,204 @@
<template>
  <div>
    <div slot="header" class="clearfix">
      <el-button
        style="float: right; padding: 8px; margin-left: 8px"
        type="text"
        icon="el-icon-setting"
        @click="saveSetting"
      >
        ä¿å­˜é…ç½®
      </el-button>
      <el-button
        style="float: right; padding: 8px; margin-left: 8px"
        type="text"
        icon="el-icon-setting"
        @click="reset()"
      >
        é‡æ–°é€‰æ‹©åº•图
      </el-button>
    </div>
    <el-row>
      <el-col :span="18">
        <!-- v-if="filePath === '空节点'" -->
        <div style="text-align: center; margin-left: 12px" v-if="filePath === '空节点'">
          <FileUpload
            :modelValue="fileList"
            @update:modelValue="fileUploadChange"
            :isShowTip="false"
            :limit="1"
            :fileSize="20"
            :fileType="[]"
            :draggable="true"
          />
        </div>
        <div id="svgHtml" v-if="filePath !== '空节点'">
          <div v-html="svgHtml" />
        </div>
      </el-col>
      <el-col :span="6" style="height: calc(100vh - 165px); overflow: auto">
        <el-table :data="tags" border>
          <el-table-column label="参数" align="center" prop="param" />
          <el-table-column label="采集点" align="center" prop="tag">
            <template #default="scope">
              <el-autocomplete
                popper-class="my-autocomplete"
                v-model="scope.row['tag']"
                :fetch-suggestions="querySearch"
                placeholder="请输入指标编码"
                placement="bottom-end"
              >
                <template #default="{ item }">
                  <div class="">{{ item.value }}</div>
                  <span class="" style="color: #409eff; display: block">{{ item.name }}</span>
                </template>
              </el-autocomplete>
            </template>
          </el-table-column>
        </el-table>
      </el-col>
    </el-row>
  </div>
</template>
<script setup>
import { getAllCollectTag, getConfigure, saveSettingApi, updateEquipmentfile } from "@/api/svg/equipmentfile"
const { proxy } = getCurrentInstance()
let props = defineProps(["types"])
const emit = defineEmits(["getList"])
const currentNode = ref({})
const filePath = ref("空节点")
const svgHtml = ref("")
const form = ref({
  nodeId: "",
  fileName: "",
  svgType: "",
})
const tags = ref([])
const fileList = ref([])
function changeModelNode(modelNode) {
  currentNode.value = modelNode
  filePath.value = "空节点"
  getConfigure(modelNode.id).then((response) => {
    tags.value = []
    svgHtml.value = ""
    if (response.code === 200) {
      if (response.data) {
        filePath.value = response.data.filePath
        tags.value = response.data.infoList
        getSvg()
      }
    } else {
      proxy.$modal.msgError(response.msg)
    }
  })
}
// åˆå§‹åŒ–svg
function getSvg() {
  /* åˆ›å»ºxhr对象 */
  const xhr = new XMLHttpRequest()
  xhr.open("GET", filePath.value, true)
  xhr.send()
  /* ç›‘听xhr对象 */
  xhr.addEventListener("load", () => {
    svgHtml.value = xhr.responseText
    let values = xhr.responseXML.getElementsByTagName("text")
    let tagTemps = []
    for (let i = 0; i < values.length; i++) {
      if (values[i].getAttribute("id") != undefined)
        tagTemps.push({
          param: values[i].textContent,
          tag: "",
          tagType: "COLLECT",
        })
    }
    console.log(tags.value.length, tagTemps.length)
    if (tags.value.length === 0 || tags.value.length != tagTemps.length) {
      tags.value = []
      tags.value = tagTemps
      console.log("222", tags.value.length, tagTemps.length)
    }
  })
}
//上传成功后
function fileUploadChange(val) {
  if (val.length) {
    // this.$refs.upload.clearFiles()
    form.value.nodeId = currentNode.value.id
    form.value.filePath = val[0].fullUrl
    form.value.svgType = "COLLECT"
    updateEquipmentfile(form.value).then((result) => {
      if (result.code === 200) {
        filePath.value = response.msg
        tags.value = []
        getSvg()
      } else {
        proxy.$modal.msgError(result.msg)
      }
    })
  } else {
    proxy.$modal.msgError(response.msg)
  }
}
function querySearch(queryString, cb) {
  if (queryString) {
    getAllCollectTag({
      codeOrName: queryString,
      indexType: "COLLECT",
    }).then((response) => {
      // è°ƒç”¨ callback è¿”回建议列表的数据
      let result = response.data
      let values = []
      result.forEach((item) => {
        values.push({
          value: item.code,
          name: item.name,
        })
      })
      cb(values)
    })
  }
}
function saveSetting() {
  saveSettingApi(currentNode.value.id, tags.value).then((response) => {
    if (response.code === 200) {
      proxy.$modal.msgSuccess(response.msg)
    } else {
      proxy.$modal.msgError(response.msg)
    }
  })
}
function reset() {
  filePath.value = "空节点"
}
defineExpose({ changeModelNode })
</script>
<style lang="scss" scoped>
.el-autocomplete {
  width: 100%;
}
.my-autocomplete li {
  line-height: normal;
  padding: 7px;
}
.my-autocomplete li .name {
  text-overflow: ellipsis;
  overflow: hidden;
}
.my-autocomplete li .addr {
  font-size: 12px;
  color: #b4b4b4;
}
.my-autocomplete li .highlighted .addr {
  color: #ddd;
}
</style>
zhitan-vue/src/views/svg/components/configureView.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,124 @@
<template>
  <div>
    <div v-if="filePath" v-html="svgHtml" />
    <div v-else>暂未上传</div>
  </div>
</template>
<script setup>
import { getConfigure, getLiveData } from "@/api/svg/equipmentfile"
import { onMounted } from "vue"
const { proxy } = getCurrentInstance()
let props = defineProps(["nodeId"])
const emit = defineEmits(["getList"])
const currentNode = ref({})
const filePath = ref("")
const svgHtml = ref("")
const form = ref({
  nodeId: "",
  fileName: "",
  svgType: "",
})
const tags = ref([])
const tagCodes = ref([])
const valueItems = ref(null)
const timer = ref(null)
function show(nodeId) {
  console.log(nodeId)
  tagCodes.value = []
  filePath.value = ""
  getConfigure(nodeId).then((response) => {
    tags.value = []
    svgHtml.value = ""
    if (response.code === 200) {
      if (response.data) {
        filePath.value = response.data.filePath
        tags.value = response.data.infoList
        getSvg()
        refresh()
      }
    } else {
      proxy.$modal.msgError(response.msg)
    }
  })
}
function refresh() {
  if (tagCodes.value.length === 0) {
    return
  }
  getLiveData(tagCodes.value).then((response) => {
    if (response.code === 200) {
      if (response.data) {
        response.data.forEach((tagValue) => {
          let value = ""
          if (tagValue.value) {
            value = parseFloat(tagValue.value).toFixed(2)
          } else {
            value = "0"
          }
          let el = document.getElementById(tagValue.tagCode)
          if (el) {
            el.textContent = value
          }
        })
        //这块是单独加的 ç”¨æ¥å¤„理 æ²¡æœ‰æŒ‡æ ‡æˆ–者指标没有结果的 éƒ½è®¾ç½®0
        let allText = document.getElementsByTagName("text")
        for (let i = 0; i < allText.length; i++) {
          // console.log(i + "textContent=" + allText[i].textContent);
          if (allText[i].textContent == null || allText[i].textContent == "") {
            allText[i].textContent = "0"
          }
        }
      }
    }
  })
}
function refreshData() {
  timer.value = setInterval(() => {
    refresh()
  }, 3000)
}
onMounted(() => {
  refreshData()
})
onBeforeUnmount(() => {
  clearInterval(timer.value)
})
// åˆå§‹åŒ–svg
function getSvg() {
  /* åˆ›å»ºxhr对象 */
  const xhr = new XMLHttpRequest()
  xhr.open("GET", filePath.value, true)
  xhr.send()
  /* ç›‘听xhr对象 */
  xhr.addEventListener("load", () => {
    const resXML = xhr.responseXML
    let svgDom = resXML.documentElement.cloneNode(true)
    let values = svgDom.getElementsByTagName("text")
    for (let i = 0; i < values.length; i++) {
      let tag = tags.value.filter((f) => f.param === values[i].textContent)
      if (tag && tag.length > 0) {
        let tagCode = tag[0].tag
        values[i].textContent = ""
        if (tagCode) {
          values[i].setAttribute("id", tagCode)
          tagCodes.value.push(tagCode)
        }
      }
    }
    let oSerializer = new XMLSerializer()
    svgHtml.value = oSerializer.serializeToString(svgDom)
  })
}
defineExpose({ show })
</script>
<style lang="scss" scoped></style>
zhitan-vue/src/views/svg/equipmentfile/chartView.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,314 @@
<template>
  <div class="page">
    <div class="page-container">
      <div class="page-container-left">
        <LeftTree ref="leftTreeRef" @handleNodeClick="handleNodeClick" />
      </div>
      <div class="page-container-right">
        <BaseCard :title="queryParams.nodeName">
          <ConfigureChartView ref="ConfigureChartViewRef" />
        </BaseCard>
      </div>
    </div>
  </div>
</template>
<script setup name="energy-real-time-monitor">
import ConfigureChartView from "../components/configureView.vue"
import { listEnergyRealTimeMonitor } from "@/api/realTimeMonitor/realTimeMonitor"
import { getConfigure } from "@/api/svg/equipmentfile"
const { proxy } = getCurrentInstance()
import { useRoute } from "vue-router"
import useSettingsStore from "@/store/modules/settings"
const settingsStore = useSettingsStore()
watch(
  () => settingsStore.sideTheme,
  (val) => {
    // getList()
  }
)
const loading = ref(false)
const data = reactive({
  queryParams: {
    nodeId: null,
    nodeName: null,
    energyType: null,
  },
  query: { ...useRoute().query },
})
const { queryParams, query } = toRefs(data)
const ConfigureChartViewRef = ref()
/** èŠ‚ç‚¹å•å‡»äº‹ä»¶ */
function handleNodeClick(data) {
  queryParams.value.nodeId = data.id
  queryParams.value.nodeName = data.label
  if (!data.id) {
    return
  }
  getConfigure(data.id).then((response) => {
    if (response.code === 200) {
      let tagCodes = []
      if (response.data) {
        response.data.infoList.forEach((tag) => {
          tagCodes.push(tag.tag)
        })
      } else {
        tagCodes = []
      }
      ConfigureChartViewRef.value.show(data.id)
    } else {
      proxy.$modal.msgError(response.msg)
    }
  })
}
</script>
<style scoped lang="scss">
@import "@/assets/styles/page.scss";
.themeDark {
  .card-box {
    margin: 0 18px;
    padding: 10px 18px;
    box-shadow: 0px 4px 10px 0px rgba(0, 0, 0, 0.12);
    border-radius: 8px 8px 8px 8px;
    border: 1px solid #22408c;
    margin-bottom: 20px;
    &-title {
      // margin: 10px 0 10px;
      color: rgba(255, 255, 255, 0.8);
      text-align: left;
      font-weight: bold;
      font-family: OPPOSans, OPPOSans;
      font-weight: 500;
      font-size: 16px;
      font-style: normal;
      text-transform: none;
    }
    &-ul {
      display: flex;
      flex-wrap: wrap;
    }
    &-li {
      width: 18%;
      margin: 1%;
      border-radius: 5px;
      border: 1px solid #22408c;
      margin-bottom: 5px;
      background: #1a235d;
      box-shadow: 0px 4px 10px 0px rgba(0, 0, 0, 0.12);
      border-radius: 8px 8px 8px 8px;
      padding: 0 10px;
      .title {
        font-size: 14px;
        color: rgba(255, 255, 255, 0.8);
        font-family: OPPOSans, OPPOSans;
        font-weight: 500;
        font-size: 16px;
        line-height: 19px;
        text-align: left;
        font-style: normal;
        text-transform: none;
      }
      .num {
        font-size: 22px;
        color: #36d3ff;
        font-family: OPPOSans, OPPOSans;
        font-weight: 800;
        font-size: 32px;
        text-align: left;
        font-style: normal;
        text-transform: none;
      }
      .time {
        color: rgba(255, 253, 253, 0.7);
        font-family: Poppins, Poppins;
        font-weight: 400;
        text-align: left;
        font-style: normal;
        text-transform: none;
      }
    }
    dd {
      padding: 0;
      margin-left: 5px;
      margin-bottom: 10px;
    }
  }
  .hamburger {
    display: inline-block;
    vertical-align: middle;
    width: 20px;
    height: 20px;
  }
  .hamburger.is-active {
    transform: rotate(180deg);
  }
  .item-box {
    display: flex;
    justify-items: center;
    align-items: center;
    flex-wrap: wrap;
    margin: 10px 18px;
    .item-tag {
      // width: 13%;
      text-align: center;
      margin: 5px 8px;
      border-radius: 8px;
      padding: 7px 10px;
      font-family: OPPOSans, OPPOSans;
      font-weight: 500;
      font-size: 16px;
      color: #ffffff;
    }
  }
}
.themeLight {
  .card-box {
    margin: 0 18px;
    padding: 10px 18px;
    box-shadow: 0px 4px 10px 0px rgba(0, 0, 0, 0.12);
    border-radius: 8px 8px 8px 8px;
    margin-bottom: 20px;
    &-title {
      // margin: 10px 0 10px;
      text-align: left;
      font-weight: bold;
      font-family: OPPOSans, OPPOSans;
      font-weight: 500;
      font-size: 16px;
      font-style: normal;
      text-transform: none;
    }
    &-ul {
      display: flex;
      flex-wrap: wrap;
    }
    &-li {
      width: 240px;
      margin-right: 10px;
      margin-top: 16px;
      border-radius: 5px;
      border: 1px solid #ebebeb;
      margin-bottom: 5px;
      background: #fff;
      // box-shadow: 0px 4px 10px 0px rgba(0, 0, 0, 0.12);
      border-radius: 8px 8px 8px 8px;
      padding: 0 10px;
      .title {
        font-size: 14px;
        color: #676767;
        font-family: OPPOSans, OPPOSans;
        font-weight: 500;
        font-size: 16px;
        line-height: 19px;
        text-align: left;
        font-style: normal;
        text-transform: none;
      }
      .num {
        font-size: 22px;
        color: #3271eb;
        font-family: OPPOSans, OPPOSans;
        font-weight: 800;
        font-size: 32px;
        text-align: left;
        font-style: normal;
        text-transform: none;
      }
      .time {
        color: #676767;
        font-family: Poppins, Poppins;
        font-weight: 400;
        text-align: left;
        font-style: normal;
        text-transform: none;
      }
    }
    dd {
      padding: 0;
      margin-left: 5px;
      margin-bottom: 10px;
    }
  }
  .hamburger {
    display: inline-block;
    vertical-align: middle;
    width: 20px;
    height: 20px;
  }
  .hamburger.is-active {
    transform: rotate(180deg);
  }
  .item-box {
    display: flex;
    justify-items: center;
    align-items: center;
    flex-wrap: wrap;
    margin: 10px 18px;
    .item-tag {
      // width: 13%;
      text-align: center;
      margin: 5px 8px;
      border-radius: 8px;
      padding: 7px 3px;
      font-family: OPPOSans, OPPOSans;
      font-weight: 500;
      font-size: 16px;
      color: #ffffff;
    }
  }
}
.scrollbar-flex-content {
  display: flex;
  margin: 10px 18px;
}
.scrollbar-demo-item {
  flex-shrink: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  // width: 100px;
  // height: 50px;
  // margin: 10px;
  text-align: center;
  border-radius: 4px;
  background: var(--el-color-danger-light-9);
  color: var(--el-color-danger);
}
.item-tag {
  // width: 13%;
  text-align: center;
  margin: 5px 8px;
  border-radius: 8px;
  padding: 7px 10px;
  font-family: OPPOSans, OPPOSans;
  font-weight: 500;
  font-size: 16px;
  color: #ffffff;
  cursor: pointer;
}
</style>
zhitan-vue/src/views/svg/equipmentfile/index.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,243 @@
<template>
  <div class="page">
    <div class="page-container">
      <div class="page-container-left">
        <div class="tree page-box">
          <div class="select-box mb20">
            æ•°æ®æ¨¡åž‹ï¼š
            <el-select
              style="width: 180px"
              v-model="modelData"
              placeholder="请选择模型"
              filterable
              @change="changeModel"
            >
              <el-option
                v-for="model in modelInfoOptions"
                :key="model.modelCode"
                :label="model.modelName"
                :value="model.modelCode"
              />
            </el-select>
          </div>
          <div class="tree-box" v-loading="treeLoading">
            <el-tree
              ref="treeRef"
              :props="defaultProps"
              :data="treeData"
              node-key="id"
              highlight-current
              :filter-node-method="filterNode"
              :default-expanded-keys="treeExpandData"
              :expand-on-click-node="false"
              @node-click="changeNode"
              accordion
            >
              <template #default="{ node, data }">
                <span>
                  <el-tooltip
                    v-if="node.label.length > 16"
                    class="item"
                    effect="dark"
                    :content="node.label"
                    placement="top-end"
                  >
                    <span>{{ node.label.slice(0, 16) + "..." }}</span>
                  </el-tooltip>
                  <span v-else id="b">{{ node.label }}</span>
                </span>
              </template>
            </el-tree>
          </div>
        </div>
      </div>
      <div class="page-container-right">
        <BaseCard :title="currentNode ? currentNode.label + '--节点配置' : '暂无节点配置'">
          <div class="content-box">
            <ConfigureView ref="configureViewRef" />
          </div>
        </BaseCard>
      </div>
    </div>
  </div>
</template>
<script setup>
import { listModel } from "@/api/modelConfiguration/businessModel"
import { treeList } from "@/api/modelConfiguration/indexWarehouse"
import ConfigureView from "../components/configure.vue"
import { nextTick } from "vue"
import { useRoute } from "vue-router"
let { proxy } = getCurrentInstance()
let treeLoading = ref(true)
let modelData = ref(null)
let modelInfoOptions = ref([]) //下拉列表
const configureViewRef = ref()
//获取下拉列表
function searchList(flag) {
  listModel({ isShow: 1 }).then((response) => {
    modelInfoOptions.value = response.data
    if (flag) {
      if (modelInfoOptions.value.length > 0) {
        if (proxy.$route.query.modelCode) {
          modelData.value = proxy.$route.query.modelCode
        } else {
          modelData.value = modelInfoOptions.value[0].modelCode
        }
        getTreeList(modelData.value)
      }
    }
  })
}
searchList(true)
//下拉选中触发树列表
function changeModel(item) {
  // console.log('changeModel', item)
  getTreeList(item)
}
let treeRef = ref(null)
let treeData = ref([])
const defaultProps = ref({
  children: "children",
  label: "label",
})
//检索树
let filterText = ref("")
const filterNode = (value, data) => {
  if (!value) return true
  return data.label.includes(value)
}
watch(filterText, (val) => {
  // æ£€æŸ¥treeRef.value是否是一个有效的ElTree实例
  if (treeRef.value && typeof treeRef.value.filter === "function") {
    // è°ƒç”¨filter方法
    treeRef.value.filter(val)
  } else {
    // treeRef.value无效,处理错误
    console.error("error")
  }
})
let currentNode = ref(null)
let treeExpandData = ref([])
let isFirstLeafNode = ref(false)
let deviceConfigRef = ref(null)
let collectIndicatorsRef = ref(null)
let statisticalIndicatorsRef = ref(null)
//获取树列表
function getTreeList(modelCode) {
  treeLoading.value = true
  treeList({ modelCode }).then((res) => {
    treeLoading.value = false
    let { data } = res
    treeData.value = data
    let chooseNode = null
    if (data.length > 0) {
      if (data[0].children && data[0].children.length !== 0 && isFirstLeafNode.value) {
        if (data[0].children[0].children && data[0].children[0].children.length !== 0) {
          chooseNode = data[0].children[0].children[0]
        } else {
          chooseNode = data[0].children[0]
        }
      } else {
        chooseNode = data[0]
      }
      currentNode.value = chooseNode
      changeNode(currentNode.value)
      treeExpandData.value.push(chooseNode.id)
      nextTick(() => {
        treeRef.value.setCurrentKey(chooseNode.id)
      })
    }
  })
}
//树点击
function changeNode(data, node, ev) {
  console.log("树点击", data)
  currentNode.value = data
  configureViewRef.value.changeModelNode(data)
}
</script>
<style lang="scss" scoped>
@import "@/assets/styles/page.scss";
.page-box {
  height: calc(100vh - 145px);
  padding-top: 12px;
  .tree-box {
    height: calc(100% - 70px);
    overflow-y: auto !important;
  }
  .select-box {
    display: flex;
    align-items: center;
    color: #3371eb;
    margin-left: 10px;
    :deep .el-icon {
      color: #fff;
      margin: 0 10px 0 15px;
      font-size: 14px;
    }
  }
  .node-opt {
    flex: 1;
    text-align: right;
    margin-right: 5px;
    :deep .el-icon {
      color: #fff;
      margin-right: 5px;
    }
  }
}
:deep .el-tabs__nav-wrap:after {
  background: transparent;
}
:deep .el-tabs__item {
  color: #fff;
  font-size: 20px;
  padding: 0 20px;
  &.is-active,
  &:hover {
    color: #999 !important;
  }
}
.tab-box {
  display: flex;
  align-items: center;
  color: #fff;
  border-bottom: 1px solid #3371eb;
  margin-right: 20px;
  .tab-li {
    cursor: pointer;
    border: 1px solid #3371eb;
    padding: 10px 25px;
    border-radius: 5px 5px 0 0;
  }
  .is-tab {
    background: #3371eb;
  }
}
.content-box {
  height: calc(100vh - 206px) !important;
}
</style>