fuliqi
2024-10-15 99b454f9d696d75368fa4ac340425ccad260f555
ycl-server/src/main/java/com/ycl/platform/service/impl/YwPointServiceImpl.java
@@ -1,20 +1,29 @@
package com.ycl.platform.service.impl;
import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.ExcelWriter;
import com.alibaba.excel.write.metadata.WriteSheet;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.conditions.query.LambdaQueryChainWrapper;
import com.baomidou.mybatisplus.extension.conditions.update.LambdaUpdateChainWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ycl.dataListener.CurrencyDataListener;
import com.ycl.platform.domain.entity.YwPeople;
import com.ycl.platform.domain.entity.YwPoint;
import com.ycl.platform.base.AbsVo;
import com.ycl.platform.domain.entity.*;
import com.ycl.platform.domain.excel.PointExport;
import com.ycl.platform.domain.form.BatchEditPointForm;
import com.ycl.platform.domain.form.YwPointForm;
import com.ycl.platform.domain.query.YwPointQuery;
import com.ycl.platform.domain.result.BaseResult;
import com.ycl.platform.domain.vo.CheckTagVO;
import com.ycl.platform.domain.vo.DynamicColumnVO;
import com.ycl.platform.domain.vo.ReportAuditingRecordVO;
import com.ycl.platform.domain.vo.YwPointVO;
import com.ycl.platform.mapper.DynamicColumnMapper;
import com.ycl.platform.mapper.TMonitorMapper;
import com.ycl.platform.mapper.YwPeopleMapper;
import com.ycl.platform.mapper.YwPointMapper;
import com.ycl.platform.service.DynamicColumnService;
import com.ycl.platform.service.YwPointService;
import com.ycl.platform.service.YwUnitService;
import com.ycl.system.Result;
@@ -23,19 +32,26 @@
import com.ycl.thread.PointImportCallable;
import com.ycl.utils.DateUtils;
import com.ycl.utils.SecurityUtils;
import com.ycl.utils.poi.EasyExcelImportUtils;
import com.ycl.utils.uuid.IdUtils;
import constant.PointHeaderConstant;
import jakarta.servlet.http.HttpServletResponse;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.context.ApplicationContext;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.Assert;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;
import org.springframework.web.multipart.MultipartFile;
import java.io.IOException;
import java.util.*;
import java.util.concurrent.*;
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.stream.Collectors;
/**
@@ -46,22 +62,17 @@
 */
