作者 钟来

水产舆情采集海报生成

@@ -2,10 +2,12 @@ package com.ruoyi.quartz.task; @@ -2,10 +2,12 @@ package com.ruoyi.quartz.task;
2 2
3 import cn.hutool.http.HttpUtil; 3 import cn.hutool.http.HttpUtil;
4 import com.alibaba.fastjson.JSONObject; 4 import com.alibaba.fastjson.JSONObject;
  5 +import com.google.common.io.Resources;
5 import com.ruoyi.common.constant.Constants; 6 import com.ruoyi.common.constant.Constants;
6 import com.ruoyi.common.tool.SysLogininforType; 7 import com.ruoyi.common.tool.SysLogininforType;
7 import com.ruoyi.common.utils.DateUtils; 8 import com.ruoyi.common.utils.DateUtils;
8 import com.ruoyi.common.utils.MessageUtils; 9 import com.ruoyi.common.utils.MessageUtils;
  10 +import com.ruoyi.quartz.task.aquatic.AquaticPublicOpinionBase;
9 import com.ruoyi.quartz.task.aquatic.AquaticPublicOpinionService; 11 import com.ruoyi.quartz.task.aquatic.AquaticPublicOpinionService;
10 import com.zhonglai.luhui.dao.service.PublicService; 12 import com.zhonglai.luhui.dao.service.PublicService;
11 import com.zhonglai.luhui.sys.manager.AsyncManager; 13 import com.zhonglai.luhui.sys.manager.AsyncManager;
@@ -15,9 +17,17 @@ import org.slf4j.LoggerFactory; @@ -15,9 +17,17 @@ import org.slf4j.LoggerFactory;
15 import org.springframework.beans.factory.annotation.Autowired; 17 import org.springframework.beans.factory.annotation.Autowired;
16 import org.springframework.stereotype.Component; 18 import org.springframework.stereotype.Component;
17 19
  20 +import java.nio.file.Files;
  21 +import java.nio.file.Path;
  22 +import java.nio.file.Paths;
  23 +import java.util.*;
  24 +
  25 +import javax.imageio.ImageIO;
  26 +import java.awt.*;
  27 +import java.awt.image.BufferedImage;
  28 +import java.io.File;
  29 +import java.io.IOException;
