21个文件已修改
8个文件已添加
994 ■■■■■ 已修改文件
pom.xml 43 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/whyc/controller/DeviceSpareController.java 13 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/whyc/controller/ExportFileController.java 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/whyc/controller/RealDataStaticController.java 36 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/whyc/controller/WorkflowMainController.java 12 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/whyc/dto/RealDataStatic/ResRealDataAc.java 16 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/whyc/dto/RealDataStatic/ResRealExportAc.java 10 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/whyc/dto/RealDataStatic/SticRealDataAc.java 13 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/whyc/mapper/DeviceSpareMapper.java 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/whyc/pojo/db_pwrdev_alarm/PwrdevAlarmParamStand.java 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/whyc/pojo/web_site/DeviceSpareLog.java 9 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/whyc/pojo/web_site/WorkflowMain.java 10 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/whyc/schedule/AlarmInspectionSchedule.java 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/whyc/service/BattRealdataIdService.java 60 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/whyc/service/BattRtstateService.java 36 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/whyc/service/DeviceSpareLogService.java 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/whyc/service/DeviceSpareService.java 164 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/whyc/service/ExportService.java 35 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/whyc/service/PwrdevAcdcdataService.java 39 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/whyc/service/PwrdevHistorydataIdService.java 58 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/whyc/service/SubTablePageInfoService.java 107 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/whyc/service/WorkflowMainService.java 63 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/whyc/util/ActionUtil.java 14 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/whyc/util/CommonUtil.java 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/whyc/webSocket/RealDataStaticAcSocket.java 114 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/whyc/webSocket/RealDataStaticHrSocket.java 114 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/resources/excel_templates/realstic_ac_template.xlsx 补丁 | 查看 | 原始文档 | blame | 历史
src/main/resources/excel_templates/template_device_spare.xlsx 补丁 | 查看 | 原始文档 | blame | 历史
src/main/resources/mapper/DeviceSpareMapper.xml 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pom.xml
@@ -142,27 +142,7 @@
            <artifactId>spring-context-support</artifactId>
            <version>5.3.9</version>
        </dependency>
        <!--poi-->
        <dependency>
            <groupId>org.apache.poi</groupId>
            <artifactId>poi-ooxml</artifactId>
            <version>3.10.1</version>
        </dependency>
        <dependency>
            <groupId>cn.afterturn</groupId>
            <artifactId>easypoi-spring-boot-starter</artifactId>
            <version>4.1.2</version>
            <exclusions>
                <exclusion>
                    <groupId>com.google.guava</groupId>
                    <artifactId>guava</artifactId>
                </exclusion>
                <exclusion>
                    <groupId>org.apache.poi</groupId>
                    <artifactId>poi-ooxml-schemas</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
        <!--<dependency>
            <groupId>org.springframework.plugin</groupId>
@@ -188,6 +168,27 @@
            <artifactId>poi-ooxml</artifactId>
            <version>4.1.2</version>
        </dependency>
        <!--poi-->
        <!--<dependency>
            <groupId>org.apache.poi</groupId>
            <artifactId>poi-ooxml</artifactId>
            <version>3.10.1</version>
        </dependency>-->
        <dependency>
            <groupId>cn.afterturn</groupId>
            <artifactId>easypoi-spring-boot-starter</artifactId>
            <version>4.1.2</version>
            <exclusions>
                <exclusion>
                    <groupId>com.google.guava</groupId>
                    <artifactId>guava</artifactId>
                </exclusion>
                <exclusion>
                    <groupId>org.apache.poi</groupId>
                    <artifactId>poi-ooxml-schemas</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
        <!--外部引入-人脸识别sdk-->
        <dependency>
            <groupId>org.apache.tomcat.embed</groupId>
src/main/java/com/whyc/controller/DeviceSpareController.java
@@ -11,6 +11,7 @@
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.List;
@@ -48,6 +49,12 @@
        return service.addByExcel(file);
    }
    @ApiOperation("excel导出")
    @GetMapping("excelExport")
    public void excelExport(HttpServletResponse response) {
        service.excelExport(response);
    }
    @PostMapping("update")
    @ApiOperation("修改")
@@ -55,6 +62,12 @@
        return service.update(spare);
    }
    @PostMapping("andOrChangePicture")
    @ApiOperation("新增或者替换图片")
    public Response andOrChangePicture(@RequestParam Integer id,@RequestParam MultipartFile file) throws IOException {
        return service.andOrChangePicture(id,file);
    }
    @PostMapping("delete")
    @ApiOperation("删除")
    public Response delete(@RequestParam Integer id) {
src/main/java/com/whyc/controller/ExportFileController.java
@@ -1,6 +1,7 @@
package com.whyc.controller;
import com.whyc.dto.Real.ExportTinfDataDto;
import com.whyc.dto.RealDataStatic.ResRealExportAc;
import com.whyc.dto.Statistic.BattCompareStic;
import com.whyc.dto.Statistic.MonStic;
import com.whyc.service.ExportService;
@@ -38,4 +39,10 @@
    public void exportBattCompare(HttpServletRequest req, HttpServletResponse resp ,@RequestBody BattCompareStic stic) throws ParseException, IOException {
        service.exportBattCompare(req,resp,stic);
    }
    @PostMapping("exportRealStaticAc")
    @ApiOperation(value = "实时数据统计曲线-交流单元导出(2.2.1)")
    public void exportRealStaticAc(HttpServletRequest req, HttpServletResponse resp ,@RequestBody ResRealExportAc exportAc) throws ParseException, IOException {
        service.exportRealStaticAc(req,resp,exportAc);
    }
}
src/main/java/com/whyc/controller/RealDataStaticController.java
New file
@@ -0,0 +1,36 @@
package com.whyc.controller;
import com.whyc.dto.RealDataStatic.SticRealDataAc;
import com.whyc.dto.Response;
import com.whyc.service.BattRealdataIdService;
import com.whyc.service.PwrdevHistorydataIdService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import java.text.ParseException;
@RestController
@Api(tags = "实时数据曲线统计")
@RequestMapping("realStatic")
public class RealDataStaticController {
    @Autowired
    private PwrdevHistorydataIdService pwrdevHistorydataIdService;
    @Autowired
    private BattRealdataIdService battRealdataIdService;
    @ApiOperation(value = "交流单元")
    @PostMapping("getSticRealAcData")
    public Response getSticRealAcData(@RequestBody SticRealDataAc stic) throws ParseException, InterruptedException {
        return pwrdevHistorydataIdService.getSticRealAcData(stic);
    }
    @ApiOperation(value = "核容设备")
    @PostMapping("getSticRealHrData")
    public Response getSticRealHrData(@RequestBody SticRealDataAc stic) throws ParseException, InterruptedException {
        return battRealdataIdService.getSticRealHrData(stic);
    }
}
src/main/java/com/whyc/controller/WorkflowMainController.java
@@ -8,11 +8,15 @@
import com.whyc.service.WorkflowMainService;
import com.whyc.util.ActionUtil;
import com.whyc.util.CommonUtil;
import com.whyc.util.JsonUtil;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import java.io.IOException;
import java.util.List;
import java.util.Map;
@RestController
@@ -23,10 +27,16 @@
    @Autowired
    private WorkflowMainService service;
    @PostMapping("submit")
    /*@PostMapping("submit")
    @ApiOperation(value = "提交单据", notes = "传参:taskDesc,mainType,mainTypeCN,mainTypeEn,dealRoleId,processLevel")
    public Response<Integer> submit(@RequestBody WorkflowMain  main){
        return service.submit(main);
    }*/
    @PostMapping("submit")
    @ApiOperation(value = "提交单据", notes = "")
    public Response<Integer> submit(@RequestParam String mainJsonStr, @RequestPart(required = false) List<MultipartFile> fileList, @RequestPart(required = false) List<MultipartFile>  picList) throws IOException {
        WorkflowMain  main = JsonUtil.getGson().fromJson(mainJsonStr, WorkflowMain.class);
        return service.submit(main,fileList,picList);
    }
