Эх сурвалжийг харах

裂解巡检 - 每月一号测温/测压趋势图发邮件

wangggziwen 1 өдөр өмнө
parent
commit
50154d133e

+ 7 - 0
master/pom.xml

@@ -530,6 +530,13 @@
 <!--            <version>1.1.0</version>-->
 <!--        </dependency>-->
 
+        <!-- JFreeChart图表组件 -->
+        <dependency>
+            <groupId>org.jfree</groupId>
+            <artifactId>jfreechart</artifactId>
+            <version>1.5.3</version>
+        </dependency>
+
     </dependencies>
 
     <build>

+ 7 - 1
master/src/main/java/com/ruoyi/common/sendEmail/IMailServiceImpl.java

@@ -249,8 +249,14 @@ public class IMailServiceImpl implements IMailService {
             helper.setSubject(subject);
             helper.setText(content, true);
 
+//            FileSystemResource file = new FileSystemResource(new File(filePath));
+//            String fileName = filePath.substring(filePath.lastIndexOf(File.separator));
+
             FileSystemResource file = new FileSystemResource(new File(filePath));
-            String fileName = filePath.substring(filePath.lastIndexOf(File.separator));
+            logger.info("filePath::::::::::" + filePath);
+            String fileName = filePath.substring(filePath.lastIndexOf("/") + 1);
+            logger.info("fileName::::::::::" + fileName);
+
             helper.addAttachment(fileName, file);
             mailSender.send(message);
             //日志信息

+ 75 - 0
master/src/main/java/com/ruoyi/common/thread/furnance/FurnanceMonthlyMailThread.java

@@ -0,0 +1,75 @@
+package com.ruoyi.common.thread.furnance;
+
+import com.github.stuxuhai.jpinyin.PinyinException;
+import com.github.stuxuhai.jpinyin.PinyinFormat;
+import com.github.stuxuhai.jpinyin.PinyinHelper;
+import com.ruoyi.common.sendEmail.IMailService;
+import com.ruoyi.project.plant.domain.TStaffmgr;
+
+import java.util.Date;
+
+public class FurnanceMonthlyMailThread implements Runnable {
+
+    private IMailService mailService;
+
+    private String email;
+
+    private String staffName;
+
+    private String staffNameEN;
+
+    private String loginName;
+
+    private String filePath;
+
+    public FurnanceMonthlyMailThread() {}
+
+    public FurnanceMonthlyMailThread(IMailService mailService, TStaffmgr staffmgr, String loginName, String filePath) throws PinyinException {
+        this.mailService = mailService;
+        this.email = staffmgr.getMail();
+        this.staffName = staffmgr.getName();
+        this.staffNameEN = PinyinHelper.convertToPinyinString(staffName.trim(), " ", PinyinFormat.WITHOUT_TONE);
+        this.loginName =  loginName;
+        this.filePath =  filePath;
+    }
+
+    @Override
+    public void run() {
+        this.sendMail();
+    }
+
+    private void sendMail() {
+        String jumpUrl = "/production/temperature";
+        //写html开始内容
+        String start = "<!DOCTYPE html><html><head><meta charset=\"utf-8\"><title></title></head><body><div style=\"background-color:#ECECEC; padding: 35px;\">" +
+                "<table cellpadding=\"0\" align=\"center\"" +
+                "style=\"width: 600px; margin: 0px auto; text-align: left; position: relative; border-top-left-radius: 5px; border-top-right-radius: 5px; border-bottom-right-radius: 5px; border-bottom-left-radius: 5px; font-size: 14px; font-family:微软雅黑, 黑体; line-height: 1.5; box-shadow: rgb(153, 153, 153) 0px 0px 5px; border-collapse: collapse; background-position: initial initial; background-repeat: initial initial;background:#fff;\">" +
+                "<tbody><tr><th valign=\"middle\" style=\"height: 25px; line-height: 25px; padding: 15px 35px; border-bottom-width: 1px; border-bottom-style: solid; border-bottom-color: #42a3d3; background-color: #49bcff; border-top-left-radius: 5px; border-top-right-radius: 5px; border-bottom-right-radius: 0px; border-bottom-left-radius: 0px;\">" +
+                "<font face=\"微软雅黑\" size=\"5\" style=\"color: rgb(255, 255, 255); \">CPMS管理系统 </font><font face=\"微软雅黑\" size=\"3\" style=\"color: rgb(255, 255, 255); \">CPMS System</font></th></tr>";
+        //表html中间内容
+        String prime = "";
+        String center = "<tr><td><div style=\"padding:25px 35px 40px; background-color:#fff;\"><h2 style=\"margin: 5px 0px; \">" +
+                "<font color=\"#333333\" style=\"line-height: 20px; \"><font style=\"line-height: 22px; \" size=\"4\">" +
+                "亲爱的staffName</font><br><font style=\"line-height: 22px; \" size=\"4\">" +
+                "Dear staffNameEN(loginName)</font></font></h2>" +
+                "<p>请查收裂解炉月度数据趋势图。"  +
+                "详情请登录<a href=\"https://cpms.basf-ypc.net.cn/cpms/index.html#" + jumpUrl + "\">CPMS管理系统</a>查看。<br>" +
+                "Please log in the <a href=\"https://cpms.basf-ypc.net.cn/cpms/index.html#" + jumpUrl + "\">CPMS</a> to handle it.</p>" +
+                "<p align=\"right\">date</p>" +
+                "<div style=\"width:700px;margin:0 auto;\">" +
+                "<div style=\"padding:10px 10px 0;border-top:1px solid #ccc;color:#747474;margin-bottom:20px;line-height:1.3em;font-size:12px;\">" +
+                "<p>此为系统邮件,请勿回复<br>This e-Mail is an automatic reminder sent by CPMS, please do not reply</p>" +
+                "</div></div></div></td></tr>";
+        String one = center.replaceFirst("staffName", staffName);
+        String two = one.replaceFirst("staffNameEN", staffNameEN);
+        String three = two.replaceFirst("loginName", loginName);
+        String result = three.replaceFirst("date", String.valueOf(new Date())).replaceFirst("jumpUrl",jumpUrl).replaceFirst("jumpUrl",jumpUrl);
+        prime = prime + result;
+        //写html结尾内容
+        String end = "</tbody></table></div></body></html>";
+        //拼接html
+        String html = start + prime + end;
+        //发邮件(带附件)
+        mailService.sendAttachmentsMail(email, "CPMS:裂解炉月度数据趋势图", html, filePath);
+    }
+}

+ 2 - 0
master/src/main/java/com/ruoyi/framework/config/SecurityConfig.java

@@ -137,6 +137,8 @@ public class SecurityConfig extends WebSecurityConfigurerAdapter
                 .antMatchers("/safecheck/weekcheck/downloadWeekcheck").anonymous()
                 .antMatchers("/safecheck/weekcheck/downloadWeekcheckPdf").anonymous()
                 .antMatchers("/production/quality/export").anonymous()
+                .antMatchers("/production/temperature/coilAnalysis").anonymous()
+                .antMatchers("/production/pressure/coilAnalysis").anonymous()
                 .antMatchers("/system/appVersion/check").permitAll()
                 // 除上面外的所有请求全部需要鉴权认证
                 .anyRequest().authenticated()

+ 427 - 1
master/src/main/java/com/ruoyi/framework/task/FurnanceTask.java

@@ -2,16 +2,21 @@ package com.ruoyi.framework.task;
 
 import com.github.stuxuhai.jpinyin.PinyinException;
 import com.ruoyi.common.sendEmail.IMailService;
+import com.ruoyi.common.thread.furnance.FurnanceMonthlyMailThread;
 import com.ruoyi.common.thread.furnance.FurnancePressureThread;
 import com.ruoyi.common.thread.furnance.FurnanceTemperatureThread;
 import com.ruoyi.common.utils.StringUtils;
+import com.ruoyi.common.utils.document.ZipUtil;
+import com.ruoyi.framework.config.RuoYiConfig;
 import com.ruoyi.framework.web.controller.BaseController;
 import com.ruoyi.framework.web.domain.AjaxResult;
 import com.ruoyi.project.plant.domain.TStaffmgr;
 import com.ruoyi.project.plant.service.ITStaffmgrService;
 import com.ruoyi.project.production.controller.TFurnancePressureController;
 import com.ruoyi.project.production.controller.TFurnanceTemperatureController;
+import com.ruoyi.project.production.controller.vo.FurnancePressureCoilVO;
 import com.ruoyi.project.production.controller.vo.FurnancePressureFvpVO;
+import com.ruoyi.project.production.controller.vo.FurnanceTemperatureCoilVO;
 import com.ruoyi.project.production.controller.vo.FurnanceTemperatureVO;
 import com.ruoyi.project.production.domain.TFurnancePressure;
 import com.ruoyi.project.production.domain.TFurnanceTemperature;
@@ -21,12 +26,40 @@ import com.ruoyi.project.system.domain.SysDictData;
 import com.ruoyi.project.system.domain.SysUser;
 import com.ruoyi.project.system.service.ISysDictTypeService;
 import com.ruoyi.project.system.service.ISysUserService;
+import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
+import org.apache.poi.util.Units;
+import org.apache.poi.xwpf.usermodel.ParagraphAlignment;
+import org.apache.poi.xwpf.usermodel.XWPFDocument;
+import org.apache.poi.xwpf.usermodel.XWPFParagraph;
+import org.apache.poi.xwpf.usermodel.XWPFRun;
+import org.jfree.chart.ChartFactory;
+import org.jfree.chart.ChartUtils;
+import org.jfree.chart.JFreeChart;
+import org.jfree.chart.axis.*;
+import org.jfree.chart.plot.PlotOrientation;
+import org.jfree.chart.plot.XYPlot;
+import org.jfree.chart.renderer.xy.XYLineAndShapeRenderer;
+import org.jfree.chart.title.LegendTitle;
+import org.jfree.chart.title.TextTitle;
+import org.jfree.data.time.Day;
+import org.jfree.data.time.Hour;
+import org.jfree.data.time.TimeSeries;
+import org.jfree.data.time.TimeSeriesCollection;
+import org.jfree.data.xy.XYSeries;
+import org.jfree.data.xy.XYSeriesCollection;
+import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTPageMar;
+import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTPageSz;
+import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTSectPr;
+import org.openxmlformats.schemas.wordprocessingml.x2006.main.STPageOrientation;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Component;
 
+import java.awt.*;
+import java.io.*;
+import java.math.BigInteger;
 import java.text.ParseException;
 import java.text.SimpleDateFormat;
-import java.util.Date;
+import java.util.*;
 import java.util.List;
 
 /**
@@ -36,6 +69,12 @@ import java.util.List;
 @Component("furnanceTask")
 public class FurnanceTask extends BaseController {
 
+    // 全局中文字体(兼容Windows/Linux/Mac,避免中文方块)
+    private static final Font CHINESE_FONT = new Font("宋体", Font.PLAIN, 12);
+
+    // 标题字体(稍大)
+    private static final Font TITLE_FONT = new Font("宋体", Font.BOLD, 16);
+
     @Autowired
     private ITFurnancePressureService pressureService;
 
@@ -374,4 +413,391 @@ public class FurnanceTask extends BaseController {
         return flag;
     }
 
+    /**
+     * 每月一号测温/测压趋势图发邮件
+     */
+    public void sendMonthlyEmail() throws ParseException, PinyinException, IOException {
+        // 1. 设置日期范围
+        Date startDate = new Date();//上个月第一天
+        Date endDate = new Date();//上个月最后一天
+        Calendar cal = Calendar.getInstance();
+        cal.setTime(new Date());
+        cal.add(Calendar.MONTH, -1);//上个月
+        cal.set(Calendar.HOUR_OF_DAY, 0);
+        cal.set(Calendar.MINUTE, 0);
+        cal.set(Calendar.SECOND, 0);
+        cal.set(Calendar.MILLISECOND, 0);
+        cal.set(Calendar.DAY_OF_MONTH, 1);//上个月第一天
+        startDate.setTime(cal.getTimeInMillis());
+        cal.roll(Calendar.DAY_OF_MONTH, -1);//上个月最后一天
+        endDate.setTime(cal.getTimeInMillis());
+        String[] furnaceArray = {"H109", "H110", "H111", "H112", "H113", "H114", "H115", "H116", "H117", "H118", "H130"};// 裂解炉名称列表
+        TFurnanceTemperature temperature = new TFurnanceTemperature();//温度趋势图数据查询方法入参
+        temperature.setStartDate(startDate);
+        temperature.setEndDate(endDate);
+        TFurnancePressure pressure = new TFurnancePressure();//压力趋势图数据查询方法入参
+        pressure.setStartDate(startDate);
+        pressure.setEndDate(endDate);
+        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM");
+        String yearMonth = sdf.format(cal.getTime());//日期yyyy-MM
+        // 2. 生成JFreeChart图表
+        List<JFreeChart> tempChartList = new ArrayList<JFreeChart>();//测温趋势图集合
+        List<JFreeChart> pressureChartList = new ArrayList<JFreeChart>();//测压趋势图集合
+        for (String furnace : furnaceArray) {
+            temperature.setFurnanceName(furnace);
+            pressure.setFurnanceName(furnace);
+            switch (furnace) {//温度/压力趋势图数据查询&生成趋势图
+                case "H109":
+                    this.selectTemp109(temperature, tempChartList);
+                    this.selectPressure109(pressure, pressureChartList);
+                    break;
+                case "H130":
+                    this.selectTemp130(temperature, tempChartList);
+                    this.selectPressure130(pressure, pressureChartList);
+                    break;
+                default:
+                    this.selectTemp11x(temperature, tempChartList);
+                    this.selectPressure11x(pressure, pressureChartList);
+            }
+        }
+        // 3. 将JFreeChart图表转换为图片字节数组
+        List<byte[]> tempChartImages = new ArrayList<>();
+        for (JFreeChart chart : tempChartList) {
+            tempChartImages.add(this.convertChartToImage(chart, 600, 400));
+        }
+        List<byte[]> pressureChartImages = new ArrayList<>();
+        for (JFreeChart chart : pressureChartList) {
+            pressureChartImages.add(this.convertChartToImage(chart, 600, 400));
+        }
+        // 4. 新建文件目录
+        String profile = RuoYiConfig.getProfile();
+        String rootPath = profile + "/crackingTrendChart";//保存word文件的目录
+        File file = new File(rootPath);
+        file.mkdirs();
+        String zipPath = profile + "/crackingTrendChartZip";//保存zip文件的目录
+        File fileZip = new File(zipPath);
+        fileZip.mkdirs();
+        // 5. 将JFreeChart插入到word,并保存到刚才创建的word文件目录中
+        String tempFilePath = rootPath + "/裂解炉测温趋势图汇总(" + yearMonth + ").docx";//测温word文件
+        String pressureFilePath = rootPath + "/裂解炉测压趋势图汇总(" + yearMonth + ").docx";//测压word文件
+        this.createWordWithCharts(tempFilePath, tempChartImages, yearMonth);
+        this.createWordWithCharts(pressureFilePath, pressureChartImages, yearMonth);
+        // 6. 将word文件打包成zip,并保存到刚才创建的zip文件目录中
+        String zipName = fileZip + "/" + "裂解炉测温趋势图汇总(" + yearMonth + ").zip";//zip文件
+        ZipUtil.toZipWithDirectory(rootPath, zipName);
+        // 7. 发邮件(带zip附件)
+        List<SysDictData> furnanceRecipientDict = iSysDictTypeService.selectDictDataByType("FURNANCE_RECIPIENT_MONTHLY");//接收人字典
+        for (SysDictData sysDictData : furnanceRecipientDict) {
+            String dictValue = sysDictData.getDictValue();
+            TStaffmgr staffmgr = staffmgrService.selectTStaffmgrByStaffId(dictValue);
+            SysUser sysUser = userService.selectUserByStaffId(dictValue);
+            FurnanceMonthlyMailThread mailThread = new FurnanceMonthlyMailThread(mailService, staffmgr, sysUser.getUserName(), zipName);
+            Thread thread = new Thread(mailThread);
+            thread.start();
+        }
+    }
+
+    /** 创建Word并插入多个图表 */
+    private static void createWordWithCharts(String filePath, List<byte[]> chartImages, String yearMonth) {
+        // 新建word对象
+        XWPFDocument document = new XWPFDocument();
+        // 设置A4横版
+        CTSectPr sectPr = document.getDocument().getBody().addNewSectPr();
+        CTPageSz pageSz = sectPr.addNewPgSz();
+        pageSz.setW(BigInteger.valueOf(16840)); // A4宽度:21cm×91440 EMU/2.54cm = 16840
+        pageSz.setH(BigInteger.valueOf(11907)); // A4高度:14.85cm×91440 EMU/2.54cm = 11907
+        pageSz.setOrient(STPageOrientation.LANDSCAPE); // 横版
+        // 文档标题
+        XWPFParagraph titlePara = document.createParagraph();
+        titlePara.setAlignment(ParagraphAlignment.CENTER); // 段落居中
+        XWPFRun titleRun = titlePara.createRun();
+        titleRun.setText("裂解炉测温趋势图汇总(" + yearMonth + ")");
+        titleRun.setFontSize(16);
+        titleRun.addBreak();
+        // 遍历插入每个图表
+        for (int i = 0; i < chartImages.size(); i++) {
+            // 图表序号标题
+//            XWPFParagraph chartTitlePara = document.createParagraph();
+//            XWPFRun chartTitleRun = chartTitlePara.createRun();
+//            chartTitleRun.setText("第" + (i + 1) + "个图表");
+//            chartTitleRun.addBreak();
+            // 插入图片
+            XWPFParagraph imagePara = document.createParagraph();
+            ByteArrayInputStream bais = new ByteArrayInputStream(chartImages.get(i));
+            XWPFRun imageRun = imagePara.createRun();
+            // 插入时的图片尺寸(宽度600像素,高度400像素,和生成时一致)
+            try {
+                imageRun.addPicture(bais, XWPFDocument.PICTURE_TYPE_PNG, "chart" + i + ".png", Units.toEMU(600), Units.toEMU(400));
+                bais.close();
+            } catch (InvalidFormatException e) {
+                e.printStackTrace();
+            } catch (IOException e) {
+                e.printStackTrace();
+            }
+            // 图表间空行
+//            document.createParagraph().createRun().addBreak();
+        }
+        // 保存文档
+        FileOutputStream fos = null;
+        try {
+            fos = new FileOutputStream(filePath);
+            document.write(fos);
+            fos.close();
+            document.close();
+        } catch (FileNotFoundException e) {
+            e.printStackTrace();
+        } catch (IOException e) {
+            e.printStackTrace();
+        }
+    }
+
+    /** 图表转图片字节数组 */
+    private static byte[] convertChartToImage(JFreeChart chart, int width, int height) throws IOException {
+        ByteArrayOutputStream baos = new ByteArrayOutputStream();
+        javax.imageio.ImageIO.write(chart.createBufferedImage(width, height), "PNG", baos);
+        byte[] bytes = baos.toByteArray();
+        baos.close();
+        return bytes;
+    }
+
+    /** 生成温度趋势图 */
+    private JFreeChart genTempChart(List<FurnanceTemperatureCoilVO> list, String furnanceName, String passNo) throws IOException {
+        // 时间序列
+        TimeSeries series = new TimeSeries(furnanceName +  "_Pass" + passNo);
+        for (FurnanceTemperatureCoilVO item : list) {
+            series.addOrUpdate(new Day(item.getRecordTime().getDate(), item.getRecordTime().getMonth()+1, item.getRecordTime().getYear()+1900), item.getPassMaxValue());
+        }
+
+        // 封装时间序列为数据集
+        TimeSeriesCollection dataset = new TimeSeriesCollection();
+        dataset.addSeries(series);
+
+        // 1. 创建基础时序图
+        JFreeChart chart = ChartFactory.createTimeSeriesChart(
+                "Temperature_" + furnanceName +  "_Pass" + passNo, // 图表标题
+                "RecordTime", // X轴标签
+                "PassMaxValue", // Y轴标签
+                dataset, // 数据集
+                true, // 显示图例
+                false, // 关闭工具提示(无GUI无需)
+                false // 关闭URL链接
+        );
+
+        // 2. 优化中文显示:设置图表标题字体
+        TextTitle chartTitle = chart.getTitle();
+        chartTitle.setFont(TITLE_FONT);
+        chartTitle.setPaint(Color.BLACK); // 标题颜色
+
+        // 3. 优化图例中文显示
+        LegendTitle legend = chart.getLegend();
+        legend.setItemFont(CHINESE_FONT); // 图例文字字体
+        legend.setBackgroundPaint(Color.WHITE); // 图例背景(避免透明叠加)
+
+        // 4. 优化绘图区域样式
+        XYPlot plot = chart.getXYPlot();
+        plot.setBackgroundPaint(Color.LIGHT_GRAY);
+        plot.setDomainGridlinePaint(Color.WHITE); // X轴网格线
+        plot.setRangeGridlinePaint(Color.WHITE);  // Y轴网格线
+
+        // 5. X轴(日期轴)格式化
+        DateAxis dateAxis = (DateAxis) plot.getDomainAxis();
+        dateAxis.setLocale(Locale.CHINA); // 设置中国地区(避免日期显示英文)
+        // 自定义日期格式(如 "2025-01-01")
+        dateAxis.setDateFormatOverride(new SimpleDateFormat("yyyy-MM-dd"));
+        // 调整日期标签旋转角度(-45度,避免重叠)
+//        dateAxis.setLabelAngle(-Math.PI / 4);
+        // 设置X轴标签字体(中文支持)
+        dateAxis.setLabelFont(CHINESE_FONT);
+        dateAxis.setTickLabelFont(CHINESE_FONT); // 日期刻度字体
+        // 设置日期轴最小间隔(1天,避免刻度过密)
+        dateAxis.setTickUnit(new org.jfree.chart.axis.DateTickUnit(org.jfree.chart.axis.DateTickUnitType.DAY, 1));
+
+
+        // 6. 优化Y轴(数值轴)中文显示
+        ValueAxis valueAxis = plot.getRangeAxis();
+        valueAxis.setLabelFont(CHINESE_FONT); // Y轴标签字体
+        valueAxis.setTickLabelFont(CHINESE_FONT); // Y轴刻度字体
+
+        // 7. 优化线条和数据点样式
+        XYLineAndShapeRenderer renderer = new XYLineAndShapeRenderer();
+        renderer.setSeriesLinesVisible(0, true);
+        renderer.setSeriesShapesVisible(0, true);
+        renderer.setSeriesLinesVisible(1, true);
+        renderer.setSeriesShapesVisible(1, true);
+        // 可选:自定义线条颜色(区分两条序列)
+        renderer.setSeriesPaint(0, Color.RED); // 温度线:红色
+        renderer.setSeriesPaint(1, Color.BLUE); // 湿度线:蓝色
+        plot.setRenderer(renderer);
+
+        // 保存为PNG,参数:文件、图表、宽度、高度
+//        ChartUtils.saveChartAsPNG(new File("furnanceAnalysis/Temperature_" + furnanceName +  "_Pass" + passNo + ".png"), chart, 800, 600);
+
+        return chart;
+    }
+
+    /** 生成压力趋势图 */
+    private JFreeChart genPressureChart(List<FurnancePressureCoilVO> list, String furnanceName, String passNo) throws IOException {
+        // 时间序列
+        TimeSeries series = new TimeSeries(furnanceName +  "_Pass" + passNo);
+        for (FurnancePressureCoilVO item : list) {
+            series.addOrUpdate(new Hour(item.getRecordTime().getHours(), item.getRecordTime().getDate(), item.getRecordTime().getMonth()+1, item.getRecordTime().getYear()+1900), item.getPassMaxValue());
+        }
+
+        // 封装时间序列为数据集
+        TimeSeriesCollection dataset = new TimeSeriesCollection();
+        dataset.addSeries(series);
+
+        // 1. 创建基础时序图
+        JFreeChart chart = ChartFactory.createTimeSeriesChart(
+                "Pressure_" + furnanceName +  "_Pass" + passNo, // 图表标题
+                "RecordTime", // X轴标签
+                "PassMaxValue", // Y轴标签
+                dataset, // 数据集
+                true, // 显示图例
+                false, // 关闭工具提示(无GUI无需)
+                false // 关闭URL链接
+        );
+
+        // 2. 优化中文显示:设置图表标题字体
+        TextTitle chartTitle = chart.getTitle();
+        chartTitle.setFont(TITLE_FONT);
+        chartTitle.setPaint(Color.BLACK); // 标题颜色
+
+        // 3. 优化图例中文显示
+        LegendTitle legend = chart.getLegend();
+        legend.setItemFont(CHINESE_FONT); // 图例文字字体
+        legend.setBackgroundPaint(Color.WHITE); // 图例背景(避免透明叠加)
+
+        // 4. 优化绘图区域样式
+        XYPlot plot = chart.getXYPlot();
+        plot.setBackgroundPaint(Color.LIGHT_GRAY);
+        plot.setDomainGridlinePaint(Color.WHITE); // X轴网格线
+        plot.setRangeGridlinePaint(Color.WHITE);  // Y轴网格线
+
+        // 5. X轴(日期轴)格式化
+        DateAxis dateAxis = (DateAxis) plot.getDomainAxis();
+        dateAxis.setLocale(Locale.CHINA); // 设置中国地区(避免日期显示英文)
+        // 自定义日期格式(如 "2025-01-01")
+        dateAxis.setDateFormatOverride(new SimpleDateFormat("yyyy-MM-dd-HH"));
+        // 调整日期标签旋转角度(-45度,避免重叠)
+//        dateAxis.setLabelAngle(-Math.PI / 4);
+        // 设置X轴标签字体(中文支持)
+        dateAxis.setLabelFont(CHINESE_FONT);
+        dateAxis.setTickLabelFont(CHINESE_FONT); // 日期刻度字体
+        // 设置日期轴最小间隔(1天,避免刻度过密)
+        dateAxis.setTickUnit(new org.jfree.chart.axis.DateTickUnit(org.jfree.chart.axis.DateTickUnitType.DAY, 1));
+
+        // 6. 优化Y轴(数值轴)中文显示
+        ValueAxis valueAxis = plot.getRangeAxis();
+        valueAxis.setLabelFont(CHINESE_FONT); // Y轴标签字体
+        valueAxis.setTickLabelFont(CHINESE_FONT); // Y轴刻度字体
+
+        // 7. 优化线条和数据点样式
+        XYLineAndShapeRenderer renderer = new XYLineAndShapeRenderer();
+        renderer.setSeriesLinesVisible(0, true);
+        renderer.setSeriesShapesVisible(0, true);
+        renderer.setSeriesLinesVisible(1, true);
+        renderer.setSeriesShapesVisible(1, true);
+        // 可选:自定义线条颜色(区分两条序列)
+        renderer.setSeriesPaint(0, Color.RED); // 温度线:红色
+        renderer.setSeriesPaint(1, Color.BLUE); // 湿度线:蓝色
+        plot.setRenderer(renderer);
+
+        // 保存为PNG,参数:文件、图表、宽度、高度
+//        ChartUtils.saveChartAsPNG(new File("furnanceAnalysis/Pressure_" + furnanceName +  "_Pass" + passNo + ".png"), chart, 800, 600);
+
+        return chart;
+    }
+
+    /** 温度趋势图数据查询(H109) */
+    private void selectTemp109(TFurnanceTemperature temperature, List<JFreeChart> chartList) throws IOException {
+        logger.info("开始执行温度趋势图数据查询(H109)接口,入参: temperature={}", temperature.toString());
+        String[] passNoArray = {"1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12", "13", "14", "15", "16"};
+        for (String passNo : passNoArray) {
+            temperature.setPassNo(passNo);
+            AjaxResult ajaxResult = temperatureService.coilAnalysis(temperature);
+            List<FurnanceTemperatureCoilVO> coilVoList = (List<FurnanceTemperatureCoilVO>)ajaxResult.get("data");
+            // 生成趋势图
+            JFreeChart chart = this.genTempChart(coilVoList, temperature.getFurnanceName(), passNo);
+            chartList.add(chart);
+            logger.info(temperature.getFurnanceName()+" pass"+passNo+" 查询到数据条数:"+coilVoList.size());
+        }
+    }
+
+    /** 温度趋势图数据查询(H130) */
+    private void selectTemp130(TFurnanceTemperature temperature, List<JFreeChart> chartList) throws IOException {
+        logger.info("开始执行温度趋势图数据查询(H130)接口,入参: temperature={}", temperature.toString());
+        String[] passNoArray = {"1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12"};
+        for (String passNo : passNoArray) {
+            temperature.setPassNo(passNo);
+            AjaxResult ajaxResult = temperatureService.coilAnalysis(temperature);
+            List<FurnanceTemperatureCoilVO> coilVoList = (List<FurnanceTemperatureCoilVO>)ajaxResult.get("data");
+            // 生成趋势图
+            JFreeChart chart = this.genTempChart(coilVoList, temperature.getFurnanceName(), passNo);
+            chartList.add(chart);
+            logger.info(temperature.getFurnanceName()+" pass"+passNo+" 查询到数据条数:"+coilVoList.size());
+        }
+    }
+
+    /** 温度趋势图数据查询(H11x) */
+    private void selectTemp11x(TFurnanceTemperature temperature, List<JFreeChart> chartList) throws IOException {
+        logger.info("开始执行温度趋势图数据查询(H11x)接口,入参: temperature={}", temperature.toString());
+        String[] passNoArray = {"1", "2", "3", "4", "5", "6", "7", "8"};
+        for (String passNo : passNoArray) {
+            temperature.setPassNo(passNo);
+            AjaxResult ajaxResult = temperatureService.coilAnalysis(temperature);
+            List<FurnanceTemperatureCoilVO> coilVoList = (List<FurnanceTemperatureCoilVO>)ajaxResult.get("data");
+            // 生成趋势图
+            JFreeChart chart = this.genTempChart(coilVoList, temperature.getFurnanceName(), passNo);
+            chartList.add(chart);
+            logger.info(temperature.getFurnanceName()+" pass"+passNo+" 查询到数据条数:"+coilVoList.size());
+        }
+    }
+
+    /** 压力趋势图数据查询(H109) */
+    private void selectPressure109(TFurnancePressure pressure, List<JFreeChart> chartList) throws IOException {
+        logger.info("开始执行压力趋势图数据查询(H109)接口,入参: temperature={}", pressure.toString());
+        String[] passNoArray = {"1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12", "13", "14", "15", "16"};
+        for (String passNo : passNoArray) {
+            pressure.setPassNo(passNo);
+            AjaxResult ajaxResult = pressureService.coilAnalysis(pressure);
+            List<FurnancePressureCoilVO> coilVoList = (List<FurnancePressureCoilVO>)ajaxResult.get("data");
+            // 生成趋势图
+            JFreeChart chart = this.genPressureChart(coilVoList, pressure.getFurnanceName(), passNo);
+            chartList.add(chart);
+            logger.info(pressure.getFurnanceName()+" pass"+passNo+" 查询到数据条数:"+coilVoList.size());
+        }
+    }
+
+    /** 压力趋势图数据查询(H130) */
+    private void selectPressure130(TFurnancePressure pressure, List<JFreeChart> chartList) throws IOException {
+        logger.info("开始执行压力趋势图数据查询(H130)接口,入参: temperature={}", pressure.toString());
+        String[] passNoArray = {"1", "2", "3", "4"};
+        for (String passNo : passNoArray) {
+            pressure.setPassNo(passNo);
+            AjaxResult ajaxResult = pressureService.coilAnalysis(pressure);
+            List<FurnancePressureCoilVO> coilVoList = (List<FurnancePressureCoilVO>)ajaxResult.get("data");
+            // 生成趋势图
+            JFreeChart chart = this.genPressureChart(coilVoList, pressure.getFurnanceName(), passNo);
+            chartList.add(chart);
+            logger.info(pressure.getFurnanceName()+" pass"+passNo+" 查询到数据条数:"+coilVoList.size());
+        }
+    }
+
+    /** 压力趋势图数据查询(H11x) */
+    private void selectPressure11x(TFurnancePressure pressure, List<JFreeChart> chartList) throws IOException {
+        logger.info("开始执行压力趋势图数据查询(H11x)接口,入参: temperature={}", pressure.toString());
+        String[] passNoArray = {"1", "2", "3", "4", "5", "6", "7", "8"};
+        for (String passNo : passNoArray) {
+            pressure.setPassNo(passNo);
+            AjaxResult ajaxResult = pressureService.coilAnalysis(pressure);
+            List<FurnancePressureCoilVO> coilVoList = (List<FurnancePressureCoilVO>)ajaxResult.get("data");
+            // 生成趋势图
+            JFreeChart chart = this.genPressureChart(coilVoList, pressure.getFurnanceName(), passNo);
+            chartList.add(chart);
+            logger.info(pressure.getFurnanceName()+" pass"+passNo+" 查询到数据条数:"+coilVoList.size());
+        }
+    }
+
+
 }