@Service
@RequiredArgsConstructor
@Slf4j
public class YwPointServiceImpl extends ServiceImpl<YwPointMapper, YwPoint> implements YwPointService {
    private final SysDeptMapper sysDeptMapper;
    private final YwUnitService unitService;
    private final YwPeopleMapper ywPeopleMapper;
    private static final ExecutorService executorService = new ThreadPoolExecutor(8,
            24,
            5000,
            TimeUnit.SECONDS,
            new ArrayBlockingQueue<>(10),
            new ThreadPoolExecutor.CallerRunsPolicy()
    );
    private final TMonitorMapper monitorMapper;
    private final DynamicColumnMapper dynamicColumnMapper;
    private final ApplicationContext context;
    /**
     * 添加
     *
     * @param form
     * @return
     */
@@ -71,7 +82,7 @@
        Date now = new Date();
        entity.setCreateTime(now);
        entity.setUpdateTime(now);
        if(baseMapper.insert(entity) > 0) {
        if (baseMapper.insert(entity) > 0) {
            return Result.ok("添加成功");
        }
        return Result.error("添加失败");
@@ -115,6 +126,7 @@
    /**
     * 修改
     *
     * @param form
     * @return
     */
@@ -131,12 +143,13 @@
    /**
     * 批量删除
     *
     * @param ids
     * @return
     */
    @Override
    public Result remove(List<String> ids) {
        if(baseMapper.deleteBatchIds(ids) > 0) {
        if (baseMapper.deleteBatchIds(ids) > 0) {
            return Result.ok("删除成功");
        }
        return Result.error("删除失败");
@@ -144,12 +157,13 @@
    /**
     * id删除
     *
     * @param id
     * @return
     */
    @Override
    public Result removeById(String id) {
        if(baseMapper.deleteById(id) > 0) {
        if (baseMapper.deleteById(id) > 0) {
            return Result.ok("删除成功");
        }
        return Result.error("删除失败");
@@ -157,6 +171,7 @@
    /**
     * 分页查询
     *
     * @param query
     * @return
     */
@@ -169,6 +184,7 @@
    /**
     * 根据id查找
     *
     * @param id
     * @return
     */
@@ -185,6 +201,7 @@
    /**
     * 列表
     *
     * @return
     */
    @Override
@@ -200,20 +217,8 @@
    @Override
    public Result select(String keyword) {
        Long userId = SecurityUtils.getUserId();
        // 获取当前运维人员的运维单位
        YwPeople people = new LambdaQueryChainWrapper<>(ywPeopleMapper)
                .eq(YwPeople::getUserId, userId)
                .one();
        Integer unitId = null;
        if (Objects.nonNull(people)) {
            unitId = people.getBelongUnit();
        }
        List<YwPoint> list = new LambdaQueryChainWrapper<>(baseMapper)
                .eq(YwPoint::getUnitId, unitId)
                .like(YwPoint::getPointName, keyword)
                .list();
        Integer unitId = SecurityUtils.getUnitId();
        List<YwPoint> list = baseMapper.select(keyword, unitId);
        List data = list.stream().map(item -> {
            Map map = new HashMap<String, Object>();
            map.put("id", item.getSerialNumber());
@@ -242,24 +247,121 @@
    public void export(YwPointQuery query, HttpServletResponse response) throws IOException {
        // 导出数据
        List<PointExport> exportData = baseMapper.export(query);
        EasyExcel.write(response.getOutputStream(), PointExport.class)
                .sheet("点位更换运维单位")
                .doWrite(exportData);
        //获取动态列数据
        List<String> dynamicsHeaders = dynamicColumnMapper.getHeader("t_yw_point");
        List<DynamicColumnVO> dynamics = dynamicColumnMapper.getData();
        Map<Integer, List<DynamicColumnVO>> dynamicMap = new HashMap<>();
        if (!CollectionUtils.isEmpty(dynamics)) {
            dynamicMap = dynamics.stream().filter(vo -> vo.getRefId() != null).collect(Collectors.groupingBy(DynamicColumnVO::getRefId));
        }
        //定义表头列表
        LinkedHashSet<String> headers = new LinkedHashSet<>();
        headers.add(PointHeaderConstant.ID);
        headers.add(PointHeaderConstant.Point_Name);
        headers.add(PointHeaderConstant.Serial_Number);
        headers.add(PointHeaderConstant.IP);
        headers.add(PointHeaderConstant.Province_Tag);
        headers.add(PointHeaderConstant.Impotrant_Command_Image);
        headers.add(PointHeaderConstant.Dept_Tag);
        List<String> headersList = new LinkedList<>();
        if (!CollectionUtils.isEmpty(dynamicsHeaders)) {
            //使用链表保证后续补充数据时获取数据顺序一致
            headersList.addAll(dynamicsHeaders);
            headers.addAll(headersList);
        }
        // 定义数据
        List<List<Object>> data = new ArrayList<>();
        for (PointExport export : exportData) {
            List<Object> list = new ArrayList<>();
            //需要保证顺序一致
            list.add(export.getId());
            list.add(export.getPointName());
            list.add(export.getSerialNumber());
            list.add(export.getPointIP());
            list.add(export.getProvinceTagString());
            list.add(export.getImportantCommandImageTagString());
            list.add(export.getDeptTagString());
            for (String header : headersList) {
                //创建一个变量记录找没找到这个header
                boolean flag = false;
                List<DynamicColumnVO> columnVOS = dynamicMap.get(export.getId());
                if (!CollectionUtils.isEmpty(columnVOS)) {
                    for (DynamicColumnVO columnVO : columnVOS) {
                        if (header.equals(columnVO.getLabelValue())) {
                            list.add(columnVO.getColumnValue());
                            flag = true;
                        }
                    }
                }
                //没找到用空串占位
                if (!flag) list.add("");
            }
            data.add(list);
        }
        List<List<String>> headList = new ArrayList<>();
        for (String header : headers) {
            headList.add(Collections.singletonList(header));
        }
        EasyExcel.write(response.getOutputStream())
                .head(headList) // 设置表头
                .sheet("点位更换运维单位") // 设置sheet名称
                .doWrite(data); // 写入数据
    }
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Result importData(MultipartFile file, Integer unitId, Date startTime, Date endTime, Boolean
            needUpdateUnit) throws IOException, ExecutionException, InterruptedException {
        List<Map<String, String>> list = EasyExcelImportUtils.makeData(file);
        List<PointExport> dataList = new ArrayList<>();
//        Consumer<List<PointExport>> consumer = (dataList) -> {
//            try {
//                this.updatePoint(dataList, unitId, startTime, endTime, needUpdateUnit);
//            } catch (ExecutionException e) {
//                e.printStackTrace();
//            } catch (InterruptedException e) {
//                e.printStackTrace();
//            }
//        };
//        EasyExcel.read(file.getInputStream(), PointExport.class, new CurrencyDataListener(consumer)).headRowNumber(1).doReadAll();
        for (Map<String, String> map : list) {
            PointExport pointExport = new PointExport();
            pointExport.setId(Integer.valueOf(map.get(PointHeaderConstant.ID)));
            pointExport.setPointName(map.get(PointHeaderConstant.Point_Name));
            pointExport.setPointIP(map.get(PointHeaderConstant.IP));
            pointExport.setSerialNumber(map.get(PointHeaderConstant.Serial_Number));
            pointExport.setProvinceTag("是".equals(map.get(PointHeaderConstant.Province_Tag)));
            pointExport.setImportantCommandImageTag("是".equals(map.get(PointHeaderConstant.Impotrant_Command_Image)));
            pointExport.setDeptTag("是".equals(map.get(PointHeaderConstant.Dept_Tag)));
            List<DynamicColumnVO> dynamics = new ArrayList<>();
            // 处理动态列
            for (Map.Entry<String, String> entry : map.entrySet()) {
                String key = entry.getKey();
                if (!PointHeaderConstant.KNOWN_KEYS.contains(key)) {
                    DynamicColumnVO dynamicColumnVO = new DynamicColumnVO();
                    dynamicColumnVO.setRefId(pointExport.getId());
                    dynamicColumnVO.setLabelValue(entry.getKey());
                    dynamicColumnVO.setColumnValue(entry.getValue());
                    dynamicColumnVO.setPropName(IdUtils.randomNO(new Date()));
                    dynamicColumnVO.setTableName("t_yw_point");
                    dynamics.add(dynamicColumnVO);
                }
            }
            pointExport.setDynamicData(dynamics);
            dataList.add(pointExport);
        }
        YwPointServiceImpl self = context.getBean(YwPointServiceImpl.class);
        self.updatePoint(dataList, unitId, startTime, endTime, needUpdateUnit);
        self.updateDynamic(dataList);
        return Result.ok();
    }
    @Override
    public Result importData(MultipartFile file, Integer unitId, Date startTime, Date endTime) throws IOException {
        Consumer<List<PointExport>> consumer = (dataList) -> {
            try {
                this.updatePoint(dataList, unitId, startTime, endTime);
            } catch (ExecutionException e) {
                e.printStackTrace();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        };
        EasyExcel.read(file.getInputStream(), PointExport.class , new CurrencyDataListener(consumer)).headRowNumber(1).doReadAll();
        return Result.ok();
    public ReportAuditingRecordVO getReportResult(String serialNumber, String reportType) {
        return baseMapper.getReportResult(serialNumber, reportType);
    }
    /**
@@ -268,20 +370,28 @@
     * @param dataList
     * @param unitId
     */
    @Transactional(rollbackFor = Exception.class)
    public void updatePoint(List<PointExport> dataList, Integer unitId, Date startTime, Date endTime) throws ExecutionException, InterruptedException {
    public void updatePoint(List<PointExport> dataList, Integer unitId, Date startTime, Date endTime, Boolean
            needUpdateUnit) throws ExecutionException, InterruptedException {
        if (CollectionUtils.isEmpty(dataList)) {
            throw new RuntimeException("导入数据不能为空");
        }
        List<YwPoint> pointList = dataList.stream().map(item -> {
            YwPoint point = new YwPoint();
            point.setImportantCommandImageTag("是".equals(item.getImportantCommandImageTagString()));
            point.setProvinceTag("是".equals(item.getProvinceTagString()));
            if (Objects.nonNull(unitId)) {
                point.setUnitId(Long.valueOf(unitId));
            point.setImportantCommandImageTag(item.getImportantCommandImageTag());
            point.setProvinceTag(item.getProvinceTag());
            point.setDeptTag(item.getDeptTag());
            if (needUpdateUnit) {
                if (Objects.nonNull(unitId)) {
                    point.setUnitId(Long.valueOf(unitId));
                }
                point.setStartTime(startTime);
                point.setEndTime(endTime);
            } else {
                point.setUnitId(null);
                point.setStartTime(null);
                point.setEndTime(null);
            }
            point.setStartTime(startTime);
            point.setEndTime(endTime);
            point.setPointName(item.getPointName());
            point.setSerialNumber(item.getSerialNumber());
            return point;
@@ -289,24 +399,97 @@
        this.waitAllFinishAndGetResult(pointList);
    }
    public void waitAllFinishAndGetResult(List<YwPoint> dataList) throws InterruptedException, ExecutionException {
        List<FutureTask<Boolean>> resultList = new ArrayList<>(512);
        List<Boolean> data = new ArrayList<>(512);
        int start = 0;
        Date startTime = new Date();
        while (true) {
            if (dataList.size() < start + 100) {
                List<YwPoint> list = dataList.subList(start, dataList.size() - 1);
                this.baseMapper.updatePoint(list);
                break;
    @Override
    public void updateDynamic(List<PointExport> dataList) {
        List<DynamicColumnValue> insertList = new ArrayList<>();
        List<DynamicColumnValue> updateList = new ArrayList<>();
        List<Integer> deleteList = new ArrayList<>();
        //查出所有种类动态列作为字典
        Map<String, Integer> dictionary = new LambdaQueryChainWrapper<>(dynamicColumnMapper)
                .list().stream().collect(Collectors.toMap(DynamicColumn::getLabelValue, DynamicColumn::getId));
        //查出点位表的所有动态列
        List<DynamicColumnVO> dynamicVOList = dynamicColumnMapper.getData();
        Map<Integer, List<DynamicColumnVO>> dynamicVOMap = new HashMap<>();
        if (!CollectionUtils.isEmpty(dynamicVOList)) {
            dynamicVOMap = dynamicVOList.stream().filter(vo -> vo.getRefId() != null).collect(Collectors.groupingBy(DynamicColumnVO::getRefId));
        }
        //根据label_value和ref_id判断是否是同一数据
        for (PointExport pointExport : dataList) {
            //得到excel中动态列名作为key的map
            Map<String, DynamicColumnVO> exportMap = pointExport.getDynamicData().stream().collect(Collectors.toMap(DynamicColumnVO::getLabelValue, Function.identity()));
            //查出数据库中这个点位的动态列
            List<DynamicColumnVO> dynamicColumnVOS = dynamicVOMap.get(pointExport.getId());
            if (!CollectionUtils.isEmpty(dynamicColumnVOS)) {
                //遍历数据库中这个点位的动态列,并根据动态列名找出excel中的值
                for (DynamicColumnVO vo : dynamicColumnVOS) {
                    DynamicColumnVO dynamicColumnVO = exportMap.get(vo.getLabelValue());
                    //存在说明excel有这个数据,将数据库这个数据的值改为excel的值
                    if (dynamicColumnVO.getColumnValue() != null) {
                        DynamicColumnValue entity = new DynamicColumnValue();
                        entity.setColumnValue(dynamicColumnVO.getColumnValue());
                        entity.setDynamicColumnId(vo.getId());
                        entity.setRefId(vo.getRefId());
                        entity.setId(vo.getValueId());
                        updateList.add(entity);
                    } else {
                        //不存在则取消标签,删除
                        deleteList.add(vo.getValueId());
                    }
                }
            } else {
                List<YwPoint> list = dataList.subList(start, start + 100);
                this.baseMapper.updatePoint(list);
                start += 100;
                //数据库里查不到excel里面的这个点位动态列,全为新增
                List<DynamicColumnVO> dynamicData = pointExport.getDynamicData();
                for (DynamicColumnVO excelData : dynamicData) {
                    if(excelData.getColumnValue()!=null) {
                        Integer dynamicId = dictionary.get(excelData.getLabelValue());
                        DynamicColumnValue entity = new DynamicColumnValue();
                        entity.setColumnValue(excelData.getColumnValue());
                        entity.setDynamicColumnId(dynamicId);
                        entity.setRefId(pointExport.getId());
                        insertList.add(entity);
                    }
                }
            }
        }
        //mybaits方法
        //插入
        if(!CollectionUtils.isEmpty(insertList)) dynamicColumnMapper.saveBatch(insertList);
        //更新
        if(!CollectionUtils.isEmpty(updateList)) dynamicColumnMapper.updateBatch(updateList);
        //删除
        if(!CollectionUtils.isEmpty(deleteList)) dynamicColumnMapper.deleteBatch(deleteList);
    }
    public void waitAllFinishAndGetResult(List<YwPoint> dataList) {
        Date startTime = new Date();
        this.baseMapper.updatePoint(dataList);
        Date endTime = new Date();
        log.error("总共耗时:" + (endTime.getTime() - startTime.getTime()));
    }
    @Override
    public <T extends BaseResult> void setDeviceTagByGB(List<T> dataList) {
        List<String> gbList = dataList.stream().map(BaseResult::getNo).collect(Collectors.toList());
        List<CheckTagVO> pointList = baseMapper.getTagsByGB(gbList);
        Map<String, CheckTagVO> pointMap = pointList.stream().collect(Collectors.toMap(CheckTagVO::getNo, item -> item));
        for (BaseResult data : dataList) {
            CheckTagVO tag = pointMap.get(data.getNo());
            if (Objects.nonNull(tag)) {
                BeanUtils.copyProperties(tag, data);
            }
        }
    }
    @Override
    public <T extends BaseResult> void setNew(List<T> dataList) {
        List<String> gbList = dataList.stream().map(BaseResult::getNo).collect(Collectors.toList());
        Map<String, BaseResult> pointMap = dataList.stream().collect(Collectors.toMap(BaseResult::getNo, item -> item));
        List<String> dbGBList = monitorMapper.getGBbyGB(gbList);
        for (String s : gbList) {
            BaseResult baseResult = pointMap.get(s);
            baseResult.setNewDevice(!dbGBList.contains(s));
        }
    }
}