src/main/java/com/whyc/dto/RealDataStatic/ResRealDataAc.java
New file
@@ -0,0 +1,16 @@
package com.whyc.dto.RealDataStatic;
import com.fasterxml.jackson.annotation.JsonFormat;
import lombok.Data;
import lombok.Value;
import java.util.Date;
import java.util.Map;
@Data
public class ResRealDataAc {
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss",timezone = "GMT+8")
    private Date recordDatetime;
    private Map<String,Map<String, Float>> propertyInfo;
}
src/main/java/com/whyc/dto/RealDataStatic/ResRealExportAc.java
New file
@@ -0,0 +1,10 @@
package com.whyc.dto.RealDataStatic;
import lombok.Data;
import java.util.List;
@Data
public class ResRealExportAc {
    private List<String> picList;
}
src/main/java/com/whyc/dto/RealDataStatic/SticRealDataAc.java
New file
@@ -0,0 +1,13 @@
package com.whyc.dto.RealDataStatic;
import lombok.Data;
import java.util.List;
import java.util.Map;
@Data
public class SticRealDataAc {
    private Integer battgroupId;
    private Integer powerId;
    private Map<String,List<String>> propertyInfo;
}
src/main/java/com/whyc/mapper/DeviceSpareMapper.java
@@ -8,4 +8,6 @@
    void outBound(List<DeviceSpare> spareList);
    void updateQuantityAndPictureBatch(List<DeviceSpare> spareListUpdate);
}
src/main/java/com/whyc/pojo/db_pwrdev_alarm/PwrdevAlarmParamStand.java
@@ -65,5 +65,8 @@
    @ApiModelProperty(value = "文件名")
    private String fileName;
    @ApiModelProperty(value = "属性字段名称")
    private String propertyName;
}
src/main/java/com/whyc/pojo/web_site/DeviceSpareLog.java
@@ -25,4 +25,13 @@
    private Date createTime;
    public DeviceSpareLog(Integer deviceSpareId, Integer operationType, String operationDetail, Date createTime) {
        this.deviceSpareId = deviceSpareId;
        this.operationType = operationType;
        this.operationDetail = operationDetail;
        this.createTime = createTime;
    }
    public DeviceSpareLog() {
    }
}
src/main/java/com/whyc/pojo/web_site/WorkflowMain.java
@@ -7,6 +7,7 @@
import lombok.Data;
import lombok.ToString;
import org.apache.ibatis.type.Alias;
import org.springframework.web.multipart.MultipartFile;
import java.util.Date;
import java.util.List;
@@ -68,16 +69,16 @@
    @ApiModelProperty("工单状态")
    private Integer status;
    /**附件名称*/
    @ApiModelProperty("附件名称")
    @ApiModelProperty("附件名称,多个用逗号隔开")
    private String fileName;
    /**附件地址*/
    @ApiModelProperty("附件地址")
    @ApiModelProperty("附件地址,多个用逗号隔开")
    private String fileUrl;
    /**图片名称*/
    @ApiModelProperty("图片名称")
    @ApiModelProperty("图片名称,多个用逗号隔开")
    private String picName;
    /**图片地址*/
    @ApiModelProperty("图片地址")
    @ApiModelProperty("图片地址,多个用逗号隔开")
    private String picUrl;
    /**归档意见*/
    @ApiModelProperty("归档意见")
@@ -101,4 +102,5 @@
    @TableField(exist = false)
    private List<WorkflowDevice> deviceList;
}
src/main/java/com/whyc/schedule/AlarmInspectionSchedule.java
@@ -17,7 +17,7 @@
/**
 * 有两个定时任务:1.告警产生,加入到巡检实时表,2.告警是否消失,同步到巡检实时表
 */