18 import java.util.List; 30 import java.util.List;
19 -import java.util.Map;  
20 -import java.util.TimerTask;  
21 31
22 /** 32 /**
23 * 水产舆情 33 * 水产舆情
@@ -31,7 +41,7 @@ public class AquaticPublicOpinionTask { @@ -31,7 +41,7 @@ public class AquaticPublicOpinionTask {
31 protected PublicService publicService; 41 protected PublicService publicService;
32 public void run(String day) 42 public void run(String day)
33 { 43 {
34 - for (AquaticPublicOpinionService service : aquaticPublicOpinionServices) { 44 + for (AquaticPublicOpinionService service : aquaticPublicOpinionServices) {
35 AsyncManager.me().execute(new TimerTask() { 45 AsyncManager.me().execute(new TimerTask() {
36 @Override 46 @Override
37 public void run() { 47 public void run() {
@@ -53,6 +63,7 @@ public class AquaticPublicOpinionTask { @@ -53,6 +63,7 @@ public class AquaticPublicOpinionTask {
53 63
54 if (null != lsit && lsit.size()!=0) 64 if (null != lsit && lsit.size()!=0)
55 { 65 {
  66 + List<AbstractMap.SimpleEntry<String, String>> dataList = new ArrayList<>();
56 for (Map<String,Object> map:lsit) 67 for (Map<String,Object> map:lsit)
57 { 68 {
58 StringBuffer content = new StringBuffer(); 69 StringBuffer content = new StringBuffer();
@@ -71,8 +82,9 @@ public class AquaticPublicOpinionTask { @@ -71,8 +82,9 @@ public class AquaticPublicOpinionTask {
71 text.put("mentioned_mobile_list",new String[]{"@all"}); 82 text.put("mentioned_mobile_list",new String[]{"@all"});
72 jsonObject.put("text",text); 83 jsonObject.put("text",text);
73 HttpUtil.post("https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key=6d6b4790-d20f-4692-bc4a-e8ceb1e8cfda",jsonObject.toJSONString()); 84 HttpUtil.post("https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key=6d6b4790-d20f-4692-bc4a-e8ceb1e8cfda",jsonObject.toJSONString());
74 -  
75 } 85 }
  86 +
  87 +
76 } 88 }
77 } 89 }
78 } 90 }
@@ -23,11 +23,13 @@ public abstract class AquaticPublicOpinionBase implements AquaticPublicOpinionS @@ -23,11 +23,13 @@ public abstract class AquaticPublicOpinionBase implements AquaticPublicOpinionS
23 protected final Logger logger = LoggerFactory.getLogger(this.getClass()); 23 protected final Logger logger = LoggerFactory.getLogger(this.getClass());
24 @Autowired 24 @Autowired
25 protected PublicService publicService; 25 protected PublicService publicService;
  26 +
  27 + public static final String saveFilePath = "uploadPath/aquaticPublicOpinion/";
26 public void updateSaveInfo(String text,Integer id) 28 public void updateSaveInfo(String text,Integer id)
27 { 29 {
28 if(StringUtils.isNotEmpty(text)) 30 if(StringUtils.isNotEmpty(text))
29 { 31 {
30 - Path path = Paths.get("uploadPath/aquaticPublicOpinion/"+id+".txt"); 32 + Path path = Paths.get(saveFilePath+id+".txt");
31 String filepath = saveFile(text, path); 33 String filepath = saveFile(text, path);
32 if(StringUtils.isNotEmpty(filepath)) 34 if(StringUtils.isNotEmpty(filepath))
33 { 35 {
@@ -69,10 +69,10 @@ public class WwwCafsAcCn extends AquaticPublicOpinionBase{ @@ -69,10 +69,10 @@ public class WwwCafsAcCn extends AquaticPublicOpinionBase{
69 StringBuilder text = new StringBuilder(); 69 StringBuilder text = new StringBuilder();
70 70
71 // 遍历段落,保留换行 71 // 遍历段落,保留换行
72 - for (Element p : content.select("p")) { 72 + for (Element p : content.children()) {
73 String line = p.text().trim(); 73 String line = p.text().trim();
74 if (!line.isEmpty()) { 74 if (!line.isEmpty()) {
75 - text.append(line).append("\n\n"); 75 + text.append(line).append("\n");
76 } 76 }
77 } 77 }
78 78
@@ -77,10 +77,10 @@ public class WwwChinaCfaOrg extends AquaticPublicOpinionBase{ @@ -77,10 +77,10 @@ public class WwwChinaCfaOrg extends AquaticPublicOpinionBase{
77 StringBuilder text = new StringBuilder(); 77 StringBuilder text = new StringBuilder();
78 78
79 // 遍历段落,保留换行 79 // 遍历段落,保留换行
80 - for (Element p : content.select("p")) { 80 + for (Element p : content.children()) {
81 String line = p.text().trim(); 81 String line = p.text().trim();
82 if (!line.isEmpty()) { 82 if (!line.isEmpty()) {
83 - text.append(line).append("\n\n"); 83 + text.append(line).append("\n");
84 } 84 }
85 } 85 }
86 86
@@ -67,10 +67,10 @@ public class WwwCsfishOrgCn extends AquaticPublicOpinionBase{ @@ -67,10 +67,10 @@ public class WwwCsfishOrgCn extends AquaticPublicOpinionBase{
67 text.append( title); 67 text.append( title);
68 text.append("\n\n"); 68 text.append("\n\n");
69 // 遍历段落,保留换行 69 // 遍历段落,保留换行
70 - for (Element p : content.select("p")) { 70 + for (Element p : content.children()) {
71 String line = p.text().trim(); 71 String line = p.text().trim();
72 if (!line.isEmpty()) { 72 if (!line.isEmpty()) {
73 - text.append(line).append("\n\n"); 73 + text.append(line).append("\n");
74 } 74 }
75 } 75 }
76 76
@@ -44,10 +44,10 @@ public class WwwMoaGovCn extends AquaticPublicOpinionBase{ @@ -44,10 +44,10 @@ public class WwwMoaGovCn extends AquaticPublicOpinionBase{
44 StringBuilder text = new StringBuilder(); 44 StringBuilder text = new StringBuilder();
45 45
46 // 遍历段落,保留换行 46 // 遍历段落,保留换行
47 - for (Element p : content.select("p")) { 47 + for (Element p : content.children()) {
48 String line = p.text().trim(); 48 String line = p.text().trim();
49 if (!line.isEmpty()) { 49 if (!line.isEmpty()) {
50 - text.append(line).append("\n\n"); 50 + text.append(line).append("\n");
51 } 51 }
52 } 52 }
53 53
@@ -91,10 +91,10 @@ public class WwwNftecAgriCn extends AquaticPublicOpinionBase{ @@ -91,10 +91,10 @@ public class WwwNftecAgriCn extends AquaticPublicOpinionBase{
91 StringBuilder text = new StringBuilder(); 91 StringBuilder text = new StringBuilder();
92 92
93 // 遍历段落,保留换行 93 // 遍历段落,保留换行
94 - for (Element p : content.select("p")) { 94 + for (Element p : content.children()) {
95 String line = p.text().trim(); 95 String line = p.text().trim();
96 if (!line.isEmpty()) { 96 if (!line.isEmpty()) {
97 - text.append(line).append("\n\n"); 97 + text.append(line).append("\n");
98 } 98 }
99 } 99 }
100 100
@@ -109,4 +109,10 @@ public class WwwNftecAgriCn extends AquaticPublicOpinionBase{ @@ -109,4 +109,10 @@ public class WwwNftecAgriCn extends AquaticPublicOpinionBase{
109 return null; 109 return null;
110 } 110 }
111 111
  112 +
  113 + public static void main(String[] args) {
  114 + WwwNftecAgriCn wwwNftecAgriCn = new WwwNftecAgriCn();
  115 + String str= wwwNftecAgriCn.getInfo("http://www.nftec.agri.cn/tzgg/202507/t20250711_8748522.htm");
  116 + System.out.println(str);
  117 + }
112 } 118 }
  1 +package com.ruoyi.quartz.util;
  2 +
  3 +import com.google.common.io.Resources;
  4 +import com.ruoyi.common.utils.DateUtils;
  5 +
  6 +import javax.imageio.ImageIO;
  7 +import java.awt.*;
  8 +import java.awt.image.BufferedImage;
  9 +import java.awt.AlphaComposite;
  10 +import java.io.File;
  11 +import java.io.IOException;
  12 +import java.util.*;
  13 +import java.util.List;
  14 +
  15 +public class MultiTextImageGenerator {
  16 +
  17 + private static final String savePath = "uploadPath/aquaticPublicOpinion/img/";
  18 + private static final String backgroundPath = "moban.png";
  19 + public static void main(String[] args) throws IOException {
  20 + // 1. 示例数据
  21 + List<AbstractMap.SimpleEntry<String, String>> dataList = Arrays.asList(
  22 + new AbstractMap.SimpleEntry<>("水质监测", "用于监测水体中溶氧、温度、pH 等参数,保障水产养殖环境。"),
  23 + new AbstractMap.SimpleEntry<>("智能告警", "当监测数据异常时,可通过APP或短信方式自动告警提醒。"),
  24 + new AbstractMap.SimpleEntry<>("移动便携", "设备小巧轻便,支持户外测量,数据实时同步上传。")
  25 + );
  26 + // 2. 配置加载
  27 + generateImage(dataList,new StyleConfig());
  28 + }
  29 +
  30 + public static String generateImage(List<AbstractMap.SimpleEntry<String, String>> dataList, StyleConfig style) throws IOException {
  31 +
  32 +
  33 + // 3. 背景图
  34 + BufferedImage image = ImageIO.read(new File(backgroundPath));
  35 + int width = image.getWidth();
  36 + int height = image.getHeight();
  37 + BufferedImage newImage = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
  38 + Graphics2D g = newImage.createGraphics();
  39 + g.drawImage(image, 0, 0, null);
  40 +
  41 + // 抗锯齿
  42 + g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
  43 + g.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
  44 +
  45 + int maxTextWidth = width - 2 * style.startX;
  46 + int currY = style.startY;
  47 +
  48 + // 4. 绘制每组内容块
  49 + for (int i = 0; i < dataList.size(); i++) {
  50 + String title = (i + 1) + ". " + dataList.get(i).getKey();
  51 + String content = dataList.get(i).getValue();
  52 +
  53 + g.setFont(style.titleFont);
  54 + FontMetrics titleMetrics = g.getFontMetrics();
  55 + int titleHeight = titleMetrics.getHeight();
  56 +
  57 + g.setFont(style.contentFont);
  58 + FontMetrics contentMetrics = g.getFontMetrics();
  59 + List<String> lines = splitTextIntoLines(content, contentMetrics, maxTextWidth);
  60 + int lineHeight = contentMetrics.getHeight() + style.lineSpacing;
  61 + int contentHeight = lines.size() * lineHeight;
  62 + int totalTextHeight = titleHeight + 10 + contentHeight;
  63 + int blockHeight = totalTextHeight + 2 * style.padding;
  64 +
  65 + int blockWidth = maxTextWidth + 2 * style.padding;
  66 + int blockX = style.startX - style.padding;
  67 + int blockY = currY;
  68 +
  69 + if (style.showBackgroundBlock)
  70 + {
  71 + g.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, style.backgroundAlpha));
  72 + g.setColor(style.backgroundColor);
  73 + g.fillRoundRect(blockX, blockY, blockWidth, blockHeight, style.cornerRadius, style.cornerRadius);
  74 + }
  75 +
  76 + g.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 1.0f));
  77 + g.setColor(style.textColor);
  78 +
  79 + int textStartY = blockY + style.padding + (blockHeight - 2 * style.padding - totalTextHeight) / 2;
  80 +
  81 + g.setFont(style.titleFont);
  82 + int titleY = textStartY + titleHeight;
  83 + g.drawString(title, style.startX, titleY);
  84 +
  85 + g.setFont(style.contentFont);
  86 + int contentStartY = titleY + 10 + lineHeight;
  87 + for (int j = 0; j < lines.size(); j++) {
  88 + int y = contentStartY + j * lineHeight;
  89 + g.drawString(lines.get(j), style.startX, y);
  90 + }
  91 +
  92 + currY = blockY + blockHeight + style.blockSpacing;
  93 + }
  94 +
  95 + // 5. 添加文字水印
  96 + drawTextWatermark(g, width, height, style);
  97 +
  98 + // 6. 添加图片水印
  99 +// drawImageWatermark(g, width, height, style);
  100 +
  101 + g.dispose();
  102 +
  103 + // 7. 保存输出
  104 + String saveFile = savePath + DateUtils.getDate()+ "_output.png";
  105 + ImageIO.write(newImage, "png", new File(saveFile));
  106 + return saveFile;
  107 + }
  108 +
  109 + // 文字自动换行
  110 + private static List<String> splitTextIntoLines(String text, FontMetrics metrics, int maxWidth) {
  111 + List<String> lines = new ArrayList<>();
  112 + StringBuilder line = new StringBuilder();
  113 + for (char c : text.toCharArray()) {
  114 + line.append(c);
  115 + if (metrics.stringWidth(line.toString()) > maxWidth) {
  116 + line.deleteCharAt(line.length() - 1);
  117 + lines.add(line.toString());
  118 + line = new StringBuilder().append(c);
  119 + }
  120 + }
  121 + if (!line.toString().isEmpty()) {
  122 + lines.add(line.toString());
  123 + }
  124 + return lines;
  125 + }
  126 +
  127 + // 文字水印
  128 + private static void drawTextWatermark(Graphics2D g, int width, int height, StyleConfig style) {
  129 + g.setFont(style.watermarkFont);
  130 + g.setColor(style.watermarkColor);
  131 + FontMetrics metrics = g.getFontMetrics();
  132 + int textWidth = metrics.stringWidth(style.watermarkText);
  133 + int x = width - textWidth - style.watermarkTextMarginX;
  134 + int y = height - style.watermarkTextMarginY;
  135 + g.drawString(style.watermarkText, x, y);
  136 + }
  137 +
  138 + // 图片水印
  139 + private static void drawImageWatermark(Graphics2D g, int width, int height, StyleConfig style) {
  140 + try {
  141 + String watermarkImagePath = style.watermarkImagePath;
  142 + File file = new File(watermarkImagePath);
  143 + if (!file.exists()) {
  144 + System.out.println("⚠️ 水印图片未找到:" + watermarkImagePath);
  145 + return;
  146 + }
  147 + Image logo = ImageIO.read(file).getScaledInstance(
  148 + style.watermarkImageWidth,
  149 + style.watermarkImageHeight,
  150 + Image.SCALE_SMOOTH
  151 + );
  152 + int x = width - style.watermarkImageWidth - style.watermarkImageMarginX;
  153 + int y = height - style.watermarkImageHeight - style.watermarkImageMarginY;
  154 + g.drawImage(logo, x, y, null);
  155 + } catch (IOException e) {
  156 + System.err.println("❌ 加载图片水印失败:" + e.getMessage());
  157 + }
  158 + }
  159 +}
  160 +
  1 +package com.ruoyi.quartz.util;
  2 +
  3 +import java.awt.*;
  4 +import java.io.File;
  5 +
  6 +/**
  7 + * 样式配置类
  8 + */
  9 +public class StyleConfig {
  10 + public StyleConfig() {
  11 + try {
  12 + Font baseFont = Font.createFont(Font.TRUETYPE_FONT,
  13 + new File("NotoSansCJKsc-Black.otf"));
  14 +
  15 + titleFont = baseFont.deriveFont(Font.BOLD, 36f);
  16 + contentFont = baseFont.deriveFont(Font.PLAIN, 28f);
  17 + watermarkFont = baseFont.deriveFont(Font.PLAIN, 20f);
  18 +
  19 + GraphicsEnvironment.getLocalGraphicsEnvironment().registerFont(baseFont);
  20 + } catch (Exception e) {
  21 + System.err.println("❌ 加载字体失败,使用默认字体:" + e.getMessage());
  22 + titleFont = new Font("Serif", Font.BOLD, 36);
  23 + contentFont = new Font("Serif", Font.PLAIN, 28);
  24 + }
  25 + }
  26 +
  27 + // 文本样式配置
  28 + public Font titleFont = new Font("微软雅黑", Font.BOLD, 36);
  29 +// 标题字体,微软雅黑,加粗,字号36
  30 +
  31 + public Font contentFont = new Font("微软雅黑", Font.PLAIN, 28);
  32 +// 正文字体,微软雅黑,常规,字号28
  33 +
  34 + public Color textColor = Color.WHITE;
  35 +// 文字颜色,默认为白色
  36 +
  37 + // 是否显示遮罩背景块(默认开启)
  38 + public boolean showBackgroundBlock = false;
  39 +
  40 + // 遮罩块样式(文字背景)
  41 + public Color backgroundColor = new Color(0, 0, 0);
  42 +// 遮罩背景颜色,默认黑色(RGB)
  43 +
  44 + public float backgroundAlpha = 0.4f;
  45 +// 遮罩背景透明度(0.0f~1.0f,0是完全透明,1是不透明)
  46 +
  47 + public int cornerRadius = 20;
  48 +// 遮罩背景圆角半径,单位像素
  49 +
  50 + public int padding = 20;
  51 +// 遮罩内部边距:文字距离遮罩边缘的内边距(上下左右均使用该值)
  52 +
  53 + public int blockSpacing = 0;
  54 +// 每个标题+内容之间的垂直间距(块间隔),单位像素
  55 +
  56 + public int startX = 97;
  57 +// 文字区域的起始横坐标(左边距)
  58 +
  59 + public int startY = 245;
  60 +// 第一段文字区域的起始纵坐标(上边距)
  61 +
  62 + public int lineSpacing = 5;
  63 +// 内容段落之间的行间距(单位像素)
  64 +
  65 + // 文字水印配置
  66 + public String watermarkText = "@鱼儿乐科技";
  67 +// 添加的文字水印内容
  68 +
  69 + public Font watermarkFont = new Font("微软雅黑", Font.PLAIN, 20);
  70 +// 水印字体:微软雅黑,常规,字号20
  71 +
  72 + public Color watermarkColor = new Color(255, 255, 255, 180);
  73 +// 水印颜色:白色,透明度约70%(255=不透明,180≈70%透明)
  74 +
  75 + public int watermarkTextMarginX = 567;
  76 +// 文字水印的横坐标偏移量,单位像素(从左上角或右下角偏移)
  77 +
  78 + public int watermarkTextMarginY = 1236;
  79 +// 文字水印的纵坐标偏移量,单位像素(从左上角或右下角偏移)
  80 +
  81 + // 图片水印配置
  82 + public String watermarkImagePath = "logo.jpg";
  83 +// 图片水印的文件路径,支持 PNG/JPG 格式
  84 +
  85 + public int watermarkImageWidth = 100;
  86 +// 图片水印缩放后的宽度(单位像素)
  87 +
  88 + public int watermarkImageHeight = 100;
  89 +// 图片水印缩放后的高度(单位像素)
  90 +
  91 + public int watermarkImageMarginX = 20;
  92 +// 图片水印的横向偏移量(从右下角向内缩进的距离)
  93 +
  94 + public int watermarkImageMarginY = 20;
  95 +// 图片水印的纵向偏移量(从右下角向内缩进的距离)
  96 +
  97 +}
  98 +
