package org.dromara.facility.service.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.dromara.common.core.constant.HttpStatus;
import org.dromara.common.core.exception.ServiceException;
import org.dromara.common.core.utils.ObjectUtils;
import org.dromara.common.core.utils.StringUtils;
import org.dromara.common.mybatis.core.page.PageQuery;
import org.dromara.common.mybatis.core.page.TableDataInfo;
import org.dromara.common.satoken.utils.LoginHelper;
import org.dromara.facility.constant.FacRedisKeyConstant;
import org.dromara.facility.domain.FacMatrix;
import org.dromara.facility.domain.FacPhotovoltaicPanel;
import org.dromara.facility.domain.dto.geojson.*;
import org.dromara.facility.domain.dto.photovoltaicpanel.FacPhotovoltaicPanelCreateByGeoJsonReq;
import org.dromara.facility.domain.dto.photovoltaicpanel.FacPhotovoltaicPanelCreateReq;
import org.dromara.facility.domain.dto.photovoltaicpanel.FacPhotovoltaicPanelQueryReq;
import org.dromara.facility.domain.dto.photovoltaicpanel.FacPhotovoltaicPanelUpdateReq;
import org.dromara.facility.domain.enums.FacFinishStatusEnum;
import org.dromara.facility.domain.vo.photovoltaicpanel.FacPhotovoltaicPanelVo;
import org.dromara.facility.mapper.FacPhotovoltaicPanelMapper;
import org.dromara.facility.service.IFacMatrixService;
import org.dromara.facility.service.IFacPhotovoltaicPanelPartsService;
import org.dromara.facility.service.IFacPhotovoltaicPanelService;
import org.dromara.progress.constant.PgsProgressCategoryConstant;
import org.dromara.progress.domain.PgsProgressCategory;
import org.dromara.progress.service.IPgsProgressCategoryService;
import org.dromara.project.service.IBusProjectService;
import org.dromara.utils.JSTUtils;
import org.springframework.aop.framework.AopContext;
import org.springframework.beans.BeanUtils;
import org.springframework.context.annotation.Lazy;
import org.springframework.dao.DataAccessException;
import org.springframework.dao.DataIntegrityViolationException;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.*;
import java.util.concurrent.*;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * 设施-光伏板Service业务层处理
 *
 * @author lcj
 * @date 2025-04-21
 */