+ 61 - 59
master/src/main/java/com/ruoyi/project/production/controller/TFurnancePressureController.java

@@ -44,6 +44,7 @@ import org.apache.http.impl.client.HttpClients;
 import org.apache.http.util.EntityUtils;
 import org.springframework.security.access.prepost.PreAuthorize;
 import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
 import org.springframework.web.bind.annotation.*;
 import com.ruoyi.framework.aspectj.lang.annotation.Log;
 import com.ruoyi.framework.aspectj.lang.enums.BusinessType;
@@ -3557,65 +3558,66 @@ public class TFurnancePressureController extends BaseController {
     @PreAuthorize("@ss.hasPermi('production:pressure:list')")
     @GetMapping("/coilAnalysis")
     public AjaxResult coilAnalysis(TFurnancePressure tFurnancePressure) {
-        String furnace = tFurnancePressure.getFurnanceName();
-        String pass = "pass" + tFurnancePressure.getPassNo();
-        Date startDate = tFurnancePressure.getStartDate();
-        Date endDate = tFurnancePressure.getEndDate();
-        TFurnancePressure pressure = new TFurnancePressure();//查询对象
-        pressure.setFurnanceName(furnace);
-        if (startDate == null && endDate == null) {//不包含指定日期
-            Date today = new Date();
-            Calendar addOneDay = Calendar.getInstance();
-            addOneDay.setTime(today);
-            addOneDay.add(Calendar.DAY_OF_MONTH, 1);
-            addOneDay.set(Calendar.HOUR_OF_DAY, 0);
-            addOneDay.set(Calendar.MINUTE, 0);
-            addOneDay.set(Calendar.SECOND, 0);
-            addOneDay.set(Calendar.MILLISECOND, 0);
-            Calendar minusOneMonth = Calendar.getInstance();
-            minusOneMonth.setTime(today);
-            minusOneMonth.add(Calendar.MONTH, -1);
-            minusOneMonth.set(Calendar.HOUR_OF_DAY, 0);
-            minusOneMonth.set(Calendar.MINUTE, 0);
-            minusOneMonth.set(Calendar.SECOND, 0);
-            minusOneMonth.set(Calendar.MILLISECOND, 0);
-            pressure.setStartDate(minusOneMonth.getTime());
-            pressure.setEndDate(addOneDay.getTime());
-        } else {//包含指定日期
-            pressure.setStartDate(startDate);
-            pressure.setEndDate(endDate);
-        }
-        List<TFurnancePressure> tFurnancePressures = tFurnancePressureService.selectCoilAnalysis(pressure);//原始数据列表
-        List<FurnancePressureCoilVO> coilVoList = new ArrayList<FurnancePressureCoilVO>();//返回数据列表
-        //数据组装
-        for (TFurnancePressure obj : tFurnancePressures) {
-            int passMaxValue = 0;//pass最大值
-            switch (furnace) {
-                case "H109":
-                    passMaxValue = this.setPassMaxValueH109(obj, pass);
-                    break;
-                case "H110":
-                case "H111":
-                case "H112":
-                case "H113":
-                case "H114":
-                case "H115":
-                case "H116":
-                case "H117":
-                case "H118":
-                    passMaxValue = this.setPassMaxValueH11x(obj, pass);
-                    break;
-                case "H130":
-                    passMaxValue = this.setPassMaxValueH130(obj, pass);
-                    break;
-            }
-            //插入返回列表
-            FurnancePressureCoilVO vo = new FurnancePressureCoilVO();
-            vo.setRecordTime(obj.getRecordTime());
-            vo.setPassMaxValue(passMaxValue);
-            coilVoList.add(vo);
-        }
-        return AjaxResult.success(coilVoList);
+//        String furnace = tFurnancePressure.getFurnanceName();
+//        String pass = "pass" + tFurnancePressure.getPassNo();
+//        Date startDate = tFurnancePressure.getStartDate();
+//        Date endDate = tFurnancePressure.getEndDate();
+//        TFurnancePressure pressure = new TFurnancePressure();//查询对象
+//        pressure.setFurnanceName(furnace);
+//        if (startDate == null && endDate == null) {//不包含指定日期
+//            Date today = new Date();
+//            Calendar addOneDay = Calendar.getInstance();
+//            addOneDay.setTime(today);
+//            addOneDay.add(Calendar.DAY_OF_MONTH, 1);
+//            addOneDay.set(Calendar.HOUR_OF_DAY, 0);
+//            addOneDay.set(Calendar.MINUTE, 0);
+//            addOneDay.set(Calendar.SECOND, 0);
+//            addOneDay.set(Calendar.MILLISECOND, 0);
+//            Calendar minusOneMonth = Calendar.getInstance();
+//            minusOneMonth.setTime(today);
+//            minusOneMonth.add(Calendar.MONTH, -1);
+//            minusOneMonth.set(Calendar.HOUR_OF_DAY, 0);
+//            minusOneMonth.set(Calendar.MINUTE, 0);
+//            minusOneMonth.set(Calendar.SECOND, 0);
+//            minusOneMonth.set(Calendar.MILLISECOND, 0);
+//            pressure.setStartDate(minusOneMonth.getTime());
+//            pressure.setEndDate(addOneDay.getTime());
+//        } else {//包含指定日期
+//            pressure.setStartDate(startDate);
+//            pressure.setEndDate(endDate);
+//        }
+//        List<TFurnancePressure> tFurnancePressures = tFurnancePressureService.selectCoilAnalysis(pressure);//原始数据列表
+//        List<FurnancePressureCoilVO> coilVoList = new ArrayList<FurnancePressureCoilVO>();//返回数据列表
+//        //数据组装
+//        for (TFurnancePressure obj : tFurnancePressures) {
+//            int passMaxValue = 0;//pass最大值
+//            switch (furnace) {
+//                case "H109":
+//                    passMaxValue = this.setPassMaxValueH109(obj, pass);
+//                    break;
+//                case "H110":
+//                case "H111":
+//                case "H112":
+//                case "H113":
+//                case "H114":
+//                case "H115":
+//                case "H116":
+//                case "H117":
+//                case "H118":
+//                    passMaxValue = this.setPassMaxValueH11x(obj, pass);
+//                    break;
+//                case "H130":
+//                    passMaxValue = this.setPassMaxValueH130(obj, pass);
+//                    break;
+//            }
+//            //插入返回列表
+//            FurnancePressureCoilVO vo = new FurnancePressureCoilVO();
+//            vo.setRecordTime(obj.getRecordTime());
+//            vo.setPassMaxValue(passMaxValue);
+//            coilVoList.add(vo);
+//        }
+//        return AjaxResult.success(coilVoList);
+        return tFurnancePressureService.coilAnalysis(tFurnancePressure);
     }
 
     /**

+ 76 - 76
master/src/main/java/com/ruoyi/project/production/controller/TFurnanceTemperatureController.java

@@ -14,9 +14,7 @@ import com.ruoyi.common.thread.furnance.FurnanceTemperatureThread;
 import com.ruoyi.common.utils.StringUtils;
 import com.ruoyi.project.plant.domain.TStaffmgr;
 import com.ruoyi.project.plant.service.ITStaffmgrService;
-import com.ruoyi.project.production.controller.vo.FurnancePressureFvpVO;
-import com.ruoyi.project.production.controller.vo.FurnanceSummaryVO;
-import com.ruoyi.project.production.controller.vo.FurnanceTemperatureVO;
+import com.ruoyi.project.production.controller.vo.*;
 import com.ruoyi.project.production.controller.vo.FurnanceTemperatureVO;
 import com.ruoyi.project.production.domain.TFurnancePressure;
 import com.ruoyi.project.production.domain.TFurnanceTemperature;
@@ -28,10 +26,11 @@ import com.ruoyi.project.system.service.ISysDictTypeService;
 import com.ruoyi.project.system.service.ISysUserService;
 import org.springframework.security.access.prepost.PreAuthorize;
 import com.ruoyi.common.utils.MathUtil;
-import com.ruoyi.project.production.controller.vo.FurnanceTemperatureCoilVO;
+
 import java.text.SimpleDateFormat;
 
 import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
 import org.springframework.web.bind.annotation.GetMapping;
 import org.springframework.web.bind.annotation.PostMapping;
 import org.springframework.web.bind.annotation.PutMapping;
@@ -1503,78 +1502,79 @@ public class TFurnanceTemperatureController extends BaseController
     @PreAuthorize("@ss.hasPermi('production:pressure:list')")
     @GetMapping("/coilAnalysis")
     public AjaxResult coilAnalysis(TFurnanceTemperature tFurnanceTemperature) {
-        logger.info("开始执行查询裂解炉炉管测温COIL趋势分析接口,入参: furnanceName={}, pass={}, startDate={}, endDate={}",
-                   tFurnanceTemperature.getFurnanceName(), tFurnanceTemperature.getPassNo(),
-                   tFurnanceTemperature.getStartDate(), tFurnanceTemperature.getEndDate());
-        try {
-            String furnace = tFurnanceTemperature.getFurnanceName();
-            String pass = "pass" + tFurnanceTemperature.getPassNo();
-            Date startDate = tFurnanceTemperature.getStartDate();
-            Date endDate = tFurnanceTemperature.getEndDate();
-            TFurnanceTemperature temperature = new TFurnanceTemperature();//查询对象
-            temperature.setFurnanceName(furnace);
-            if (startDate == null && endDate == null) {//不包含指定日期
-                Date today = new Date();
-                Calendar addOneDay = Calendar.getInstance();
-                addOneDay.setTime(today);
-                addOneDay.add(Calendar.DAY_OF_MONTH, 1);
-                addOneDay.set(Calendar.HOUR_OF_DAY, 0);
-                addOneDay.set(Calendar.MINUTE, 0);
-                addOneDay.set(Calendar.SECOND, 0);
-                addOneDay.set(Calendar.MILLISECOND, 0);
-                Calendar minusOneMonth = Calendar.getInstance();
-                minusOneMonth.setTime(today);
-                minusOneMonth.add(Calendar.MONTH, -1);
-                minusOneMonth.set(Calendar.HOUR_OF_DAY, 0);
-                minusOneMonth.set(Calendar.MINUTE, 0);
-                minusOneMonth.set(Calendar.SECOND, 0);
-                minusOneMonth.set(Calendar.MILLISECOND, 0);
-                temperature.setStartDate(minusOneMonth.getTime());
-                temperature.setEndDate(addOneDay.getTime());
-                logger.debug("未指定日期范围,使用默认范围: {} 到 {}", minusOneMonth.getTime(), addOneDay.getTime());
-            } else {//包含指定日期
-                temperature.setStartDate(startDate);
-                temperature.setEndDate(endDate);
-                logger.debug("使用指定日期范围: {} 到 {}", startDate, endDate);
-            }
-            List<TFurnanceTemperature> tFurnanceTemperatures = tFurnanceTemperatureService.selectCoilAnalysis(temperature);//原始数据列表
-            logger.info("查询到原始数据条数: {}", tFurnanceTemperatures.size());
-
-            List<FurnanceTemperatureCoilVO> coilVoList = new ArrayList<FurnanceTemperatureCoilVO>();//返回数据列表
-            //数据组装
-            for (TFurnanceTemperature obj : tFurnanceTemperatures) {
-                int passMaxValue = 0;//pass最大值
-                switch (furnace) {
-                    case "H109":
-                        passMaxValue = this.setPassMaxValueH109(obj, pass);
-                        break;
-                    case "H110":
-                    case "H111":
-                    case "H112":
-                    case "H113":
-                    case "H114":
-                    case "H115":
-                    case "H116":
-                    case "H117":
-                    case "H118":
-                        passMaxValue = this.setPassMaxValueH11x(obj, pass);
-                        break;
-                    case "H130":
-                        passMaxValue = this.setPassMaxValueH130(obj, pass);
-                        break;
-                }
-                //插入返回列表
-                FurnanceTemperatureCoilVO vo = new FurnanceTemperatureCoilVO();
-                vo.setRecordTime(obj.getRecordTime());
-                vo.setPassMaxValue(passMaxValue);
-                coilVoList.add(vo);
-            }
-            logger.info("查询裂解炉炉管测温COIL趋势分析接口执行完成,返回数据条数: {}", coilVoList.size());
-            return AjaxResult.success(coilVoList);
-        } catch (Exception e) {
-            logger.error("查询裂解炉炉管测温COIL趋势分析接口执行异常", e);
-            throw e;
-        }
+//        logger.info("开始执行查询裂解炉炉管测温COIL趋势分析接口,入参: furnanceName={}, pass={}, startDate={}, endDate={}",
+//                   tFurnanceTemperature.getFurnanceName(), tFurnanceTemperature.getPassNo(),
+//                   tFurnanceTemperature.getStartDate(), tFurnanceTemperature.getEndDate());
+//        try {
+//            String furnace = tFurnanceTemperature.getFurnanceName();
+//            String pass = "pass" + tFurnanceTemperature.getPassNo();
+//            Date startDate = tFurnanceTemperature.getStartDate();
+//            Date endDate = tFurnanceTemperature.getEndDate();
+//            TFurnanceTemperature temperature = new TFurnanceTemperature();//查询对象
+//            temperature.setFurnanceName(furnace);
+//            if (startDate == null && endDate == null) {//不包含指定日期
+//                Date today = new Date();
+//                Calendar addOneDay = Calendar.getInstance();
+//                addOneDay.setTime(today);
+//                addOneDay.add(Calendar.DAY_OF_MONTH, 1);
+//                addOneDay.set(Calendar.HOUR_OF_DAY, 0);
+//                addOneDay.set(Calendar.MINUTE, 0);
+//                addOneDay.set(Calendar.SECOND, 0);
+//                addOneDay.set(Calendar.MILLISECOND, 0);
+//                Calendar minusOneMonth = Calendar.getInstance();
+//                minusOneMonth.setTime(today);
+//                minusOneMonth.add(Calendar.MONTH, -1);
+//                minusOneMonth.set(Calendar.HOUR_OF_DAY, 0);
+//                minusOneMonth.set(Calendar.MINUTE, 0);
+//                minusOneMonth.set(Calendar.SECOND, 0);
+//                minusOneMonth.set(Calendar.MILLISECOND, 0);
+//                temperature.setStartDate(minusOneMonth.getTime());
+//                temperature.setEndDate(addOneDay.getTime());
+//                logger.debug("未指定日期范围,使用默认范围: {} 到 {}", minusOneMonth.getTime(), addOneDay.getTime());
+//            } else {//包含指定日期
+//                temperature.setStartDate(startDate);
+//                temperature.setEndDate(endDate);
+//                logger.debug("使用指定日期范围: {} 到 {}", startDate, endDate);
+//            }
+//            List<TFurnanceTemperature> tFurnanceTemperatures = tFurnanceTemperatureService.selectCoilAnalysis(temperature);//原始数据列表
+//            logger.info("查询到原始数据条数: {}", tFurnanceTemperatures.size());
+//
+//            List<FurnanceTemperatureCoilVO> coilVoList = new ArrayList<FurnanceTemperatureCoilVO>();//返回数据列表
+//            //数据组装
+//            for (TFurnanceTemperature obj : tFurnanceTemperatures) {
+//                int passMaxValue = 0;//pass最大值
+//                switch (furnace) {
+//                    case "H109":
+//                        passMaxValue = this.setPassMaxValueH109(obj, pass);
+//                        break;
+//                    case "H110":
+//                    case "H111":
+//                    case "H112":
+//                    case "H113":
+//                    case "H114":
+//                    case "H115":
+//                    case "H116":
+//                    case "H117":
+//                    case "H118":
+//                        passMaxValue = this.setPassMaxValueH11x(obj, pass);
+//                        break;
+//                    case "H130":
+//                        passMaxValue = this.setPassMaxValueH130(obj, pass);
+//                        break;
+//                }
+//                //插入返回列表
+//                FurnanceTemperatureCoilVO vo = new FurnanceTemperatureCoilVO();
+//                vo.setRecordTime(obj.getRecordTime());
+//                vo.setPassMaxValue(passMaxValue);
+//                coilVoList.add(vo);
+//            }
+//            logger.info("查询裂解炉炉管测温COIL趋势分析接口执行完成,返回数据条数: {}", coilVoList.size());
+//            return AjaxResult.success(coilVoList);
+//        } catch (Exception e) {
+//            logger.error("查询裂解炉炉管测温COIL趋势分析接口执行异常", e);
+//            throw e;
+//        }
+        return tFurnanceTemperatureService.coilAnalysis(tFurnanceTemperature);
     }
 
     public int setPassMaxValueH109(TFurnanceTemperature temperature, String pass) {

+ 7 - 0
master/src/main/java/com/ruoyi/project/production/controller/vo/FurnancePressureCoilVO.java

@@ -35,4 +35,11 @@ public class FurnancePressureCoilVO extends BaseEntity {
         this.passMaxValue = passMaxValue;
     }
 
+    @Override
+    public String toString() {
+        return "FurnancePressureCoilVO{" +
+                "recordTime=" + recordTime +
+                ", passMaxValue=" + passMaxValue +
+                '}';
+    }
 }

+ 7 - 0
master/src/main/java/com/ruoyi/project/production/controller/vo/FurnanceTemperatureCoilVO.java

@@ -35,4 +35,11 @@ public class FurnanceTemperatureCoilVO extends BaseEntity {
         this.passMaxValue = passMaxValue;
     }
 
+    @Override
+    public String toString() {
+        return "FurnanceTemperatureCoilVO{" +
+                "recordTime=" + recordTime +
+                ", passMaxValue=" + passMaxValue +
+                '}';
+    }
 }

+ 4 - 0
master/src/main/java/com/ruoyi/project/production/service/ITFurnancePressureService.java

@@ -1,6 +1,8 @@
 package com.ruoyi.project.production.service;
 
 import java.util.List;
+
+import com.ruoyi.framework.web.domain.AjaxResult;
 import com.ruoyi.project.production.domain.TFurnancePressure;
 
 /**
@@ -11,6 +13,8 @@ import com.ruoyi.project.production.domain.TFurnancePressure;
  */
 public interface ITFurnancePressureService 
 {
+    public AjaxResult coilAnalysis(TFurnancePressure tFurnancePressure);
+
     /**
      * 查询裂解炉炉管测压COIL趋势分析
      *

+ 3 - 0
master/src/main/java/com/ruoyi/project/production/service/ITFurnanceTemperatureService.java

@@ -2,6 +2,7 @@ package com.ruoyi.project.production.service;
 
 import java.util.List;
 
+import com.ruoyi.framework.web.domain.AjaxResult;
 import com.ruoyi.project.production.domain.TFurnancePressure;
 import com.ruoyi.project.production.domain.TFurnanceTemperature;
 
@@ -13,6 +14,8 @@ import com.ruoyi.project.production.domain.TFurnanceTemperature;
  */
 public interface ITFurnanceTemperatureService 
 {
+    public AjaxResult coilAnalysis(TFurnanceTemperature tFurnanceTemperature);
+
     /**
      * 查询裂解炉炉管测温COIL趋势分析
      *

+ 181 - 0
master/src/main/java/com/ruoyi/project/production/service/impl/TFurnancePressureServiceImpl.java

@@ -1,7 +1,17 @@
 package com.ruoyi.project.production.service.impl;
 
+import java.util.ArrayList;
+import java.util.Calendar;
+import java.util.Date;
 import java.util.List;
 import com.ruoyi.common.utils.DateUtils;
+import com.ruoyi.common.utils.StringUtils;
+import com.ruoyi.framework.web.controller.BaseController;
+import com.ruoyi.framework.web.domain.AjaxResult;
+import com.ruoyi.project.production.controller.vo.FurnancePressureCoilVO;
+import com.ruoyi.project.production.domain.TFurnanceTemperature;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 import com.ruoyi.project.production.mapper.TFurnancePressureMapper;
@@ -17,9 +27,180 @@ import com.ruoyi.project.production.service.ITFurnancePressureService;
 @Service
 public class TFurnancePressureServiceImpl implements ITFurnancePressureService
 {
+    protected final Logger logger = LoggerFactory.getLogger(BaseController.class);
+
     @Autowired
     private TFurnancePressureMapper tFurnancePressureMapper;
 
+    @Override
+    public AjaxResult coilAnalysis(TFurnancePressure tFurnancePressure) {
+        String furnace = tFurnancePressure.getFurnanceName();
+        String pass = "pass" + tFurnancePressure.getPassNo();
+        Date startDate = tFurnancePressure.getStartDate();
+        Date endDate = tFurnancePressure.getEndDate();
+        TFurnancePressure pressure = new TFurnancePressure();//查询对象
+        pressure.setFurnanceName(furnace);
+        if (startDate == null && endDate == null) {//不包含指定日期
+            Date today = new Date();
+            Calendar addOneDay = Calendar.getInstance();
+            addOneDay.setTime(today);
+            addOneDay.add(Calendar.DAY_OF_MONTH, 1);
+            addOneDay.set(Calendar.HOUR_OF_DAY, 0);
+            addOneDay.set(Calendar.MINUTE, 0);
+            addOneDay.set(Calendar.SECOND, 0);
+            addOneDay.set(Calendar.MILLISECOND, 0);
+            Calendar minusOneMonth = Calendar.getInstance();
+            minusOneMonth.setTime(today);
+            minusOneMonth.add(Calendar.MONTH, -1);
+            minusOneMonth.set(Calendar.HOUR_OF_DAY, 0);
+            minusOneMonth.set(Calendar.MINUTE, 0);
+            minusOneMonth.set(Calendar.SECOND, 0);
+            minusOneMonth.set(Calendar.MILLISECOND, 0);
+            pressure.setStartDate(minusOneMonth.getTime());
+            pressure.setEndDate(addOneDay.getTime());
+        } else {//包含指定日期
+            pressure.setStartDate(startDate);
+            pressure.setEndDate(endDate);
+        }
+        List<TFurnancePressure> tFurnancePressures = this.selectCoilAnalysis(pressure);//原始数据列表
+        List<FurnancePressureCoilVO> coilVoList = new ArrayList<FurnancePressureCoilVO>();//返回数据列表
+        //数据组装
+        for (TFurnancePressure obj : tFurnancePressures) {
+            int passMaxValue = 0;//pass最大值
+            switch (furnace) {
+                case "H109":
+                    passMaxValue = this.setPassMaxValueH109(obj, pass);
+                    break;
+                case "H110":
+                case "H111":
+                case "H112":
+                case "H113":
+                case "H114":
+                case "H115":
+                case "H116":
+                case "H117":
+                case "H118":
+                    passMaxValue = this.setPassMaxValueH11x(obj, pass);
+                    break;
+                case "H130":
+                    passMaxValue = this.setPassMaxValueH130(obj, pass);
+                    break;
+            }
+            //插入返回列表
+            FurnancePressureCoilVO vo = new FurnancePressureCoilVO();
+            vo.setRecordTime(obj.getRecordTime());
+            vo.setPassMaxValue(passMaxValue);
+            coilVoList.add(vo);
+        }
+        return AjaxResult.success(coilVoList);
+    }
+
+    public int setPassMaxValueH109(TFurnancePressure pressure, String pass) {
+        String pass1 = this.checkNull(pressure.getPass1());
+        String pass2 = this.checkNull(pressure.getPass2());
+        String pass3 = this.checkNull(pressure.getPass3());
+        String pass4 = this.checkNull(pressure.getPass4());
+        String pass5 = this.checkNull(pressure.getPass5());
+        String pass6 = this.checkNull(pressure.getPass6());
+        String pass7 = this.checkNull(pressure.getPass7());
+        String pass8 = this.checkNull(pressure.getPass8());
+        String pass9 = this.checkNull(pressure.getPass9());
+        String pass10 = this.checkNull(pressure.getPass10());
+        String pass11 = this.checkNull(pressure.getPass11());
+        String pass12 = this.checkNull(pressure.getPass12());
+        String pass13 = this.checkNull(pressure.getPass13());
+        String pass14 = this.checkNull(pressure.getPass14());
+        String pass15 = this.checkNull(pressure.getPass15());
+        String pass16 = this.checkNull(pressure.getPass16());
+        switch (pass) {
+            case "pass1": return this.getMaxValue(pass1 + "," + pass2);
+            case "pass2": return this.getMaxValue(pass3 + "," + pass4);
+            case "pass3": return this.getMaxValue(pass5 + "," + pass6);
+            case "pass4": return this.getMaxValue(pass7 + "," + pass8);
+            case "pass5": return this.getMaxValue(pass9 + "," + pass10);
+            case "pass6": return this.getMaxValue(pass11 + "," + pass12);
+            case "pass7": return this.getMaxValue(pass13 + "," + pass14);
+            case "pass8": return this.getMaxValue(pass15 + "," + pass16);
+        }
+        return 0;
+    }
+
+    public int setPassMaxValueH130(TFurnancePressure pressure, String pass) {
+        String pass1 = this.checkNull(pressure.getPass1());
+        String pass2 = this.checkNull(pressure.getPass2());
+        String pass3 = this.checkNull(pressure.getPass3());
+        String pass4 = this.checkNull(pressure.getPass4());
+        String pass5 = this.checkNull(pressure.getPass5());
+        String pass6 = this.checkNull(pressure.getPass6());
+        String pass7 = this.checkNull(pressure.getPass7());
+        String pass8 = this.checkNull(pressure.getPass8());
+        String pass9 = this.checkNull(pressure.getPass9());
+        String pass10 = this.checkNull(pressure.getPass10());
+        String pass11 = this.checkNull(pressure.getPass11());
+        String pass12 = this.checkNull(pressure.getPass12());
+        switch (pass) {
+            case "pass1": return this.getMaxValue(pass1);
+            case "pass2": return this.getMaxValue(pass2);
+            case "pass3": return this.getMaxValue(pass3);
+            case "pass4": return this.getMaxValue(pass4);
+            case "pass5": return this.getMaxValue(pass5);
+            case "pass6": return this.getMaxValue(pass6);
+            case "pass7": return this.getMaxValue(pass7);
+            case "pass8": return this.getMaxValue(pass8);
+            case "pass9": return this.getMaxValue(pass9);
+            case "pass10": return this.getMaxValue(pass10);
+            case "pass11": return this.getMaxValue(pass11);
+            case "pass12": return this.getMaxValue(pass12);
+        }
+        return 0;
+    }
+
+    public int setPassMaxValueH11x(TFurnancePressure pressure, String pass) {
+        String pass1 = this.checkNull(pressure.getPass1());
+        String pass2 = this.checkNull(pressure.getPass2());
+        String pass3 = this.checkNull(pressure.getPass3());
+        String pass4 = this.checkNull(pressure.getPass4());
+        String pass5 = this.checkNull(pressure.getPass5());
+        String pass6 = this.checkNull(pressure.getPass6());
+        String pass7 = this.checkNull(pressure.getPass7());
+        String pass8 = this.checkNull(pressure.getPass8());
+        switch (pass) {
+            case "pass1": return this.getMaxValue(pass1);
+            case "pass2": return this.getMaxValue(pass2);
+            case "pass3": return this.getMaxValue(pass3);
+            case "pass4": return this.getMaxValue(pass4);
+            case "pass5": return this.getMaxValue(pass5);
+            case "pass6": return this.getMaxValue(pass6);
+            case "pass7": return this.getMaxValue(pass7);
+            case "pass8": return this.getMaxValue(pass8);
+        }
+        return 0;
+    }
+
+    public String checkNull(String pass) {
+        if (StringUtils.isNull(pass)) {
+            return "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0";
+        } else {
+            return pass;
+        }
+    }
+
+    public int getMaxValue(String value) {
+        if (StringUtils.isNotNull(value) && StringUtils.isNotEmpty(value)) {
+            String[] split = value.split(",");
+            int max = Integer.parseInt(split[0]);
+            for (int i = 0; i < split.length; i++) {
+                int element = Integer.parseInt(split[i]);
+                if (element > max) {
+                    max = element;
+                }
+            }
+            return max;
+        } else {
+            return 0;
+        }
+    }
+
     @Override
     public List<TFurnancePressure> selectCoilAnalysis(TFurnancePressure tFurnancePressure) {
         return tFurnancePressureMapper.selectCoilAnalysis(tFurnancePressure);

+ 194 - 0
master/src/main/java/com/ruoyi/project/production/service/impl/TFurnanceTemperatureServiceImpl.java

@@ -1,7 +1,16 @@
 package com.ruoyi.project.production.service.impl;
 
+import java.util.ArrayList;
+import java.util.Calendar;
+import java.util.Date;
 import java.util.List;
 import com.ruoyi.common.utils.DateUtils;
+import com.ruoyi.common.utils.StringUtils;
+import com.ruoyi.framework.web.controller.BaseController;
+import com.ruoyi.framework.web.domain.AjaxResult;
+import com.ruoyi.project.production.controller.vo.FurnanceTemperatureCoilVO;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 import com.ruoyi.project.production.mapper.TFurnanceTemperatureMapper;
@@ -17,9 +26,194 @@ import com.ruoyi.project.production.service.ITFurnanceTemperatureService;
 @Service
 public class TFurnanceTemperatureServiceImpl implements ITFurnanceTemperatureService
 {
+    protected final Logger logger = LoggerFactory.getLogger(BaseController.class);
+
     @Autowired
     private TFurnanceTemperatureMapper tFurnanceTemperatureMapper;
 
+    @Override
+    public AjaxResult coilAnalysis(TFurnanceTemperature tFurnanceTemperature) {
+        logger.info("开始执行查询裂解炉炉管测温COIL趋势分析接口,入参: furnanceName={}, pass={}, startDate={}, endDate={}",
+                tFurnanceTemperature.getFurnanceName(), tFurnanceTemperature.getPassNo(),
+                tFurnanceTemperature.getStartDate(), tFurnanceTemperature.getEndDate());
+
+        try {
+            String furnace = tFurnanceTemperature.getFurnanceName();
+            String pass = "pass" + tFurnanceTemperature.getPassNo();
+            Date startDate = tFurnanceTemperature.getStartDate();
+            Date endDate = tFurnanceTemperature.getEndDate();
+            TFurnanceTemperature temperature = new TFurnanceTemperature();//查询对象
+            temperature.setFurnanceName(furnace);
+            if (startDate == null && endDate == null) {//不包含指定日期
+                Date today = new Date();
+                Calendar addOneDay = Calendar.getInstance();
+                addOneDay.setTime(today);
+                addOneDay.add(Calendar.DAY_OF_MONTH, 1);
+                addOneDay.set(Calendar.HOUR_OF_DAY, 0);
+                addOneDay.set(Calendar.MINUTE, 0);
+                addOneDay.set(Calendar.SECOND, 0);
+                addOneDay.set(Calendar.MILLISECOND, 0);
+                Calendar minusOneMonth = Calendar.getInstance();
+                minusOneMonth.setTime(today);
+                minusOneMonth.add(Calendar.MONTH, -1);
+                minusOneMonth.set(Calendar.HOUR_OF_DAY, 0);
+                minusOneMonth.set(Calendar.MINUTE, 0);
+                minusOneMonth.set(Calendar.SECOND, 0);
+                minusOneMonth.set(Calendar.MILLISECOND, 0);
+                temperature.setStartDate(minusOneMonth.getTime());
+                temperature.setEndDate(addOneDay.getTime());
+                logger.debug("未指定日期范围,使用默认范围: {} 到 {}", minusOneMonth.getTime(), addOneDay.getTime());
+            } else {//包含指定日期
+                temperature.setStartDate(startDate);
+                temperature.setEndDate(endDate);
+                logger.debug("使用指定日期范围: {} 到 {}", startDate, endDate);
+            }
+            List<TFurnanceTemperature> tFurnanceTemperatures = tFurnanceTemperatureMapper.selectCoilAnalysis(temperature);//原始数据列表
+            logger.info("查询到原始数据条数: {}", tFurnanceTemperatures.size());
+
+            List<FurnanceTemperatureCoilVO> coilVoList = new ArrayList<FurnanceTemperatureCoilVO>();//返回数据列表
+            //数据组装
+            for (TFurnanceTemperature obj : tFurnanceTemperatures) {
+                int passMaxValue = 0;//pass最大值
+                switch (furnace) {
+                    case "H109":
+                        passMaxValue = this.setPassMaxValueH109(obj, pass);
+                        break;
+                    case "H110":
+                    case "H111":
+                    case "H112":
+                    case "H113":
+                    case "H114":
+                    case "H115":
+                    case "H116":
+                    case "H117":
+                    case "H118":
+                        passMaxValue = this.setPassMaxValueH11x(obj, pass);
+                        break;
+                    case "H130":
+                        passMaxValue = this.setPassMaxValueH130(obj, pass);
+                        break;
+                }
+                //插入返回列表
+                FurnanceTemperatureCoilVO vo = new FurnanceTemperatureCoilVO();
+                vo.setRecordTime(obj.getRecordTime());
+                vo.setPassMaxValue(passMaxValue);
+                coilVoList.add(vo);
+            }
+            logger.info("查询裂解炉炉管测温COIL趋势分析接口执行完成,返回数据条数: {}", coilVoList.size());
+            return AjaxResult.success(coilVoList);
+        } catch (Exception e) {
+            logger.error("查询裂解炉炉管测温COIL趋势分析接口执行异常", e);
+            throw e;
+        }
+    }
+
+    public int setPassMaxValueH109(TFurnanceTemperature temperature, String pass) {
+        String pass1 = this.checkNull(temperature.getPass1());
+        String pass2 = this.checkNull(temperature.getPass2());
+        String pass3 = this.checkNull(temperature.getPass3());
+        String pass4 = this.checkNull(temperature.getPass4());
+        String pass5 = this.checkNull(temperature.getPass5());
+        String pass6 = this.checkNull(temperature.getPass6());
+        String pass7 = this.checkNull(temperature.getPass7());
+        String pass8 = this.checkNull(temperature.getPass8());
+        String pass9 = this.checkNull(temperature.getPass9());
+        String pass10 = this.checkNull(temperature.getPass10());
+        String pass11 = this.checkNull(temperature.getPass11());
+        String pass12 = this.checkNull(temperature.getPass12());
+        String pass13 = this.checkNull(temperature.getPass13());
+        String pass14 = this.checkNull(temperature.getPass14());
+        String pass15 = this.checkNull(temperature.getPass15());
+        String pass16 = this.checkNull(temperature.getPass16());
+        switch (pass) {
+            case "pass1": return this.getMaxValue(pass1 + "," + pass2);
+            case "pass2": return this.getMaxValue(pass3 + "," + pass4);
+            case "pass3": return this.getMaxValue(pass5 + "," + pass6);
+            case "pass4": return this.getMaxValue(pass7 + "," + pass8);
+            case "pass5": return this.getMaxValue(pass9 + "," + pass10);
+            case "pass6": return this.getMaxValue(pass11 + "," + pass12);
+            case "pass7": return this.getMaxValue(pass13 + "," + pass14);
+            case "pass8": return this.getMaxValue(pass15 + "," + pass16);
+        }
+        return 0;
+    }
+
+    public int setPassMaxValueH130(TFurnanceTemperature temperature, String pass) {
+        String pass1 = this.checkNull(temperature.getPass1());
+        String pass2 = this.checkNull(temperature.getPass2());
+        String pass3 = this.checkNull(temperature.getPass3());
+        String pass4 = this.checkNull(temperature.getPass4());
+        String pass5 = this.checkNull(temperature.getPass5());
+        String pass6 = this.checkNull(temperature.getPass6());
+        String pass7 = this.checkNull(temperature.getPass7());
+        String pass8 = this.checkNull(temperature.getPass8());
+        String pass9 = this.checkNull(temperature.getPass9());
+        String pass10 = this.checkNull(temperature.getPass10());
+        String pass11 = this.checkNull(temperature.getPass11());
+        String pass12 = this.checkNull(temperature.getPass12());
+        switch (pass) {
+            case "pass1": return this.getMaxValue(pass1);
+            case "pass2": return this.getMaxValue(pass2);
+            case "pass3": return this.getMaxValue(pass3);
+            case "pass4": return this.getMaxValue(pass4);
+            case "pass5": return this.getMaxValue(pass5);
+            case "pass6": return this.getMaxValue(pass6);
+            case "pass7": return this.getMaxValue(pass7);
+            case "pass8": return this.getMaxValue(pass8);
+            case "pass9": return this.getMaxValue(pass9);
+            case "pass10": return this.getMaxValue(pass10);
+            case "pass11": return this.getMaxValue(pass11);
+            case "pass12": return this.getMaxValue(pass12);
+        }
+        return 0;
+    }
+
+    public int setPassMaxValueH11x(TFurnanceTemperature temperature, String pass) {
+        String pass1 = this.checkNull(temperature.getPass1());
+        String pass2 = this.checkNull(temperature.getPass2());
+        String pass3 = this.checkNull(temperature.getPass3());
+        String pass4 = this.checkNull(temperature.getPass4());
+        String pass5 = this.checkNull(temperature.getPass5());
+        String pass6 = this.checkNull(temperature.getPass6());
+        String pass7 = this.checkNull(temperature.getPass7());
+        String pass8 = this.checkNull(temperature.getPass8());
+        switch (pass) {
+            case "pass1": return this.getMaxValue(pass1);
+            case "pass2": return this.getMaxValue(pass2);
+            case "pass3": return this.getMaxValue(pass3);
+            case "pass4": return this.getMaxValue(pass4);
+            case "pass5": return this.getMaxValue(pass5);
+            case "pass6": return this.getMaxValue(pass6);
+            case "pass7": return this.getMaxValue(pass7);
+            case "pass8": return this.getMaxValue(pass8);
+        }
+        return 0;
+    }
+
+    public String checkNull(String pass) {
+        if (StringUtils.isNull(pass)) {
+            return "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0";
+        } else {
+            return pass;
+        }
+    }
+
+    public int getMaxValue(String value) {
+        if (StringUtils.isNotNull(value) && StringUtils.isNotEmpty(value)) {
+            String[] split = value.split(",");
+            int max = Integer.parseInt(split[0]);
+            for (int i = 0; i < split.length; i++) {
+                int element = Integer.parseInt(split[i]);
+                if (element > max) {
+                    max = element;
+                }
+            }
+            return max;
+        } else {
+            return 0;
+        }
+    }
+
     @Override
     public List<TFurnanceTemperature> selectCoilAnalysis(TFurnanceTemperature tFurnanceTemperature) {
         return tFurnanceTemperatureMapper.selectCoilAnalysis(tFurnanceTemperature);

+ 1 - 1
ui/src/views/aerial/detail/index.vue

@@ -56,7 +56,7 @@
     <el-dialog
       :title="dialogTitle"
       :visible.sync="dialogVisible"
-      width="80%">
+      width="60%">
       <div class="video-player-container">
         <video-player
           class="video-player"