1 package com.zhonglai.luhui.admin.controller.monitor; 1 package com.zhonglai.luhui.admin.controller.monitor;
2 2
3 -import cn.hutool.core.bean.BeanUtil;  
4 import cn.hutool.http.HttpUtil; 3 import cn.hutool.http.HttpUtil;
5 import com.alibaba.fastjson.JSONObject; 4 import com.alibaba.fastjson.JSONObject;
6 -import com.google.gson.JsonArray;  
7 import com.google.gson.JsonObject; 5 import com.google.gson.JsonObject;
8 import com.ruoyi.common.core.domain.AjaxResult; 6 import com.ruoyi.common.core.domain.AjaxResult;
9 import com.ruoyi.common.core.page.TableDataInfo; 7 import com.ruoyi.common.core.page.TableDataInfo;
@@ -12,15 +10,17 @@ import com.ruoyi.common.utils.GsonConstructor; @@ -12,15 +10,17 @@ import com.ruoyi.common.utils.GsonConstructor;
12 import com.ruoyi.common.utils.ServletUtils; 10 import com.ruoyi.common.utils.ServletUtils;
13 import com.ruoyi.common.utils.ip.IpUtils; 11 import com.ruoyi.common.utils.ip.IpUtils;
14 import com.ruoyi.framework.web.domain.Server; 12 import com.ruoyi.framework.web.domain.Server;
  13 +import com.ruoyi.quartz.util.MultiTextImageGenerator;
  14 +import com.ruoyi.quartz.util.StyleConfig;