@Slf4j
@Service
public class FacPhotovoltaicPanelServiceImpl extends ServiceImpl<FacPhotovoltaicPanelMapper, FacPhotovoltaicPanel>
    implements IFacPhotovoltaicPanelService {

    @Resource
    private IBusProjectService projectService;

    @Resource
    private IFacMatrixService matrixService;

    @Lazy
    @Resource
    private IFacPhotovoltaicPanelPartsService photovoltaicPanelPartsService;

    @Resource
    private IPgsProgressCategoryService progressCategoryService;

    @Resource
    private RedisTemplate<String, Object> redisTemplate;

    /**
     * 查询设施-光伏板
     *
     * @param id 主键
     * @return 设施-光伏板
     */
    @Override
    public FacPhotovoltaicPanelVo queryById(Long id) {
        FacPhotovoltaicPanel photovoltaicPanel = this.getById(id);
        if (photovoltaicPanel == null) {
            throw new ServiceException("查询光伏板失败，数据不存在", HttpStatus.NOT_FOUND);
        }
        return this.getVo(photovoltaicPanel);
    }

    /**
     * 分页查询设施-光伏板列表
     *
     * @param req       查询条件
     * @param pageQuery 分页参数
     * @return 设施-光伏板分页列表
     */
    @Override
    public TableDataInfo<FacPhotovoltaicPanelVo> queryPageList(FacPhotovoltaicPanelQueryReq req, PageQuery pageQuery) {
        Page<FacPhotovoltaicPanel> result = this.page(pageQuery.build(), this.buildQueryWrapper(req));
        return TableDataInfo.build(this.getVoPage(result));
    }

    /**
     * 查询符合条件的设施-光伏板列表
     *
     * @param req 查询条件
     * @return 设施-光伏板列表
     */
    @Override
    public List<FacPhotovoltaicPanelVo> queryList(FacPhotovoltaicPanelQueryReq req) {
        List<FacPhotovoltaicPanel> photovoltaicPanelList = this.list(this.buildQueryWrapper(req));
        return photovoltaicPanelList.stream().map(this::getVo).toList();
    }

    /**
     * 新增设施-光伏板
     *
     * @param req 设施-光伏板
     * @return 新增光伏板id
     */
    @Override
    public Long insertByBo(FacPhotovoltaicPanelCreateReq req) {
        // 将实体类和 DTO 进行转换
        FacPhotovoltaicPanel photovoltaicPanel = new FacPhotovoltaicPanel();
        BeanUtils.copyProperties(req, photovoltaicPanel);
        // 将位置信息转换为 JSON 字符串
        List<List<String>> positionList = req.getPositionList();
        if (ObjectUtils.isNotEmpty(positionList)) {
            String positionStr = JSONUtil.toJsonStr(positionList);
            photovoltaicPanel.setPositions(positionStr);
        }
        // 数据校验
        validEntityBeforeSave(photovoltaicPanel, true);
        // 判断是否存在同名光伏板
        Long count = this.lambdaQuery()
            .eq(FacPhotovoltaicPanel::getProjectId, photovoltaicPanel.getProjectId())
            .eq(FacPhotovoltaicPanel::getName, photovoltaicPanel.getName())
            .count();
        if (count > 0) {
            throw new ServiceException("该项目已存在同名光伏板", HttpStatus.CONFLICT);
        }
        // 操作数据库
        boolean save = this.save(photovoltaicPanel);
        if (!save) {
            throw new ServiceException("新增光伏板失败，数据库异常", HttpStatus.ERROR);
        }
        return photovoltaicPanel.getId();
    }

    /**
     * 新增光伏板
     *
     * @param geoJson GeoJson格式
     * @return 是否新增成功
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean insertByGeoJson(FacPhotovoltaicPanelCreateByGeoJsonReq geoJson) {
        // 判断当前项目是否正在执行桩点、立柱、支架数据
        String operationRedisKey = FacRedisKeyConstant.getInOperationByProjectRedisKey(geoJson.getProjectId());
        // 判断 redis key 是否存在，存在则返回
        Object object = redisTemplate.opsForValue().get(operationRedisKey);
        if (object != null && (Boolean) object) {
            throw new ServiceException("项目下桩点、立柱、支架数据正在处理中，请等待处理完毕后操作", HttpStatus.BAD_REQUEST);
        }
        Long projectId = geoJson.getProjectId();
        if (projectService.getById(projectId) == null) {
            throw new ServiceException("项目不存在", HttpStatus.NOT_FOUND);
        }
        // 获取项目下方阵信息
        List<FacMatrix> matrixList = matrixService.lambdaQuery()
            .eq(FacMatrix::getProjectId, projectId).list();
        if (CollUtil.isEmpty(matrixList)) {
            throw new ServiceException("项目下无方阵数据，请先创建方阵信息后再添加光伏板信息", HttpStatus.NOT_FOUND);
        }
        // 获取当下项目下光伏板的信息
        List<FacPhotovoltaicPanel> oldPhotovoltaicPanelList = this.lambdaQuery()
            .eq(FacPhotovoltaicPanel::getProjectId, projectId).list();
        Map<String, FacPhotovoltaicPanel> photovoltaicPanelMap = oldPhotovoltaicPanelList.stream()
            .collect(Collectors.toMap(
                panel -> panel.getName() + "_" + panel.getProgressCategoryId(),
                Function.identity(),
                (existing, replacement) -> existing   // 如果有重复，保留第一个
            ));
        List<FacGeoJsonByPlane> locationGeoJsonList = geoJson.getLocationGeoJson();
        List<FacFeatureByPlane> locationFeatures = new ArrayList<>();
        for (FacGeoJsonByPlane geoJsonByPlane : locationGeoJsonList) {
            locationFeatures.addAll(geoJsonByPlane.getFeatures());
        }
        // 获取所有对应名称的点
        List<FacGeoJsonByPoint> nameGeoJsonList = geoJson.getNameGeoJson();
        List<FacFeatureByPoint> nameFeatures = new ArrayList<>();
        for (FacGeoJsonByPoint geoJsonByPoint : nameGeoJsonList) {
            nameFeatures.addAll(geoJsonByPoint.getFeatures());
        }
        // 获取进度类别信息
        List<PgsProgressCategory> progressCategoryList = progressCategoryService.lambdaQuery()
            .in(PgsProgressCategory::getWorkType, PgsProgressCategoryConstant.PHOTOVOLTAIC_PANEL_PROGRESS_CATEGORY_WORK_TYPE).list();
        Map<Long, List<PgsProgressCategory>> progressCategoryMap = progressCategoryList.stream()
            .collect(Collectors.groupingBy(PgsProgressCategory::getMatrixId));
        ExecutorService executorService = Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors());
        List<FacPhotovoltaicPanel> allPanels = new ArrayList<>();
        try {
            List<Future<List<FacPhotovoltaicPanel>>> futures = new ArrayList<>();
            Long userId = LoginHelper.getUserId();
            for (FacFeatureByPlane locationFeature : locationFeatures) {
                Future<List<FacPhotovoltaicPanel>> future = executorService.submit(() -> {
                    List<FacPhotovoltaicPanel> panelList = new ArrayList<>();
                    // ① 获取 geometry 坐标
                    FacGeometryByPlane geometry = locationFeature.getGeometry();
                    List<List<Double>> coordinates = geometry.getCoordinates().getFirst();
                    // ② 判断方阵
                    FacMatrix matrix = matrixService.getMatrixIdBy2Coordinates(matrixList, coordinates);
                    if (matrix == null) return Collections.emptyList();
                    // ③ 获取名称
                    String name = JSTUtils.findNearestPointText(coordinates, nameFeatures);
                    if (name == null) return Collections.emptyList();
                    // ④ 获取进度类别
                    Long matrixId = matrix.getId();
                    List<PgsProgressCategory> progressCategoryListByMatrix = progressCategoryMap.get(matrixId);
                    if (CollUtil.isEmpty(progressCategoryListByMatrix)) return Collections.emptyList();
                    // ⑤ 构建光伏板
                    for (PgsProgressCategory progressCategory : progressCategoryListByMatrix) {
                        FacPhotovoltaicPanel panel = new FacPhotovoltaicPanel();
                        panel.setMatrixId(matrixId);
                        panel.setName(name);
                        panel.setProjectId(projectId);
                        panel.setPositions(JSONUtil.toJsonStr(coordinates));
                        panel.setCreateBy(userId);
                        panel.setUpdateBy(userId);
                        String mapKey = name + "_" + progressCategory.getId();
                        FacPhotovoltaicPanel oldPanel = photovoltaicPanelMap.get(mapKey);
                        if (oldPanel != null) {
                            panel.setStatus(oldPanel.getStatus());
                            if (FacFinishStatusEnum.FINISH.getValue().equals(oldPanel.getStatus())) {
                                panel.setFinishType(oldPanel.getFinishType());
                                panel.setFinishDate(oldPanel.getFinishDate());
                            }
                            panel.setProgressCategoryId(oldPanel.getProgressCategoryId());
                            panel.setProgressCategoryName(oldPanel.getProgressCategoryName());
                        } else {
                            panel.setProgressCategoryId(progressCategory.getId());
                            panel.setProgressCategoryName(progressCategory.getName());
                        }
                        panelList.add(panel);
                    }
                    return panelList;
                });
                futures.add(future);
            }
            // 等待所有结果
            for (Future<List<FacPhotovoltaicPanel>> future : futures) {
                try {
                    allPanels.addAll(future.get());
                } catch (Exception e) {
                    log.error("线程执行异常", e);
                }
            }
        } finally {
            executorService.shutdown();
            try {
                if (!executorService.awaitTermination(60, TimeUnit.SECONDS)) {
                    executorService.shutdownNow();
                }
            } catch (InterruptedException e) {
                executorService.shutdownNow();
                Thread.currentThread().interrupt();
            }
        }
        // 自定义线程池（IO 密集型线程池）
        ThreadPoolExecutor customExecutor = new ThreadPoolExecutor(
            20,             // 核心线程数
            50,                        // 最大线程数
            60L,                       // 线程空闲存活时间
            TimeUnit.SECONDS,           // 存活时间单位
            new LinkedBlockingQueue<>(10000),  // 阻塞队列容量
            new ThreadPoolExecutor.CallerRunsPolicy() // 拒绝策略：由调用线程处理任务
        );
        // 分批处理，避免长事务，每次处理 1000 条数据
        int batchSize = 1000;
        // 保存所有批次任务
        List<CompletableFuture<Void>> deleteFutures = new ArrayList<>();
        int deleteSize = oldPhotovoltaicPanelList.size();
        for (int i = 0; i < deleteSize; i += batchSize) {
            int endIndex = Math.min(i + batchSize, deleteSize);
            List<FacPhotovoltaicPanel> batchList = oldPhotovoltaicPanelList.subList(i, endIndex);
            // 使用事务处理每批数据
            // 获取代理
            FacPhotovoltaicPanelServiceImpl photovoltaicPanelService = (FacPhotovoltaicPanelServiceImpl) AopContext.currentProxy();
            // 异步处理每批数据，将任务添加到异步任务列表
            CompletableFuture<Void> future = CompletableFuture.runAsync(() -> photovoltaicPanelService.deleteBatchInner(batchList), customExecutor);
            deleteFutures.add(future);
        }
        // 等待所有批次完成操作
        CompletableFuture.allOf(deleteFutures.toArray(new CompletableFuture[0])).join();
        // 保存所有批次任务
        List<CompletableFuture<Void>> insertFutures = new ArrayList<>();
        int totalSize = allPanels.size();
        for (int i = 0; i < totalSize; i += batchSize) {
            int endIndex = Math.min(i + batchSize, totalSize);
            List<FacPhotovoltaicPanel> batchList = allPanels.subList(i, endIndex);
            // 使用事务处理每批数据
            // 获取代理
            FacPhotovoltaicPanelServiceImpl photovoltaicPanelService = (FacPhotovoltaicPanelServiceImpl) AopContext.currentProxy();
            // 异步处理每批数据，将任务添加到异步任务列表
            CompletableFuture<Void> future = CompletableFuture.runAsync(() -> photovoltaicPanelService.insertBatchInner(batchList), customExecutor);
            insertFutures.add(future);
        }
        // 等待所有批次完成操作
        CompletableFuture.allOf(insertFutures.toArray(new CompletableFuture[0])).join();
        // 关闭线程池
        customExecutor.shutdown();
        // 更新数量
        Map<Long, List<FacPhotovoltaicPanel>> countMap = allPanels
            .stream().collect(Collectors.groupingBy(FacPhotovoltaicPanel::getProgressCategoryId));
        for (PgsProgressCategory progressCategory : progressCategoryList) {
            Long progressCategoryId = progressCategory.getId();
            int total = 0;
            if (countMap.containsKey(progressCategoryId)) {
                total = countMap.get(progressCategoryId).size();
            }
            progressCategory.setTotal(BigDecimal.valueOf(total));
        }
        boolean result = progressCategoryService.updateBatchById(progressCategoryList);
        if (!result) {
            throw new ServiceException("更新进度类别失败，数据库异常", HttpStatus.ERROR);
        }
        return true;
    }

    /**
     * 批量新增光伏板
     *
     * @param photovoltaicPanelList 光伏板列表
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void insertBatchInner(List<FacPhotovoltaicPanel> photovoltaicPanelList) {
        try {
            if (CollUtil.isNotEmpty(photovoltaicPanelList)) {
                boolean result = this.saveBatch(photovoltaicPanelList);
                if (!result) {
                    throw new ServiceException("批量新增光伏板失败，数据库异常", HttpStatus.ERROR);
                }
            }
        } catch (DataIntegrityViolationException e) {
            log.error("数据库唯一键冲突或违反其他完整性约束, 错误信息: {}", e.getMessage());
            throw new ServiceException("数据已存在，无法重复添加");
        } catch (DataAccessException e) {
            log.error("数据库连接问题、事务问题等导致操作失败, 错误信息: {}", e.getMessage());
            throw new ServiceException("数据库操作失败");
        } catch (Exception e) {
            // 捕获其他异常，做通用处理
            log.error("批量添加光伏板时发生未知错误，错误信息: {}", e.getMessage());
            throw new ServiceException("批量添加光伏板失败");
        }
    }

    /**
     * 批量删除光伏板
     *
     * @param photovoltaicPanelList 光伏板列表
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void deleteBatchInner(List<FacPhotovoltaicPanel> photovoltaicPanelList) {
        try {
            if (CollUtil.isNotEmpty(photovoltaicPanelList)) {
                boolean result = this.removeBatchByIds(photovoltaicPanelList);
                if (!result) {
                    throw new ServiceException("删除光伏板失败，数据库异常", HttpStatus.ERROR);
                }
            }
        } catch (DataIntegrityViolationException e) {
            log.error("数据库唯一键冲突或违反其他完整性约束: {}", e.getMessage());
            throw new ServiceException("数据已存在，无法重复添加");
        } catch (DataAccessException e) {
            log.error("数据库连接问题、事务问题等导致操作失败: {}", e.getMessage());
            throw new ServiceException("数据库操作失败");
        } catch (Exception e) {
            // 捕获其他异常，做通用处理
            log.error("批量删除光伏板时发生未知错误，错误信息: {}", e.getMessage());
            throw new ServiceException("批量添加光伏板失败");
        }
    }

    /**
     * 修改设施-光伏板
     *
     * @param req 设施-光伏板
     * @return 是否修改成功
     */
    @Override
    public Boolean updateByBo(FacPhotovoltaicPanelUpdateReq req) {
        // 将实体类和 DTO 进行转换
        FacPhotovoltaicPanel photovoltaicPanel = new FacPhotovoltaicPanel();
        BeanUtils.copyProperties(req, photovoltaicPanel);
        // 将位置信息转换为 JSON 字符串
        List<List<String>> positionList = req.getPositionList();
        if (ObjectUtils.isNotEmpty(positionList)) {
            String positionStr = JSONUtil.toJsonStr(positionList);
            photovoltaicPanel.setPositions(positionStr);
        }
        // 数据校验
        validEntityBeforeSave(photovoltaicPanel, false);
        // 判断是否存在
        FacPhotovoltaicPanel oldPhotovoltaicPanel = this.getById(photovoltaicPanel.getId());
        if (oldPhotovoltaicPanel == null) {
            throw new ServiceException("修改光伏板失败，数据不存在", HttpStatus.NOT_FOUND);
        }
        // 判断是否修改名称
        if (!oldPhotovoltaicPanel.getName().equals(photovoltaicPanel.getName())) {
            Long count = this.lambdaQuery()
                .eq(FacPhotovoltaicPanel::getProjectId, photovoltaicPanel.getProjectId())
                .eq(FacPhotovoltaicPanel::getName, photovoltaicPanel.getName())
                .count();
            if (count > 0) {
                throw new ServiceException("该项目已存在同名光伏板", HttpStatus.CONFLICT);
            }
        }
        // 操作数据库
        boolean update = this.updateById(photovoltaicPanel);
        if (!update) {
            throw new ServiceException("修改光伏板失败，数据库异常", HttpStatus.ERROR);
        }
        return true;
    }

    /**
     * 保存前的数据校验
     */
    private void validEntityBeforeSave(FacPhotovoltaicPanel entity, Boolean create) {
        // TODO 做一些数据校验,如唯一约束
        Long projectId = entity.getProjectId();
        Long matrixId = entity.getMatrixId();
        if (create) {
            if (projectId == null) {
                throw new ServiceException("项目id不能为空", HttpStatus.BAD_REQUEST);
            }
            if (matrixId == null) {
                throw new ServiceException("方阵id不能为空", HttpStatus.BAD_REQUEST);
            }
        }
        if (projectId != null && projectService.getById(projectId) == null) {
            throw new ServiceException("对应项目不存在", HttpStatus.NOT_FOUND);
        }
        if (matrixId != null && matrixService.getById(matrixId) == null) {
            throw new ServiceException("对应方阵不存在", HttpStatus.NOT_FOUND);
        }
    }

    /**
     * 校验并批量删除设施-光伏板信息
     *
     * @param ids     待删除的主键集合
     * @param isValid 是否进行有效性校验
     * @return 是否删除成功
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid) {
        Long userId = LoginHelper.getUserId();
        List<FacPhotovoltaicPanel> photovoltaicPanelList = this.listByIds(ids);
        if (isValid) {
            //TODO 做一些业务上的校验,判断是否需要校验
            List<Long> projectIds = photovoltaicPanelList.stream().map(FacPhotovoltaicPanel::getProjectId).distinct().toList();
            if (CollUtil.isNotEmpty(projectIds) && projectIds.size() > 1) {
                throw new ServiceException("仅能删除单个项目下的光伏板", HttpStatus.BAD_REQUEST);
            }
            Long projectId = projectIds.getFirst();
            projectService.validAuth(projectId, userId);
            // 判断是否存在光伏板点信息
            List<String> matrixNames = photovoltaicPanelList.stream().map(FacPhotovoltaicPanel::getName).toList();
            Boolean result = photovoltaicPanelPartsService.validPartsExistByPhotovoltaicPanel(projectId, matrixNames);
            if (result) {
                throw new ServiceException("删除失败，存在光伏板点信息", HttpStatus.CONFLICT);
            }
        }
        return this.removeBatchByIds(ids);
    }

    /**
     * 获取设施-光伏板视图对象
     *
     * @param photovoltaicPanel 设施-光伏板对象
     * @return 设施-光伏板视图对象
     */
    @Override
    public FacPhotovoltaicPanelVo getVo(FacPhotovoltaicPanel photovoltaicPanel) {
        // 对象转封装类
        FacPhotovoltaicPanelVo photovoltaicPanelVo = new FacPhotovoltaicPanelVo();
        if (photovoltaicPanel == null) {
            return photovoltaicPanelVo;
        }
        BeanUtils.copyProperties(photovoltaicPanel, photovoltaicPanelVo);
        // 将 JSON 字符串转化为 List
        String positions = photovoltaicPanel.getPositions();
        if (StringUtils.isNotBlank(positions)) {
            List<List<String>> positionList = new ArrayList<>();
            List<String> arr = JSONUtil.toList(positions, String.class);
            for (String s : arr) {
                positionList.add(JSONUtil.toList(s, String.class));
            }
            photovoltaicPanelVo.setPositionList(positionList);
        }
        return photovoltaicPanelVo;
    }

    /**
     * 获取设施-光伏板查询条件封装
     *
     * @param req 查询条件
     * @return 查询条件封装
     */
    @Override
    public LambdaQueryWrapper<FacPhotovoltaicPanel> buildQueryWrapper(FacPhotovoltaicPanelQueryReq req) {
        LambdaQueryWrapper<FacPhotovoltaicPanel> lqw = new LambdaQueryWrapper<>();
        if (req == null) {
            return lqw;
        }
        Long projectId = req.getProjectId();
        Long matrixId = req.getMatrixId();
        String name = req.getName();
        String status = req.getStatus();
        String finishType = req.getFinishType();
        // 模糊查询
        lqw.like(StringUtils.isNotBlank(name), FacPhotovoltaicPanel::getName, name);
        // 精确查询
        lqw.eq(ObjectUtils.isNotEmpty(projectId), FacPhotovoltaicPanel::getProjectId, projectId);
        lqw.eq(ObjectUtils.isNotEmpty(matrixId), FacPhotovoltaicPanel::getMatrixId, matrixId);
        lqw.eq(StringUtils.isNotBlank(status), FacPhotovoltaicPanel::getStatus, status);
        lqw.eq(StringUtils.isNotBlank(finishType), FacPhotovoltaicPanel::getFinishType, finishType);
        return lqw;
    }

    /**
     * 获取设施-光伏板分页对象视图
     *
     * @param photovoltaicPanelPage 设施-光伏板分页对象
     * @return 设施-光伏板分页对象视图
     */
    @Override
    public Page<FacPhotovoltaicPanelVo> getVoPage(Page<FacPhotovoltaicPanel> photovoltaicPanelPage) {
        List<FacPhotovoltaicPanel> photovoltaicPanelList = photovoltaicPanelPage.getRecords();
        Page<FacPhotovoltaicPanelVo> photovoltaicPanelVoPage = new Page<>(
            photovoltaicPanelPage.getCurrent(),
            photovoltaicPanelPage.getSize(),
            photovoltaicPanelPage.getTotal());
        if (CollUtil.isEmpty(photovoltaicPanelList)) {
            return photovoltaicPanelVoPage;
        }
        List<FacPhotovoltaicPanelVo> photovoltaicPanelVoList = photovoltaicPanelList.stream().map(this::getVo).toList();
        photovoltaicPanelVoPage.setRecords(photovoltaicPanelVoList);
        return photovoltaicPanelVoPage;
    }

}