@EnableScheduling
//@EnableScheduling
@Component
public class AlarmInspectionSchedule {
src/main/java/com/whyc/service/BattRealdataIdService.java
@@ -1,6 +1,8 @@
package com.whyc.service;
import com.whyc.dto.Real.*;
import com.whyc.dto.RealDataStatic.ResRealDataAc;
import com.whyc.dto.RealDataStatic.SticRealDataAc;
import com.whyc.dto.Response;
import com.whyc.factory.ThreadPoolExecutorFactory;
import com.whyc.mapper.CommonMapper;
@@ -275,4 +277,62 @@
        List dataListSorted = dataList.stream().sorted(Comparator.comparing(RealDateDTO::getRecordTime)).collect(Collectors.toList());
        return new Response().setIII(1, dataListSorted!=null,dataListSorted,map,"历史实时查询");
    }
    //实时数据统计曲线--核容设备
    public Response getSticRealHrData(SticRealDataAc stic) throws ParseException, InterruptedException {
        //获取前笔数*时间间隔
        PowerheartParam heartParam=heartService.getHeartParamByPowerId(stic.getPowerId());
        Integer interverCount=100*5;//默认值
        Integer granularity=5;//默认值
        if(heartParam!=null){
            interverCount=heartParam.getAcinInterverCfg()*heartParam.getAcinCountCfg();
            granularity=heartParam.getAcinInterverCfg();
        }
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
        LocalDateTime now = LocalDateTime.now();
        String dateTime = now.format(formatter);
        Date endTime=ActionUtil.sdf.parse(dateTime);
        // 计算笔数*时间间隔的时间点
        LocalDateTime halfHourAgo = now.minusMinutes(interverCount);
        // 格式化输出
        String halfHourAgoTime=halfHourAgo.format(formatter);
        Date startTime=ActionUtil.sdf.parse(halfHourAgoTime);
        //获取两个时间分割多少张表
        List<List<Date>> monthTimeList = DateUtil.getMonthTime(startTime,endTime);
        List<ResRealDataAc> dataList = new LinkedList<>();
        ThreadPoolExecutor pool = ThreadPoolExecutorFactory.getPoolExecutor();
        CountDownLatch latch = new CountDownLatch(monthTimeList.size());
        for (int i = 0; i < monthTimeList.size(); i++) {
            int finalI = i;
            Integer finalGranularity = granularity;
            pool.execute(() -> {
                int finalII = finalI;
                BattRealdataId realdata = new BattRealdataId();
                realdata.setRecordTime(monthTimeList.get(finalII).get(0));
                realdata.setRecordTime1(monthTimeList.get(finalII).get(1));
                String table = stic.getBattgroupId() + "_" + ThreadLocalUtil.format(realdata.getRecordTime(),2);
                String tableName="db_data_history.tb_batt_realdata_"+table;
                realdata.setTableName(table);//表名时间格式部分
                //判断表是否存在
                int tableNum = subTablePageInfoService.judgeTable_realdata(table);
                List<ResRealDataAc> list = new ArrayList();
                if (tableNum > 0) {
                    //获取指定时间段内最大最小recordNum确保数据的完整
                    List recordNums= subTablePageInfoService.getBattMaxAndMinRecordNum(tableName,realdata.getRecordTime(),realdata.getRecordTime1());
                    Integer maxRecordNum= 0;
                    Integer minRecordNum= 0;
                    if(recordNums.size()>0){
                        maxRecordNum=(Integer)recordNums.get(0);
                        minRecordNum=(Integer)recordNums.get(1);
                    }
                    list = subTablePageInfoService.getSticRealHrData(realdata, finalGranularity,maxRecordNum,minRecordNum,stic.getPropertyInfo());
                }
                dataList.addAll(list);
                latch.countDown();
            });
            sleep(200);
        }
        latch.await(10, TimeUnit.MINUTES);
        List dataListSorted = dataList.stream().sorted(Comparator.comparing(ResRealDataAc::getRecordDatetime)).collect(Collectors.toList());
        return new Response().setII(1,dataList.size()>0,dataListSorted,"实时数据统计曲线--核容设备");
    }
}
src/main/java/com/whyc/service/BattRtstateService.java
@@ -5,12 +5,19 @@
import com.whyc.constant.DevStateEnum;
import com.whyc.dto.Real.PwrHisRealDcoutInDto;
import com.whyc.dto.Real.RealDateDTO;
import com.whyc.dto.RealDataStatic.ResRealDataAc;
import com.whyc.dto.RealDataStatic.SticRealDataAc;
import com.whyc.dto.Response;
import com.whyc.mapper.BattRtstateMapper;
import com.whyc.pojo.db_ram_db.BattRtstate;
import com.whyc.pojo.db_ram_db.PwrdevAcdcdata;
import com.whyc.util.ActionUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.lang.reflect.Field;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@Service
@@ -36,4 +43,33 @@
        RealDateDTO hrDto=mapper.getBattRealHr(battgroupId);
        return hrDto;
    }
    //实时数据统计曲线-核容设备
    public ResRealDataAc getSticRealDataAc(SticRealDataAc realDataAc) throws NoSuchFieldException, IllegalAccessException {
        Integer battgroupId=realDataAc.getBattgroupId();
        Map<String, List<String>> propertyInfo=realDataAc.getPropertyInfo();
        QueryWrapper wrapper=new QueryWrapper();
        wrapper.eq("battgroup_id",battgroupId);
        wrapper.last("limit 1");
        BattRtstate batt=mapper.selectOne(wrapper);
        ResRealDataAc data=new ResRealDataAc();
        if(batt!=null){
            data.setRecordDatetime(batt.getRecDatetime());
            Map<String, Map<String,Float>>dataMap=new HashMap<>();
            for (Map.Entry<String, List<String>> entry : propertyInfo.entrySet()) {
                String key = entry.getKey();
                List<String> valueList = entry.getValue();
                Map<String,Float> propertyMap=new HashMap<>();
                for (String value : valueList) {
                    String propertyName = ActionUtil.toCamelCase(value);
                    Field field = BattRtstate.class.getDeclaredField(propertyName);
                    field.setAccessible(true); // 如果字段是私有的,需要设置为可访问
                    Float propertyValue = (Float) field.get(batt);
                    propertyMap.put(value,propertyValue);
                }
                dataMap.put(key,propertyMap);
            }
            data.setPropertyInfo(dataMap);
        }
        return data;
    }
}
src/main/java/com/whyc/service/DeviceSpareLogService.java
@@ -8,6 +8,7 @@
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import java.util.Date;
import java.util.List;
@Service
@@ -21,6 +22,11 @@
        mapper.insert(deviceSpareLog);
    }
    public void add(Integer deviceSpareId, Integer operationType, String operationDetail, Date createTime) {
        DeviceSpareLog deviceSpareLog = new DeviceSpareLog(deviceSpareId, operationType, operationDetail, createTime);
        mapper.insert(deviceSpareLog);
    }
    public Response<List<DeviceSpareLog>> getList(int deviceSpareId) {
        QueryWrapper<DeviceSpareLog> query = Wrappers.query();
        query.eq("device_spare_id",deviceSpareId);
src/main/java/com/whyc/service/DeviceSpareService.java
@@ -1,5 +1,8 @@
package com.whyc.service;
import cn.afterturn.easypoi.excel.ExcelExportUtil;
import cn.afterturn.easypoi.excel.entity.TemplateExportParams;
import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
@@ -13,17 +16,22 @@
import com.whyc.util.ThreadLocalUtil;
import org.apache.commons.lang.StringUtils;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.xssf.usermodel.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.io.ClassPathResource;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.net.URLEncoder;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.*;
@Service
public class DeviceSpareService {
@@ -66,10 +74,10 @@
        if (file != null && file.size() > 0) {
            for (int i = 0; i < file.size(); i++) {
                MultipartFile multipartFile = file.get(i);
                String fileName = multipartFile.getOriginalFilename();
                //String fileName = multipartFile.getOriginalFilename();
                //将fileName中可能存在的,去掉
                fileName = fileName.replace(",","");
                String filePath = fileDirPath + File.separator + timeFormat+"_"+fileName;
                //fileName = fileName.replace(",","");
                String filePath = fileDirPath + File.separator + spare.getName()+"_"+spare.getModel()+"_"+spare.getVersion() + "_" + (i+1) + "_"+ timeFormat+".png";
                multipartFile.transferTo(new File(filePath));
                String split = "pis_file"+File.separator+"deviceSpare";
@@ -229,13 +237,143 @@
            spare.setSupplier(supplier);
            spareList.add(spare);
            //第七列为图片 TODO 待处理
            /*Cell cell = row.getCell(7);
            CellType cellType = cell.getCellType();
            System.out.println("-");*/
        }
        addBatch(spareList);
        return null;
        }
        //第七列为图片-浮动式图片
        //获取绘图对象中的所有图形
        XSSFDrawing drawing = (XSSFDrawing) sheet.getDrawingPatriarch();
        if (drawing == null) {
            drawing = (XSSFDrawing) sheet.createDrawingPatriarch();
        }
        List<XSSFShape> shapes = drawing.getShapes();
        for (XSSFShape shape : shapes) {
            if (shape instanceof XSSFPicture) {
                XSSFPicture pic = (XSSFPicture) shape;
                XSSFClientAnchor anchor = pic.getClientAnchor();
                //获取图片所在的起始行
                int rowIndex = anchor.getRow1();
                byte[] data = pic.getPictureData().getData();
                DeviceSpare spare = spareList.get(rowIndex - 1);
                //对存储路径进行定义
                Date now = new Date();
                String timeFormat = ThreadLocalUtil.format(ThreadLocalUtil.TIME_YYYY_MM_DD_HH_MM_SS_UNION, now);
                String dirMonth = ThreadLocalUtil.format(ThreadLocalUtil.TIME_YYYY_MM, now);
                String fileDirPath = CommonUtil.getRootFile() + "deviceSpare" + File.separator + dirMonth;
                File fileDir = new File(fileDirPath);
                //如果文件夹不存在则创建
                if (!fileDir.exists()) {
                    fileDir.mkdirs();
                }
                String filePath = fileDirPath + File.separator + spare.getName()+"_"+spare.getModel()+"_"+spare.getVersion() + "_"+ timeFormat+".png";
                // 保存图片到本地
                try (FileOutputStream fos = new FileOutputStream(filePath)) {
                    fos.write(data);
                }
                String split = "pis_file"+File.separator+"deviceSpare";
                String picUrl = File.separator + filePath.substring(filePath.indexOf(split));
                spare.setPictureUrl(picUrl);
            }
        }
        //新增列表
        List<DeviceSpare> spareListNew = new ArrayList<>();
        //更新列表
        List<DeviceSpare> spareListUpdate = new ArrayList<>();
        //查询库中的所有设备器件
        List<DeviceSpare> deviceSpareListInDB = mapper.selectList((Wrapper<DeviceSpare>) CommonUtil.nullObject);
        for (DeviceSpare spare : spareList){
            boolean isExist = false;
            for (DeviceSpare spareInDB : deviceSpareListInDB){
                if (spare.getName().equals(spareInDB.getName())
                        && spare.getModel().equals(spareInDB.getModel())
                        && spare.getVersion().equals(spareInDB.getVersion())
                        && spare.getBrand().equals(spareInDB.getBrand())
                        && spare.getType().equals(spareInDB.getType())
                        && spare.getSupplier().equals(spareInDB.getSupplier())
                ){
                    isExist = true;
                    spare.setId(spareInDB.getId());
                    spare.setQuantity(spareInDB.getQuantity()+spare.getQuantity());
                    if (spare.getPictureUrl() != null && spareInDB.getPictureUrl()!=null){
                        spare.setPictureUrl(spareInDB.getPictureUrl()+","+spare.getPictureUrl());
                    }
                    spareListUpdate.add(spare);
                }
            }
            if(!isExist){
                //不存在则新增
                spareListNew.add(spare);
            }
        }
        //更新
        if(spareListUpdate.size()>0) {
            updateQuantityAndPictureBatch(spareListUpdate);
        }
        //新增
        if(spareListNew.size()>0) {
            addBatch(spareListNew);
        }
        return new Response().setII(1,"导入完成");
    }
    private void updateQuantityAndPictureBatch(List<DeviceSpare> spareListUpdate) {
        mapper.updateQuantityAndPictureBatch(spareListUpdate);
    }
    public void excelExport(HttpServletResponse response) {
        //查询所有的设备器件
        List<DeviceSpare> deviceSpareList = mapper.selectList((Wrapper<DeviceSpare>) CommonUtil.nullObject);
        //获取导出模板地址
        ClassPathResource classPathResource = new ClassPathResource("excel_templates/template_device_spare.xlsx");
        String path = classPathResource.getPath();
        TemplateExportParams templateExportParams1 = new TemplateExportParams(path,true);
        // 构建导出数据模型
        Map<String, Object> map = new HashMap<>();
        map.put("deviceSpareList", deviceSpareList); // 假设模板中使用 ${deviceSpareList} 作为变量名
        Workbook wb = ExcelExportUtil.exportExcel(templateExportParams1, map);
        try {
            LocalDateTime now = LocalDateTime.now();
            String fileName = "维修管理器件库存_"+now.format(DateTimeFormatter.ofPattern("yyyyMMddHHmmss"))+".xlsx";
            response.setContentType("application/vnd.ms-excel");
            response.setHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(fileName, "utf-8"));
            response.flushBuffer();
            wb.write(response.getOutputStream());
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    public Response andOrChangePicture(Integer id, MultipartFile file) throws IOException {
        DeviceSpare spare = mapper.selectById(id);
        //对存储路径进行定义
        Date now = new Date();
        String timeFormat = ThreadLocalUtil.format(ThreadLocalUtil.TIME_YYYY_MM_DD_HH_MM_SS_UNION, now);
        String dirMonth = ThreadLocalUtil.format(ThreadLocalUtil.TIME_YYYY_MM, now);
        String fileDirPath = CommonUtil.getRootFile() + "deviceSpare" + File.separator + dirMonth;
        File fileDir = new File(fileDirPath);
        //如果文件夹不存在则创建
        if (!fileDir.exists()) {
            fileDir.mkdirs();
        }
        String filePath = fileDirPath + File.separator + spare.getName()+"_"+spare.getModel()+"_"+spare.getVersion() + "_"+ timeFormat+".png";
        // 保存图片到本地
        file.transferTo(new File(filePath));
        String split = "pis_file"+File.separator+"deviceSpare";
        String picUrl = File.separator + filePath.substring(filePath.indexOf(split));
        //更新图片
        UpdateWrapper<DeviceSpare> update = Wrappers.update();
        update.eq("id",id);
        update.set("picture_url",picUrl);
        mapper.update((DeviceSpare) CommonUtil.nullObject,update);
        //记录变更
        deviceSpareLogService.add(id,2,"更换图片",now);
        return new Response().setII(1,"新增或者替换图片完成");
    }
}
src/main/java/com/whyc/service/ExportService.java
@@ -4,7 +4,7 @@
import cn.afterturn.easypoi.excel.ExcelExportUtil;
import cn.afterturn.easypoi.excel.entity.TemplateExportParams;
import com.whyc.dto.Real.ExportTinfDataDto;
import com.whyc.dto.Response;
import com.whyc.dto.RealDataStatic.ResRealExportAc;
import com.whyc.dto.Statistic.BattCompareStic;
import com.whyc.dto.Statistic.MonStic;
import com.whyc.dto.Statistic.SticCompare15Res;
@@ -16,7 +16,6 @@
import com.whyc.util.ActionUtil;
import com.whyc.util.ServletUtils;
import org.apache.poi.hssf.usermodel.*;
import org.apache.poi.ss.formula.functions.T;
import org.apache.poi.ss.usermodel.ClientAnchor;
import org.apache.poi.ss.usermodel.Workbook;
import org.springframework.beans.factory.annotation.Autowired;
@@ -276,4 +275,36 @@
            e.printStackTrace();
        }
    }
    //实时数据统计曲线-交流单元导出(2.5.2)
    public void exportRealStaticAc(HttpServletRequest req, HttpServletResponse resp,  ResRealExportAc exportAc) throws IOException {
        List<String> picList=exportAc.getPicList();
        Map<String,Object> map=new HashMap<>();
        List<ImageEntity> imageList = new ArrayList<>();
        BASE64Decoder decoder = new BASE64Decoder();
        if(picList!=null&&picList.size()>0){
            for(int i=0;i<picList.size();i++){
                ImageEntity pic = new ImageEntity();
                pic.setData(decoder.decodeBuffer(picList.get(i).substring(picList.get(i).indexOf(",") + 1)));
                pic.setHeight(1000);      // 必须设置高度
                pic.setColspan(6);
                pic.setRowspan(17);
                imageList.add(pic);
            }
        }
        map.put("imageList", imageList);
        //获取导出模板地址
        ClassPathResource classPathResource = new ClassPathResource("excel_templates/realstic_ac_template.xls");
        String path = classPathResource.getPath();
        TemplateExportParams templateExportParams1 = new TemplateExportParams(path,true);
        Workbook wb = ExcelExportUtil.exportExcel(templateExportParams1, map);
        try {
            String fileName = "实时数据统计曲线-交流单元.xls";
            resp.setContentType("application/vnd.ms-excel");
            resp.setHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(fileName, "utf-8"));
            resp.flushBuffer();
            wb.write(resp.getOutputStream());
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}
src/main/java/com/whyc/service/PwrdevAcdcdataService.java
@@ -3,11 +3,20 @@
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.whyc.dto.Real.PwrHisRealAcInDto;
import com.whyc.dto.Real.PwrHisRealDcoutInDto;
import com.whyc.dto.RealDataStatic.ResRealDataAc;
import com.whyc.dto.RealDataStatic.SticRealDataAc;
import com.whyc.mapper.PwrdevAcdcdataMapper;
import com.whyc.pojo.db_data_history.PwrdevHistorydataId;
import com.whyc.pojo.db_ram_db.BattRtstate;
import com.whyc.pojo.db_ram_db.PwrdevAcdcdata;
import com.whyc.util.ActionUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.lang.reflect.Field;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@Service
public class PwrdevAcdcdataService {
@@ -32,5 +41,33 @@
        PwrHisRealDcoutInDto dcoutDto=mapper.getPwrRealDcOut(powerId);
        return dcoutDto;
    }
    //实时数据统计曲线-交流单元
    public ResRealDataAc getSticRealDataAc(SticRealDataAc realDataAc) throws NoSuchFieldException, IllegalAccessException {
        Integer powerId=realDataAc.getPowerId();
        Map<String,List<String>> propertyInfo=realDataAc.getPropertyInfo();
        QueryWrapper wrapper=new QueryWrapper();
        wrapper.eq("power_id",powerId);
        wrapper.last("limit 1");
        PwrdevAcdcdata pwr=mapper.selectOne(wrapper);
        ResRealDataAc data=new ResRealDataAc();
        if(pwr!=null){
            data.setRecordDatetime(pwr.getRecordDatetime());
            Map<String, Map<String,Float>>dataMap=new HashMap<>();
            for (Map.Entry<String, List<String>> entry : propertyInfo.entrySet()) {
                String key = entry.getKey();
                List<String> valueList = entry.getValue();
                Map<String,Float> propertyMap=new HashMap<>();
                for (String value : valueList) {
                    String propertyName = ActionUtil.toCamelCase(value);
                    Field field = PwrdevAcdcdata.class.getDeclaredField(propertyName);
                    field.setAccessible(true); // 如果字段是私有的,需要设置为可访问
                    Float propertyValue = (Float) field.get(pwr);
                    propertyMap.put(value,propertyValue);
                }
                dataMap.put(key,propertyMap);
            }
            data.setPropertyInfo(dataMap);
        }
        return data;
    }
}
src/main/java/com/whyc/service/PwrdevHistorydataIdService.java
@@ -7,6 +7,8 @@
import com.whyc.dto.Real.PwrHisRealAcInDto;
import com.whyc.dto.Real.PwrHisRealDcoutInDto;
import com.whyc.dto.Real.QuarterDto;
import com.whyc.dto.RealDataStatic.ResRealDataAc;
import com.whyc.dto.RealDataStatic.SticRealDataAc;
import com.whyc.dto.Response;
import com.whyc.dto.Statistic.QuarterPwr7Res;
import com.whyc.factory.ThreadPoolExecutorFactory;
@@ -301,4 +303,60 @@
        List dataListSorted = dataList.stream().sorted(Comparator.comparing(PwrHisRealDcoutInDto::getRecordDatetime)).collect(Collectors.toList());
        return new Response().setII(1,dataList.size()>0,dataListSorted,"获取半小时内直流输出统计");
    }
    //实时数据数据曲线统计-交流单元
    public Response getSticRealAcData(SticRealDataAc stic) throws ParseException, InterruptedException {
        //获取前笔数*时间间隔
        PowerheartParam heartParam=heartService.getHeartParamByPowerId(stic.getPowerId());
        Integer interverCount=100*5;//默认值
        Integer granularity=5;//默认值
        if(heartParam!=null){
            interverCount=heartParam.getAcinInterverCfg()*heartParam.getAcinCountCfg();
            granularity=heartParam.getAcinInterverCfg();
        }
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
        LocalDateTime now = LocalDateTime.now();
        String dateTime = now.format(formatter);
        Date endTime=ActionUtil.sdf.parse(dateTime);
        // 计算笔数*时间间隔的时间点
        LocalDateTime halfHourAgo = now.minusMinutes(interverCount);
        // 格式化输出
        String halfHourAgoTime=halfHourAgo.format(formatter);
        Date startTime=ActionUtil.sdf.parse(halfHourAgoTime);
        //获取两个时间分割多少张表
        List<List<Date>> monthTimeList = DateUtil.getMonthTime(startTime,endTime);
        List<ResRealDataAc> dataList = new LinkedList<>();
        ThreadPoolExecutor pool = ThreadPoolExecutorFactory.getPoolExecutor();
        CountDownLatch latch = new CountDownLatch(monthTimeList.size());
        for (int i = 0; i < monthTimeList.size(); i++) {
            int finalI = i;
            Integer finalGranularity = granularity;
            pool.execute(() -> {
                int finalII = finalI;
                Date recordDatetime=monthTimeList.get(finalII).get(0);
                Date recordDatetime1=monthTimeList.get(finalII).get(1);
                String table = stic.getPowerId() + "_" + ThreadLocalUtil.format(recordDatetime,2);
                String tableName="db_data_history.tb_pwrdev_historydata_"+table;
                //判断表是否存在
                int tableNum = subTablePageInfoService.judgeTable_pwrhis(table);
                List<ResRealDataAc> list = new ArrayList();
                if (tableNum > 0) {
                    //获取指定时间段内最大最小recordNum确保数据的完整
                    List recordNums= subTablePageInfoService.getPwrMaxAndMinRecordNum(tableName,recordDatetime,recordDatetime1);
                    Integer maxRecordNum= 0;
                    Integer minRecordNum= 0;
                    if(recordNums.size()>0){
                        maxRecordNum=(Integer)recordNums.get(0);
                        minRecordNum=(Integer)recordNums.get(1);
                    }
                    list=subTablePageInfoService.getSticRealAcData(tableName, finalGranularity,recordDatetime,recordDatetime1,maxRecordNum,minRecordNum,stic.getPropertyInfo());
                }
                dataList.addAll(list);
                latch.countDown();
            });
            sleep(200);
        }
        latch.await(10, TimeUnit.MINUTES);
        List dataListSorted = dataList.stream().sorted(Comparator.comparing(ResRealDataAc::getRecordDatetime)).collect(Collectors.toList());
        return new Response().setII(1,dataList.size()>0,dataListSorted,"获取半小时内交流输入统计");
    }
}
src/main/java/com/whyc/service/SubTablePageInfoService.java
@@ -5,6 +5,7 @@
import com.whyc.dto.AlmHis.PwrAlmPar;
import com.whyc.dto.AnalysisAlm.ResAnalysis;
import com.whyc.dto.Real.*;
import com.whyc.dto.RealDataStatic.ResRealDataAc;
import com.whyc.dto.Statistic.ComPareChangeCurve;
import com.whyc.dto.Statistic.ComPareChart;
import com.whyc.dto.Statistic.QuarterPwr7Res;
@@ -610,34 +611,6 @@
        });
        return list;
    }
    //系统概览获取半小时核容设备信息(组端信息取一个单体信息即可)
    public List<BattHisRealDto> getHalfHourBattDevData(String tableName,Integer granularity,String halfHourAgoTime) {
        String sql="select  distinct mon_num,record_time,group_vol,online_vol,group_curr,group_tmp,load_curr " +
                "from (select a.*, (@i:= @i+1) as number " +
                "     from (select * from "+tableName+" "+
                "                    where record_time>='"+halfHourAgoTime+"' and mon_num=1) a, " +
                "                   (select @i:=0) b) c "+
                " where c.number%"+granularity+"=0 or c.number=1 ";
        sql+=" order by record_time asc";
        List<BattHisRealDto> list = sqlExecuteService.executeQuery_call(sql, new CallBack() {
            @Override
            public List getResults(ResultSet rs) throws SQLException {
                List<BattHisRealDto> list=new ArrayList<>();
                while (rs.next()){
                    BattHisRealDto data=new BattHisRealDto();
                    data.setRecordTime(rs.getTimestamp("record_time"));
                    data.setGroupVol(rs.getFloat("group_vol"));
                    data.setOnlineVol(rs.getFloat("online_vol"));
                    data.setGroupCurr(rs.getFloat("group_curr"));
                    data.setGroupTmp(rs.getFloat("group_tmp"));
                    data.setLoadCurr(rs.getFloat("load_curr"));
                    list.add(data);
                }
                return list;
            }
        });
        return list;
    }
    //系统概览获取半小时交流输入统计
    public List<PwrHisRealAcInDto> getHalfHourPwrHisAcinData(String tableName,Integer granularity,Date recordDatetime,Date recordDatetime1,Integer maxRecordNum,Integer minRecordNum) {
        String sql=" select  distinct record_datetime,acin1_vola,acin1_volb,acin1_volc,acin2_vola,acin2_volb,acin2_volc " +
@@ -672,7 +645,7 @@
        });
        return list;
    }
    //系统概览获取半小时交流输出统计
    public List<PwrHisRealDcoutInDto> getHalfHourPwrHisDcoutData(String tableName,Integer granularity,Date recordDatetime,Date recordDatetime1,Integer maxRecordNum,Integer minRecordNum) {
        String sql="select  distinct * " +
                " from "+tableName+" where record_datetime>='"+ActionUtil.sdf.format(recordDatetime)+"'" +
@@ -719,6 +692,43 @@
                    data.setM14OutVol(rs.getFloat("m14_out_vol"));
                    data.setM15OutVol(rs.getFloat("m15_out_vol"));
                    data.setM16OutVol(rs.getFloat("m16_out_vol"));
                    list.add(data);
                }
                return list;
            }
        });
        return list;
    }
    //实时数据数据曲线统计-交流单元
    public List<ResRealDataAc> getSticRealAcData(String tableName, Integer granularity, Date recordDatetime, Date recordDatetime1
            , Integer maxRecordNum, Integer minRecordNum, Map<String, List<String>> propertyInfo) {
        String  propertyStr = propertyInfo.values().stream()
                .flatMap(List::stream)
                .collect(Collectors.joining(","));
        String sql=" select  distinct record_datetime,"+propertyStr+" "+
                " from "+tableName+" where record_datetime>='"+ActionUtil.sdf.format(recordDatetime)+"'" +
                "                    and record_datetime<='"+ActionUtil.sdf.format(recordDatetime1)+
                "' and (record_num-"+minRecordNum+")%"+granularity+"=0  or record_num="+minRecordNum+" or record_num="+maxRecordNum;
        sql+="  order by record_datetime asc";
        List<ResRealDataAc> list = sqlExecuteService.executeQuery_call(sql, new CallBack() {
            @Override
            public List getResults(ResultSet rs) throws SQLException {
                List<ResRealDataAc> list=new ArrayList<>();
                while (rs.next()){
                    ResRealDataAc data=new ResRealDataAc();
                    data.setRecordDatetime(rs.getTimestamp("record_datetime"));
                    Map<String,Map<String,Float>>dataMap=new HashMap<>();
                    for (Map.Entry<String, List<String>> entry : propertyInfo.entrySet()) {
                        String key = entry.getKey();
                        List<String> valueList = entry.getValue();
                        Map<String,Float> propertyMap=new HashMap<>();
                        for (String value : valueList) {
                            Float propertyValue = rs.getFloat(value);
                            propertyMap.put(value,propertyValue);
                        }
                        dataMap.put(key,propertyMap);
                    }
                    data.setPropertyInfo(dataMap);
                    list.add(data);
                }
                return list;
@@ -869,7 +879,7 @@
    }
    //电池数据历史实时处理
    public List<RealDateDTO> getBattRealDataHis(BattRealdataId realdata, int granularity,Integer maxRecordNum,Integer minRecordNum) {
        String sql=" select record_time, group_vol, online_vol,group_curr,load_curr, mon_vol, mon_tmp, mon_res, mon_num,record_num  " +
        String sql=" select distinct record_time, group_vol, online_vol,group_curr,load_curr, mon_vol, mon_tmp, mon_res, mon_num,record_num  " +
                "               from db_data_history.tb_batt_realdata_"+realdata.getTableName()+" " +
                "               where record_time >= '"+ThreadLocalUtil.format(realdata.getRecordTime(),1)+"' " +
                "               and record_time <= '"+ThreadLocalUtil.format(realdata.getRecordTime1(),1)+"' "+
@@ -896,7 +906,42 @@
        });
        return list;
    }
    //实时数据统计曲线--核容设备
    public List<ResRealDataAc> getSticRealHrData(BattRealdataId realdata, Integer granularity, Integer maxRecordNum, Integer minRecordNum, Map<String, List<String>> propertyInfo) {
        String  propertyStr = propertyInfo.values().stream()
                .flatMap(List::stream)
                .collect(Collectors.joining(","));
        String sql=" select distinct record_time, "+propertyStr+" "+
                "               from db_data_history.tb_batt_realdata_"+realdata.getTableName()+" " +
                "               where record_time >= '"+ThreadLocalUtil.format(realdata.getRecordTime(),1)+"' " +
                "               and record_time <= '"+ThreadLocalUtil.format(realdata.getRecordTime1(),1)+"' "+
                "               and (record_num-"+minRecordNum+")%"+granularity+"=0 or record_num="+maxRecordNum+" or record_num="+minRecordNum ;
        List<ResRealDataAc> list = sqlExecuteService.executeQuery_call(sql, new CallBack() {
            @Override
            public List getResults(ResultSet rs) throws SQLException {
                List<ResRealDataAc> list=new ArrayList<>();
                while (rs.next()){
                    ResRealDataAc data=new ResRealDataAc();
                    data.setRecordDatetime(rs.getTimestamp("record_time"));
                    Map<String,Map<String,Float>>dataMap=new HashMap<>();
                    for (Map.Entry<String, List<String>> entry : propertyInfo.entrySet()) {
                        String key = entry.getKey();
                        List<String> valueList = entry.getValue();
                        Map<String,Float> propertyMap=new HashMap<>();
                        for (String value : valueList) {
                            Float propertyValue = rs.getFloat(value);
                            propertyMap.put(value,propertyValue);
                        }
                        dataMap.put(key,propertyMap);
                    }
                    data.setPropertyInfo(dataMap);
                    list.add(data);
                }
                return list;
            }
        });
        return list;
    }
    //系统概览获取前N笔核容设备信息
    public List<RealDateDTO> getBattDevData100(String tableName, Integer granularity, Date recordDatetime, Date recordDatetime1,Integer maxRecordNum,Integer minRecordNum) {
        String sql=" select record_time, group_vol, online_vol,group_curr, load_curr,record_num  " +
src/main/java/com/whyc/service/WorkflowMainService.java
@@ -20,9 +20,12 @@
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;
import javax.annotation.Resource;
import javax.servlet.ServletContext;
import java.io.File;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.stream.Collectors;
@@ -244,7 +247,7 @@
     */
    @Transactional
    public Response submit(WorkflowMain main){
    public Response submit(WorkflowMain main, List<MultipartFile> fileList, List<MultipartFile> picList) throws IOException {
        //1.提交到单据审批流程
        //如果存在关联单据id,首先校验提交的数量
        Date now = new Date();
@@ -299,6 +302,64 @@
                deviceList.get(i).setQuantityUnprocessed(deviceList.get(i).getQuantity());
            }
        }
        //如果存在附件和图片,则存入对应字段
        //对存储路径进行定义
        String timeFormat = ThreadLocalUtil.format(ThreadLocalUtil.TIME_YYYY_MM_DD_HH_MM_SS_UNION, now);
        String dirMonth = ThreadLocalUtil.format(ThreadLocalUtil.TIME_YYYY_MM, now);
        String fileDirPath = CommonUtil.getRootFile() + "workflow" + File.separator + dirMonth;
        File fileDir = new File(fileDirPath);
        //如果文件夹不存在则创建
        if (!fileDir.exists()) {
            fileDir.mkdirs();
        }
        StringBuilder fileUrlSb = new StringBuilder();
        StringBuilder fileNameSb = new StringBuilder();
        if (fileList != null && fileList.size() > 0) {
            for (int i = 0; i < fileList.size(); i++) {
                MultipartFile multipartFile = fileList.get(i);
                String fileName = multipartFile.getOriginalFilename();
                //将fileName中可能存在的,去掉
                fileName = fileName.replace(",","");
                String filePath = fileDirPath + File.separator + timeFormat+"_"+fileName;
                multipartFile.transferTo(new File(filePath));
                String split = "pis_file"+File.separator+"workflow";
                String fileUrl = File.separator + filePath.substring(filePath.indexOf(split));
                if(i == fileList.size()-1) {
                    fileUrlSb.append(fileUrl);
                    fileNameSb.append(fileName);
                }else {
                    fileUrlSb.append(fileUrl).append(",");
                    fileNameSb.append(fileName).append(",");
                }
            }
        }
        main.setFileUrl(fileUrlSb.toString());
        main.setFileName(fileNameSb.toString());
        StringBuilder picUrlSb = new StringBuilder();
        StringBuilder picNameSb = new StringBuilder();
        if (picList != null && picList.size() > 0) {
            for (int i = 0; i < picList.size(); i++) {
                MultipartFile multipartFile = picList.get(i);
                String picName = multipartFile.getOriginalFilename();
                //将picName中可能存在的,去掉
                picName = picName.replace(",","");
                String picPath = fileDirPath + File.separator + picName;
                multipartFile.transferTo(new File(picPath));
                String split = "pis_file"+File.separator+"workflow";
                String picUrl = File.separator + picPath.substring(picPath.indexOf(split));
                if(i == picList.size()-1) {
                    picUrlSb.append(picUrl);
                    picNameSb.append(picName);
                }else {
                    picUrlSb.append(picUrl).append(",");
                    picNameSb.append(picName).append(",");
                }
            }
        }
        main.setPicUrl(picUrlSb.toString());
        main.setPicName(picNameSb.toString());
        add(main);
        //主表关联的物料插入
        for (WorkflowDevice device : deviceList) {
src/main/java/com/whyc/util/ActionUtil.java
@@ -23,6 +23,9 @@
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import com.whyc.pojo.db_user.User;
public class ActionUtil {
@@ -678,7 +681,14 @@
            System.out.println(date);
        }*/
        //System.out.println(toCamelCase("user_name_and_age"));
        Date time1=getDateAdd(new Date(),-10);
        System.out.println(ActionUtil.sdf.format(time1));
        /*Date time1=getDateAdd(new Date(),-10);
        System.out.println(ActionUtil.sdf.format(time1));*/
        Map<String, List<String>> map = new HashMap<>();
        map.put("key1", Stream.of("value1", "value2").collect(Collectors.toList()));
        map.put("key2", Stream.of("value3", "value4").collect(Collectors.toList()));
        String result = map.values().stream()
                .flatMap(List::stream)
                .collect(Collectors.joining(","));
        System.out.println( result);
    }
}    
src/main/java/com/whyc/util/CommonUtil.java
@@ -3,6 +3,7 @@
import com.whyc.constant.YamlProperties;
import com.whyc.pojo.db_user.User;
import com.whyc.service.UserLogService;
import org.apache.poi.ss.formula.functions.T;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.subject.Subject;
import org.springframework.beans.factory.annotation.Autowired;
@@ -20,6 +21,7 @@
@Component
public class CommonUtil {
    public static Object nullObject = null;
    private static UserLogService userLogService;
    @Autowired
src/main/java/com/whyc/webSocket/RealDataStaticAcSocket.java
New file
@@ -0,0 +1,114 @@
package com.whyc.webSocket;
import com.whyc.config.WebSocketConfig;
import com.whyc.dto.Real.PwrHisRealAcInDto;
import com.whyc.dto.RealDataStatic.ResRealDataAc;
import com.whyc.dto.RealDataStatic.SticRealDataAc;
import com.whyc.dto.Response;
import com.whyc.pojo.db_param.PowerheartParam;
import com.whyc.service.PowerheartParamService;
import com.whyc.service.PwrdevAcdcdataService;
import com.whyc.util.ActionUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import javax.servlet.http.HttpSession;
import javax.websocket.*;
import javax.websocket.server.ServerEndpoint;
import java.util.HashMap;
import java.util.Map;
/**
 * 实时数据统计推送交流单元,更改频率
 */
@Component
@ServerEndpoint(value = "/realsticAc",encoders = WebSocketEncoder.class,configurator = WebSocketConfig.class)
public class RealDataStaticAcSocket {
    private Session session;
    private Thread thread;
    private static PwrdevAcdcdataService acdcdataService;
    private static PowerheartParamService pwrHeartService;
    private static HttpSession httpSession;
    private volatile boolean runFlag = true;
    private volatile Map<String, Thread> threadMap = new HashMap<>();
    private volatile Map<Long,Boolean> threadFlagMap = new HashMap<>();
    @Autowired
    public void setPwrdevAcdcdataService(PwrdevAcdcdataService service) {
        RealDataStaticAcSocket.acdcdataService = service;
    }
    @Autowired
    public void setPowerheartParamService(PowerheartParamService service) {
        RealDataStaticAcSocket.pwrHeartService = service;
    }
    @OnOpen
    public void onOpen(Session session, EndpointConfig config) {
        this.session = session;
        this.httpSession = (HttpSession) config.getUserProperties().get("httpSession");
    }
    @OnMessage
    public void onMessage(Session session, String message) {
        SticRealDataAc realData= ActionUtil.getGson().fromJson(message,SticRealDataAc.class);
        thread = new Thread("Thread_HeartacinSocket") {
            @Override
            public void run() {
                while (runFlag && !isInterrupted()) {
                    Thread thread = currentThread();
                    threadFlagMap.put(thread.getId(), true);
                    try {
                        ResRealDataAc dataAc = acdcdataService.getSticRealDataAc(realData);
                        if (session.isOpen()) {
                            //推送信息
                            synchronized (session) {
                                session.getBasicRemote().sendObject(new Response<>().setII(1,dataAc!=null,dataAc,"实时数据统计-交流单元"));
                            }
                            threadFlagMap.put(thread.getId(), false);
                        }
                        PowerheartParam powerheartParam=pwrHeartService.getHeartParamByPowerId(realData.getPowerId());
                        sleep(1000*60*powerheartParam.getAcinInterverCfg());
                    } catch (Exception e) {
                        interrupt();
                    }
                }
            }
        };
        thread.start();
        threadFlagMap.put(thread.getId(),true);
        //停止老的socket线程
        Thread threadBefore = threadMap.get(session.getId());
        if(threadBefore !=null && threadBefore.isAlive()){
            while (threadFlagMap.get(threadBefore.getId())){
            }
            threadBefore.interrupt();
        }
        //将线程存储,便于调用定位
        threadMap.put(session.getId(), this.thread);
    }
    @OnClose
    public void onClose(CloseReason closeReason){
        System.err.println("closeReason = " + closeReason);
        runFlag = false;
        if (thread != null && thread.isAlive()) {
            thread.interrupt();
        }
        threadMap.remove(session.getId());
    }
    @OnError
    public void onError(Throwable error) {
        error.printStackTrace();
        if (thread != null && thread.isAlive()) {
            thread.interrupt();
        }
        threadMap.remove(session.getId());
    }
}
src/main/java/com/whyc/webSocket/RealDataStaticHrSocket.java
New file
@@ -0,0 +1,114 @@
package com.whyc.webSocket;
import com.whyc.config.WebSocketConfig;
import com.whyc.dto.RealDataStatic.ResRealDataAc;
import com.whyc.dto.RealDataStatic.SticRealDataAc;
import com.whyc.dto.Response;
import com.whyc.pojo.db_param.PowerheartParam;
import com.whyc.service.BattRtstateService;
import com.whyc.service.PowerheartParamService;
import com.whyc.util.ActionUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import javax.servlet.http.HttpSession;
import javax.websocket.*;
import javax.websocket.server.ServerEndpoint;
import java.util.HashMap;
import java.util.Map;
/**
 * 实时数据统计推送核容设备,更改频率
 */
@Component
@ServerEndpoint(value = "/realsticHr",encoders = WebSocketEncoder.class,configurator = WebSocketConfig.class)
public class RealDataStaticHrSocket {
    private Session session;
    private Thread thread;
    private static BattRtstateService rtstateService;
    private static PowerheartParamService pwrHeartService;
    private static HttpSession httpSession;
    private volatile boolean runFlag = true;
    private volatile Map<String, Thread> threadMap = new HashMap<>();
    private volatile Map<Long,Boolean> threadFlagMap = new HashMap<>();
    @Autowired
    public void setBattRtstateService(BattRtstateService service) {
        RealDataStaticHrSocket.rtstateService = service;
    }
    @Autowired
    public void setPowerheartParamService(PowerheartParamService service) {
        RealDataStaticHrSocket.pwrHeartService = service;
    }
    @OnOpen
    public void onOpen(Session session, EndpointConfig config) {
        this.session = session;
        this.httpSession = (HttpSession) config.getUserProperties().get("httpSession");
    }
    @OnMessage
    public void onMessage(Session session, String message) {
        SticRealDataAc realData= ActionUtil.getGson().fromJson(message,SticRealDataAc.class);
        thread = new Thread("Thread_HeartacinSocket") {
            @Override
            public void run() {
                while (runFlag && !isInterrupted()) {
                    Thread thread = currentThread();
                    threadFlagMap.put(thread.getId(), true);
                    try {
                        ResRealDataAc dataAc = rtstateService.getSticRealDataAc(realData);
                        if (session.isOpen()) {
                            //推送信息
                            synchronized (session) {
                                session.getBasicRemote().sendObject(new Response<>().setII(1,dataAc!=null,dataAc,"实时数据统计-核容设备"));
                            }
                            threadFlagMap.put(thread.getId(), false);
                        }
                        PowerheartParam powerheartParam=pwrHeartService.getHeartParamByPowerId(realData.getPowerId());
                        sleep(1000*60*powerheartParam.getAcinInterverCfg());
                    } catch (Exception e) {
                        interrupt();
                    }
                }
            }
        };
        thread.start();
        threadFlagMap.put(thread.getId(),true);
        //停止老的socket线程
        Thread threadBefore = threadMap.get(session.getId());
        if(threadBefore !=null && threadBefore.isAlive()){
            while (threadFlagMap.get(threadBefore.getId())){
            }
            threadBefore.interrupt();
        }
        //将线程存储,便于调用定位
        threadMap.put(session.getId(), this.thread);
    }
    @OnClose
    public void onClose(CloseReason closeReason){
        System.err.println("closeReason = " + closeReason);
        runFlag = false;
        if (thread != null && thread.isAlive()) {
            thread.interrupt();
        }
        threadMap.remove(session.getId());
    }
    @OnError
    public void onError(Throwable error) {
        error.printStackTrace();
        if (thread != null && thread.isAlive()) {
            thread.interrupt();
        }
        threadMap.remove(session.getId());
    }
}
src/main/resources/excel_templates/realstic_ac_template.xlsx
Binary files differ
src/main/resources/excel_templates/template_device_spare.xlsx
Binary files differ
src/main/resources/mapper/DeviceSpareMapper.xml
@@ -13,4 +13,10 @@
            and supplier = #{item.supplier}
        </foreach>
    </update>
    <update id="updateQuantityAndPictureBatch">
        <foreach collection="list" item="item" separator=";">
            update web_site.tb_device_spare set quantity = #{item.quantity},picture_url = #{item.pictureUrl}
            where id = #{item.id}
        </foreach>
    </update>
</mapper>