15 import com.ruoyi.system.domain.sys.SysMonitorApplication; 15 import com.ruoyi.system.domain.sys.SysMonitorApplication;
16 import com.ruoyi.system.domain.sys.SysMonitorApplicationLog; 16 import com.ruoyi.system.domain.sys.SysMonitorApplicationLog;
17 import com.ruoyi.system.domain.sys.SysMonitorServer; 17 import com.ruoyi.system.domain.sys.SysMonitorServer;
18 import com.ruoyi.system.domain.sys.SysMonitorServerLog; 18 import com.ruoyi.system.domain.sys.SysMonitorServerLog;
19 import com.zhonglai.luhui.action.BaseController; 19 import com.zhonglai.luhui.action.BaseController;
  20 +import com.zhonglai.luhui.admin.dto.GenerateAquaticPublicOpinionPosterDto;
20 import com.zhonglai.luhui.admin.dto.MonitorServerUploadApplicationDto; 21 import com.zhonglai.luhui.admin.dto.MonitorServerUploadApplicationDto;
21 import com.zhonglai.luhui.admin.dto.MonitorServerUploadDto; 22 import com.zhonglai.luhui.admin.dto.MonitorServerUploadDto;
22 import com.zhonglai.luhui.admin.qywx.AesException; 23 import com.zhonglai.luhui.admin.qywx.AesException;
23 -import com.zhonglai.luhui.admin.qywx.QyWxApplication;  
24 import com.zhonglai.luhui.admin.qywx.WXBizMsgCrypt; 24 import com.zhonglai.luhui.admin.qywx.WXBizMsgCrypt;
25 import com.zhonglai.luhui.admin.service.SendSysMonitorServerMessge; 25 import com.zhonglai.luhui.admin.service.SendSysMonitorServerMessge;
26 import com.zhonglai.luhui.dao.service.PublicService; 26 import com.zhonglai.luhui.dao.service.PublicService;
@@ -28,7 +28,6 @@ import com.zhonglai.luhui.device.analysis.comm.util.StringUtils; @@ -28,7 +28,6 @@ import com.zhonglai.luhui.device.analysis.comm.util.StringUtils;
28 import io.swagger.annotations.Api; 28 import io.swagger.annotations.Api;
29 import io.swagger.annotations.ApiOperation; 29 import io.swagger.annotations.ApiOperation;
30 import org.springframework.beans.factory.annotation.Autowired; 30 import org.springframework.beans.factory.annotation.Autowired;
31 -import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;  
32 import org.springframework.security.access.prepost.PreAuthorize; 31 import org.springframework.security.access.prepost.PreAuthorize;
33 import org.springframework.transaction.annotation.Transactional; 32 import org.springframework.transaction.annotation.Transactional;
34 import org.springframework.util.StreamUtils; 33 import org.springframework.util.StreamUtils;
@@ -44,11 +43,13 @@ import javax.servlet.http.HttpServletRequest; @@ -44,11 +43,13 @@ import javax.servlet.http.HttpServletRequest;
44 import javax.xml.parsers.DocumentBuilder; 43 import javax.xml.parsers.DocumentBuilder;
45 import javax.xml.parsers.DocumentBuilderFactory; 44 import javax.xml.parsers.DocumentBuilderFactory;
46 import javax.xml.parsers.ParserConfigurationException; 45 import javax.xml.parsers.ParserConfigurationException;
  46 +import java.io.File;
47 import java.io.IOException; 47 import java.io.IOException;
48 import java.io.StringReader; 48 import java.io.StringReader;
49 import java.util.*; 49 import java.util.*;
50 import java.util.concurrent.ScheduledExecutorService; 50 import java.util.concurrent.ScheduledExecutorService;
51 import java.util.concurrent.TimeUnit; 51 import java.util.concurrent.TimeUnit;
  52 +import java.util.stream.Collectors;
52 53
53 54
54 /** 55 /**
@@ -176,12 +177,40 @@ public class ServerController extends BaseController @@ -176,12 +177,40 @@ public class ServerController extends BaseController
176 177
177 @ApiOperation("获取当天水产新闻") 178 @ApiOperation("获取当天水产新闻")
178 @GetMapping("/getNowAquaticPublicOpinion") 179 @GetMapping("/getNowAquaticPublicOpinion")
179 - public AjaxResult getNowAquaticPublicOpinion() 180 + public AjaxResult getNowAquaticPublicOpinion(String day)
180 { 181 {
181 - List<Map<String,Object>> lsit = publicService.getObjectListBySQL("SELECT * FROM `fish_aquatic_public_opinion` WHERE release_time='"+DateUtils.getDate()+" 00:00:00'"); 182 + if(StringUtils.isEmpty(day))
  183 + {
  184 + day = DateUtils.getDate();
  185 + }
  186 + List<Map<String,Object>> lsit = publicService.getObjectListBySQL("SELECT * FROM `fish_aquatic_public_opinion` WHERE release_time='"+day+" 00:00:00'");
182 return AjaxResult.success(lsit); 187 return AjaxResult.success(lsit);
183 } 188 }
184 189
  190 + @ApiOperation("生成水产新闻海报")
  191 + @PostMapping("/generateAquaticPublicOpinionPoster")
  192 + public AjaxResult generateAquaticPublicOpinionPoster(@RequestBody List<GenerateAquaticPublicOpinionPosterDto> list)
  193 + {
  194 + if (null == list || list.size()==0)
  195 + {
  196 + return AjaxResult.error("参数不能为空");
  197 + }
  198 + List<AbstractMap.SimpleEntry<String, String>> dataList = list.stream()
  199 + .map(dto -> new AbstractMap.SimpleEntry<>(dto.getTitle(), dto.getContent()))
  200 + .collect(Collectors.toList());
  201 + try {
  202 + logger.info("转换数据:{}",dataList);
  203 + String savePath = MultiTextImageGenerator.generateImage(dataList, new StyleConfig());
  204 + String imgurl = "https://lh.admin.yu2le.com/api/"+savePath.replace("uploadPath","profile");
  205 + return AjaxResult.success(imgurl);
  206 + } catch (IOException e) {
  207 + logger.info(new File("moban.png").getAbsolutePath());
  208 + logger.error("生成海报错误",e);
  209 + return AjaxResult.error("生成海报错误"+e.getMessage());
  210 + }
  211 +
  212 + }
  213 +
185 @ApiOperation("获取服务器应用列表") 214 @ApiOperation("获取服务器应用列表")
186 @GetMapping("/getServiceAoolicationList") 215 @GetMapping("/getServiceAoolicationList")
187 public Map<String,Object> getServiceAoolicationList() 216 public Map<String,Object> getServiceAoolicationList()
  1 +package com.zhonglai.luhui.admin.dto;
  2 +
  3 +/**
  4 + * 生成水产新闻海报对象
  5 + */
  6 +public class GenerateAquaticPublicOpinionPosterDto {
  7 + private String title;
  8 + private String content;
  9 +
  10 + public String getTitle() {
  11 + return title;
  12 + }
  13 +
  14 + public void setTitle(String title) {
  15 + this.title = title;
  16 + }
  17 +
  18 + public String getContent() {
  19 + return content;
  20 + }
  21 +
  22 + public void setContent(String content) {
  23 + this.content = content;
  24 + }
  25 +}
1 -# 项目相关配置 jhlt: # 名称 name: zhonglai # 版本 version: 3.8.2 # 版权年份 copyrightYear: 2022 # 实例演示开关 demoEnabled: true # 文件路径 示例( Windows配置D:/ruoyi/uploadPath,Linux配置 /home/ruoyi/uploadPath) profile: E:/work/idea/Luhui/uploadPath # 获取ip地址开关 addressEnabled: false # 验证码类型 math 数组计算 char 字符验证 captchaType: math # 开发环境配置 server: # 服务器的HTTP端口,默认为8080 port: 8080 servlet: # 应用的访问路径 context-path: / tomcat: # tomcat的URI编码 uri-encoding: UTF-8 # 连接数满后的排队数,默认为100 accept-count: 1000 threads: # tomcat最大线程数,默认为200 max: 800 # Tomcat启动初始化的线程数,默认值10 min-spare: 100 # 日志配置 logging: level: com.ruoyi: debug org.springframework: warn com.zhonglai.luhui: debug # Spring配置 spring: # 资源信息 messages: # 国际化资源文件路径 basename: i18n/messages profiles: active: druid # 文件上传 servlet: multipart: # 单个文件大小 max-file-size: 10MB # 设置总上传的文件大小 max-request-size: 20MB # 服务模块 devtools: restart: # 热部署开关 enabled: true # redis 配置 redis: # 地址 host: 119.23.218.181 # 端口,默认为6379 port: 6379 # 数据库索引 database: 1 # 密码 password: # 连接超时时间 timeout: 10s lettuce: pool: # 连接池中的最小空闲连接 min-idle: 0 # 连接池中的最大空闲连接 max-idle: 8 # 连接池的最大数据库连接数 max-active: 8 # #连接池最大阻塞等待时间(使用负值表示没有限制) max-wait: -1ms # token配置 token: # 令牌自定义标识 header: Authorization # 令牌密钥 secret: abcdefghijklmnopqrstuvwxyz # 令牌有效期(默认30分钟) expireTime: 1440 rediskey: lh-admin # MyBatis配置 mybatis: # 搜索指定包别名 typeAliasesPackage: com.ruoyi.**.domain,com.zhonglai.**.domain # 配置mapper的扫描,找到所有的mapper.xml映射文件 mapperLocations: classpath*:mapper/**/*Mapper.xml # 加载全局的配置文件 configLocation: classpath:mybatis/mybatis-config.xml # PageHelper分页插件 pagehelper: helperDialect: mysql supportMethodsArguments: true params: count=countSql # Swagger配置 swagger: # 是否开启swagger enabled: true # 请求前缀 pathMapping: /dev-api # 防止XSS攻击 xss: # 过滤开关 enabled: true # 排除链接(多个用逗号分隔) excludes: /system/notice # 匹配链接 urlPatterns: /system/*,/monitor/*,/tool/* mqtt: client: device_life: 180 sys: ## // 对于登录login 注册register 验证码captchaImage 允许匿名访问 antMatchers: /login,/register,/captchaImage,/getCacheObject,/v2/api-docs,/tool/gen/generatorCodeFromDb,/data/**,/monitor/server/upload,/monitor/server/getSysMonitorServerList,/monitor/server/getSysMonitorServerLogList # NameServer地址 rocketmq: name-server: 8.129.224.117:9876 # 默认的消息组 producer: group: deviceCommand send-message-timeout: 30000 send-topic: lh-mqtt-service-deviceCommand-test send-tags: 1  
  1 +# 项目相关配置 jhlt: # 名称 name: zhonglai # 版本 version: 3.8.2 # 版权年份 copyrightYear: 2022 # 实例演示开关 demoEnabled: true # 文件路径 示例( Windows配置D:/ruoyi/uploadPath,Linux配置 /home/ruoyi/uploadPath) profile: E:/work/idea/Luhui/uploadPath # 获取ip地址开关 addressEnabled: false # 验证码类型 math 数组计算 char 字符验证 captchaType: math # 开发环境配置 server: # 服务器的HTTP端口,默认为8080 port: 8080 servlet: # 应用的访问路径 context-path: / tomcat: # tomcat的URI编码 uri-encoding: UTF-8 # 连接数满后的排队数,默认为100 accept-count: 1000 threads: # tomcat最大线程数,默认为200 max: 800 # Tomcat启动初始化的线程数,默认值10 min-spare: 100 # 日志配置 logging: level: com.ruoyi: debug org.springframework: warn com.zhonglai.luhui: debug # Spring配置 spring: # 资源信息 messages: # 国际化资源文件路径 basename: i18n/messages profiles: active: druid # 文件上传 servlet: multipart: # 单个文件大小 max-file-size: 10MB # 设置总上传的文件大小 max-request-size: 20MB # 服务模块 devtools: restart: # 热部署开关 enabled: true # redis 配置 redis: # 地址 host: 119.23.218.181 # 端口,默认为6379 port: 6379 # 数据库索引 database: 1 # 密码 password: # 连接超时时间 timeout: 10s lettuce: pool: # 连接池中的最小空闲连接 min-idle: 0 # 连接池中的最大空闲连接 max-idle: 8 # 连接池的最大数据库连接数 max-active: 8 # #连接池最大阻塞等待时间(使用负值表示没有限制) max-wait: -1ms # token配置 token: # 令牌自定义标识 header: Authorization # 令牌密钥 secret: abcdefghijklmnopqrstuvwxyz # 令牌有效期(默认30分钟) expireTime: 1440 rediskey: lh-admin # MyBatis配置 mybatis: # 搜索指定包别名 typeAliasesPackage: com.ruoyi.**.domain,com.zhonglai.**.domain # 配置mapper的扫描,找到所有的mapper.xml映射文件 mapperLocations: classpath*:mapper/**/*Mapper.xml # 加载全局的配置文件 configLocation: classpath:mybatis/mybatis-config.xml # PageHelper分页插件 pagehelper: helperDialect: mysql supportMethodsArguments: true params: count=countSql # Swagger配置 swagger: # 是否开启swagger enabled: true # 请求前缀 pathMapping: /dev-api # 防止XSS攻击 xss: # 过滤开关 enabled: true # 排除链接(多个用逗号分隔) excludes: /system/notice # 匹配链接 urlPatterns: /system/*,/monitor/*,/tool/* mqtt: client: device_life: 180 sys: ## // 对于登录login 注册register 验证码captchaImage 允许匿名访问 antMatchers: /login,/register,/captchaImage,/getCacheObject,/v2/api-docs,/tool/gen/generatorCodeFromDb,/data/**,/monitor/server/upload,/monitor/server/getSysMonitorServerList,/monitor/server/getSysMonitorServerLogList,/monitor/server/getNowAquaticPublicOpinion # NameServer地址 rocketmq: name-server: 8.129.224.117:9876 # 默认的消息组 producer: group: deviceCommand send-message-timeout: 30000 send-topic: lh-mqtt-service-deviceCommand-test send-tags: 1
@@ -57,9 +57,7 @@ public class IotTerminalController extends BaseController @@ -57,9 +57,7 @@ public class IotTerminalController extends BaseController
57 @GetMapping("/listByDeviceId/{deviceId}") 57 @GetMapping("/listByDeviceId/{deviceId}")
58 public AjaxResult listByDeviceId(@PathVariable String deviceId) 58 public AjaxResult listByDeviceId(@PathVariable String deviceId)
59 { 59 {
60 - IotTerminal iotTerminal = new IotTerminal();  
61 - iotTerminal.setDevice_id(deviceId);  
62 - List<IotTerminal> list = iotTerminalService.selectIotTerminalListByUserId(iotTerminal); 60 + List<IotTerminal> list = iotTerminalService.selectNotUserIotTerminalListByImei(deviceId);
63 return AjaxResult.success(list); 61 return AjaxResult.success(list);
64 } 62 }
65 63