Browse Source

代码提交 用于图片水印

cxd 6 months ago
parent
commit
26f0241c90

+ 1 - 0
gqy-admin/src/main/java/com/gqy/web/controller/document/DcSpecController.java

@@ -81,4 +81,5 @@ public class DcSpecController  extends BaseController {
 
 
 
+
 }

+ 193 - 0
gqy-admin/src/main/java/com/gqy/web/controller/document/ImageController.java

@@ -0,0 +1,193 @@
+package com.gqy.web.controller.document;
+
+import com.gqy.common.core.domain.AjaxResult;
+import com.gqy.common.utils.image.WatermarkUtils;
+import com.gqy.document.domain.DcProduct;
+import com.gqy.document.mapper.DcProductMapper;
+import com.gqy.document.service.IDcProductService;
+import com.gqy.document.service.impl.ProductServiceImpl;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.core.io.Resource;
+import org.springframework.core.io.ResourceLoader;
+import org.springframework.web.bind.annotation.*;
+import org.springframework.web.multipart.MultipartFile;
+
+import javax.imageio.ImageIO;
+import java.awt.*;
+import java.awt.image.BufferedImage;
+import java.io.*;
+import java.net.InetAddress;
+import java.net.UnknownHostException;
+import java.time.LocalDateTime;
+import java.time.format.DateTimeFormatter;
+import java.util.UUID;
+
+/**
+ * 图片处理控制器
+ *
+ * @author gqy
+ */
+@RestController
+@RequestMapping("/document/image")
+public class ImageController {
+
+    private static final Logger log = LoggerFactory.getLogger(ImageController.class);
+
+    @Autowired
+    private ResourceLoader resourceLoader;
+
+    @Value("${server.port}")
+    private String serverPort;
+
+
+    @Autowired
+    private IDcProductService iDcProductService;
+
+    /**
+     * 静态资源相关配置
+     */
+    private static final String WATERMARK_DIR = "watermark";
+    private static final String STATIC_URL_PREFIX = "/static"; // 静态资源访问前缀
+
+    /**
+     * 获取服务器IP地址
+     */
+    private String getServerIp() {
+        try {
+            InetAddress address = InetAddress.getLocalHost();
+            return address.getHostAddress();
+        } catch (UnknownHostException e) {
+            log.error("获取服务器IP失败", e);
+            return "localhost";
+        }
+    }
+
+    /**
+     * 添加文字水印(保存到静态资源目录)
+     *
+     * @param file 要添加水印的原图片文件
+     * @return AjaxResult 处理结果,包含访问URL和文件名
+     */
+    @PostMapping("/watermark")
+    public AjaxResult addWatermarkToStatic(
+            @RequestParam("file") MultipartFile file,
+            @RequestParam("isShow") String isShow,
+            @RequestParam("productId") Long productId
+    ) {
+
+        System.out.println("==========addWatermarkToStatic===start=====");
+
+
+        DcProduct dcProduct = iDcProductService.selectDcProductById(productId);
+        String dcpName = dcProduct.getDcp_name();
+        BufferedImage sourceImage = null;
+        InputStream inputStream = null;
+        try {
+            inputStream = file.getInputStream();
+            // 读取原图片
+            sourceImage = ImageIO.read(inputStream);
+            if (sourceImage == null) {
+                return AjaxResult.error("无效的图片文件");
+            }
+
+            // 设置水印字体
+            Font font = new Font("微软雅黑", Font.BOLD, 30);
+
+            // 获取项目根目录
+            String projectPath = System.getProperty("user.dir");
+            // 构建static目录路径
+            String staticPath = projectPath + File.separator + "gqy-admin" + File.separator + "src" +
+                              File.separator + "main" + File.separator + "resources" +
+                              File.separator + "static";
+
+            // 构建水印目录
+            File watermarkDir = new File(staticPath, WATERMARK_DIR);
+            if (!watermarkDir.exists()) {
+                if (!watermarkDir.mkdirs()) {
+                    log.error("Failed to create directory: {}", watermarkDir.getAbsolutePath());
+                    return AjaxResult.error("创建水印目录失败");
+                }
+            }
+
+            // 生成文件名
+            String fileName = generateFileName(file.getOriginalFilename());
+
+            // 构建完整的保存路径
+            File saveFile = new File(watermarkDir, fileName);
+
+            // 添加水印
+            WatermarkUtils.WatermarkResult result = WatermarkUtils.addTextWatermarkAndSave(
+                sourceImage,
+                "水印内容为仅供",
+                font,
+                Color.WHITE,
+                0.5f,
+                4,
+                null,
+                saveFile.getAbsolutePath()
+            );
+
+            if (result.isSuccess()) {
+                // 构建完整的访问URL,包含IP和端口
+                String serverIp = getServerIp();
+                String url = String.format("http://%s:%s%s/%s/%s",
+                    serverIp,
+                    serverPort,
+                    STATIC_URL_PREFIX,
+                    WATERMARK_DIR,
+                    fileName);
+
+                log.info("文件访问URL: {}", url);
+                return AjaxResult.success()
+                    .put("url", url)
+                    .put("fileName", fileName);
+            } else {
+                return AjaxResult.error("添加水印失败:" + result.getErrorMessage());
+            }
+
+        } catch (Exception e) {
+            log.error("处理水印图片失败", e);
+            return AjaxResult.error("处理失败:" + e.getMessage());
+        } finally {
+            // 关闭资源
+            if (inputStream != null) {
+                try {
+                    inputStream.close();
+                } catch (IOException e) {
+                    log.error("关闭输入流失败", e);
+                }
+            }
+            // 清理临时文件
+            try {
+                if (file instanceof org.apache.catalina.core.ApplicationPart) {
+                    ((org.apache.catalina.core.ApplicationPart) file).delete();
+                }
+            } catch (Exception e) {
+                log.warn("清理临时文件失败", e);
+            }
+        }
+    }
+
+    /**
+     * 生成唯一文件名
+     * 格式:yyyyMMddHHmmss_随机串.扩展名
+     */
+    private String generateFileName(String originalFilename) {
+        String timestamp = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyyMMddHHmmss"));
+        String random = UUID.randomUUID().toString().substring(0, 8);
+        String extension = getFileExtension(originalFilename);
+
+        return timestamp + "_" + random + "." + extension;
+    }
+
+    /**
+     * 获取文件扩展名
+     */
+    private String getFileExtension(String fileName) {
+        int dotIndex = fileName.lastIndexOf('.');
+        return (dotIndex == -1) ? "png" : fileName.substring(dotIndex + 1);
+    }
+}

+ 10 - 0
gqy-admin/src/main/java/com/gqy/web/controller/document/ProductController.java

@@ -54,6 +54,16 @@ public class ProductController extends BaseController {
     }
 
 
+    /**
+     * 导入JSON
+     * @param context
+     * @return
+     */
+    @PostMapping("/export/json")
+    public AjaxResultCQY exportJSON(String context) {
+        return AjaxResultCQY.success(iDcProductService.exportJSON(context));
+    }
+
 
     /**
      * 添加产品

+ 22 - 6
gqy-common/src/main/java/com/gqy/common/utils/html/EscapeUtil.java

@@ -1,7 +1,16 @@
 package com.gqy.common.utils.html;
 
+import com.fasterxml.jackson.core.JsonProcessingException;
+import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.ObjectMapper;
 import com.gqy.common.utils.StringUtils;
 
+import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.ObjectMapper;
+
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
 /**
  * 转义和反转义工具类
  *
@@ -153,11 +162,18 @@ public class EscapeUtil
         return tmp.toString();
     }
 
-    public static void main(String[] args)
-    {
-        int a =-1;
-        int b = -1;
-        int c = b+a;
-        System.out.println("=========c="+c);
+    public static void main(String[] args) throws JsonProcessingException {
+        String input = "DDW{ 型号:DDW-60EF, 箱体{ 类型:反射, 材质:铁, 尺寸{宽:1328,高:747,厚:850} }, 屏幕{ 型号:CSP - P, 屏幕比例:16:9, 屏幕尺寸:60 }, 投影机{ 光源:LED3X4, 分辨率{\"W\":1920,\"H\":1080}, 亮度:1200, 控制盒:单电源 } }";
+        // 去除多余的空格等非JSON标准字符,进行简单格式化使其更接近JSON格式
+        input = input.replaceAll(" ", "")
+                .replaceAll(":", ":\"")
+                .replaceAll("}", "\"}")
+                .replaceAll("\\{", "{\"")
+                .replaceAll(",", "\",\"")
+                .replaceAll("DDW", "{\"DDW\"")
+                .replaceAll("CSP-P", "\"CSP-P\"")
+                .replaceAll("LED3X4", "\"LED3X4\"")
+                .replaceAll("单电源", "\"单电源\"") + "}";
+        System.out.println(input);
     }
 }

+ 496 - 0
gqy-common/src/main/java/com/gqy/common/utils/image/WatermarkUtils.java

@@ -0,0 +1,496 @@
+package com.gqy.common.utils.image;
+
+import javax.imageio.ImageIO;
+import java.awt.*;
+import java.awt.geom.AffineTransform;
+import java.awt.image.BufferedImage;
+import java.io.File;
+import java.io.IOException;
+import java.util.Base64;
+
+import java.io.ByteArrayOutputStream;
+
+/**
+ * 图片水印工具类
+ */
+public class WatermarkUtils {
+
+    /**
+     * 默认参数值
+     */
+    private static final int DEFAULT_MARGIN = 20;
+    private static final int DEFAULT_SPACING = 5;
+    private static final float DEFAULT_ALPHA = 0.3f;
+    private static final int DEFAULT_FONT_SIZE = 30;
+    private static final int DEFAULT_POSITION = 4; // 右下角
+    private static final int DEFAULT_DEGREE = -30; // 默认旋转角度
+
+    /**
+     * 添加文字水印并返回Base64
+     *
+     * @param srcImage 源图片
+     * @param text 水印文字
+     * @param font 字体
+     * @param color 水印颜色
+     * @param alpha 透明度(0.0 ~ 1.0f)
+     * @param position 水印位置 (1:左上 2:右上 3:左下 4:右下 5:居中)
+     * @param degree 旋转角度
+     * @return Base64字符串
+     */
+    public static String addTextWatermark(BufferedImage srcImage, String text, Font font, Color color, float alpha, int position, Integer degree) {
+        try {
+            // 使用默认的 margin, spacing 和 repeat 值调用完整版本
+            BufferedImage watermarkedImage = addTextWatermarkToImage(
+                srcImage, text, font, color, alpha, position, degree
+            );
+            return convertToBase64(watermarkedImage);
+        } catch (Exception e) {
+            e.printStackTrace();
+            return null;
+        }
+    }
+
+    /**
+     * 添加文字水印并返回Base64(完整参数版本)
+     */
+    public static String addTextWatermark(
+            BufferedImage srcImage, 
+            String text, 
+            Font font, 
+            Color color, 
+            float alpha, 
+            int position, 
+            Integer degree,
+            int margin,
+            int spacing,
+            boolean repeat) {
+        try {
+            BufferedImage watermarkedImage = addTextWatermarkToImage(
+                srcImage, text, font, color, alpha, position, degree, 
+                margin, spacing, repeat
+            );
+            return convertToBase64(watermarkedImage);
+        } catch (Exception e) {
+            e.printStackTrace();
+            return null;
+        }
+    }
+
+    /**
+     * 添加图片水印并返回Base64
+     *
+     * @param srcImage 源图片
+     * @param watermarkImage 水印图片
+     * @param position 水印位置 (1:左上 2:右上 3:左下 4:右下 5:居中)
+     * @param alpha 透明度(0.0 ~ 1.0f)
+     * @return Base64字符串
+     */
+    public static String addImageWatermark(BufferedImage srcImage, BufferedImage watermarkImage, int position, float alpha) {
+        try {
+            BufferedImage watermarkedImage = addImageWatermarkToImage(srcImage, watermarkImage, position, alpha);
+            return convertToBase64(watermarkedImage);
+        } catch (Exception e) {
+            e.printStackTrace();
+            return null;
+        }
+    }
+
+    /**
+     * 将BufferedImage转换为Base64字符串
+     */
+    private static String convertToBase64(BufferedImage image) throws IOException {
+        ByteArrayOutputStream baos = new ByteArrayOutputStream();
+        ImageIO.write(image, "png", baos);
+        byte[] bytes = baos.toByteArray();
+        baos.close();
+        return "data:image/png;base64," + Base64.getEncoder().encodeToString(bytes);
+    }
+
+    /**
+     * 绘制文本块
+     */
+    private static void drawTextBlock(Graphics2D g2d, String[] lines, int x, int y,
+            int lineHeight, Integer degree, FontMetrics fontMetrics) {
+        // 保存当前变换状态
+        AffineTransform originalTransform = g2d.getTransform();
+
+        // 计算文本块的整体宽度和高度
+        int blockWidth = 0;
+        int blockHeight = lineHeight * lines.length;
+        for (String line : lines) {
+            blockWidth = Math.max(blockWidth, fontMetrics.stringWidth(line));
+        }
+
+        // 计算旋转中心点
+        int centerX = x + blockWidth / 2;
+        int centerY = y + blockHeight / 2;
+
+        if (degree != null) {
+            // 先平移到旋转中心
+            g2d.translate(centerX, centerY);
+            // 执行旋转
+            g2d.rotate(Math.toRadians(degree));
+            // 平移回原点,考虑文本块的尺寸
+            g2d.translate(-blockWidth / 2, -blockHeight / 2);
+
+            // 绘制文本
+            int currentY = fontMetrics.getAscent();
+            for (String line : lines) {
+                int lineWidth = fontMetrics.stringWidth(line);
+                // 居中对齐每一行
+                int lineX = (blockWidth - lineWidth) / 2;
+                g2d.drawString(line, lineX, currentY);
+                currentY += lineHeight;
+            }
+        } else {
+            // 不旋转时直接绘制
+            int currentY = y;
+            for (String line : lines) {
+                g2d.drawString(line, x, currentY);
+                currentY += lineHeight;
+            }
+        }
+
+        // 恢复变换状态
+        g2d.setTransform(originalTransform);
+    }
+
+    /**
+     * 添加文字水印到图片
+     */
+    private static BufferedImage addTextWatermarkToImage(
+            BufferedImage srcImage, String text, Font font, Color color,
+            float alpha, int position, Integer degree) {
+        // 使用默认值调用完整版本
+        return addTextWatermarkToImage(
+            srcImage, text, font, color, alpha, position, degree,
+            DEFAULT_MARGIN, DEFAULT_SPACING, true);
+    }
+
+    /**
+     * 添加文字水印到图片(完整参数版本)
+     */
+    private static BufferedImage addTextWatermarkToImage(
+            BufferedImage srcImage, String text, Font font, Color color,
+            float alpha, int position, Integer degree,
+            int margin, int spacing, boolean repeat) {
+        int width = srcImage.getWidth();
+        int height = srcImage.getHeight();
+
+        BufferedImage bufferedImage = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
+        Graphics2D g2d = bufferedImage.createGraphics();
+
+        // 设置渲染质量
+        g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
+        g2d.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
+        g2d.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY);
+
+        // 绘制原图
+        g2d.drawImage(srcImage, 0, 0, width, height, null);
+
+        // 设置水印文字透明度
+        g2d.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, alpha));
+
+        // 设置水印文字颜色和字体
+        g2d.setColor(color);
+        g2d.setFont(font);
+
+        // 处理多行文字
+        String[] lines = text.split("\n");
+        FontMetrics fontMetrics = g2d.getFontMetrics(font);
+        int lineHeight = fontMetrics.getHeight() + spacing;
+
+        // 计算文本整体尺寸
+        int totalTextHeight = lineHeight * lines.length - spacing;
+        int maxTextWidth = 0;
+        for (String line : lines) {
+            maxTextWidth = Math.max(maxTextWidth, fontMetrics.stringWidth(line));
+        }
+
+        // 如果有旋转,调整文本块尺寸
+        double rotationRad = degree != null ? Math.toRadians(degree) : 0;
+        int rotatedWidth = (int) Math.abs(maxTextWidth * Math.cos(rotationRad) +
+                totalTextHeight * Math.sin(rotationRad));
+        int rotatedHeight = (int) Math.abs(maxTextWidth * Math.sin(rotationRad) +
+                totalTextHeight * Math.cos(rotationRad));
+
+        // 计算初始位置,考虑旋转后的尺寸
+        int startX = 0;
+        int startY = 0;
+        switch (position) {
+            case 1: // 左上
+                startX = margin + rotatedWidth/2;
+                startY = margin + rotatedHeight/2;
+                break;
+            case 2: // 右上
+                startX = width - rotatedWidth/2 - margin;
+                startY = margin + rotatedHeight/2;
+                break;
+            case 3: // 左下
+                startX = margin + rotatedWidth/2;
+                startY = height - rotatedHeight/2 - margin;
+                break;
+            case 4: // 右下
+                startX = width - rotatedWidth/2 - margin;
+                startY = height - rotatedHeight/2 - margin;
+                break;
+            case 5: // 居中
+                startX = width / 2;
+                startY = height / 2;
+                break;
+            default:
+                startX = margin + rotatedWidth/2;
+                startY = height - rotatedHeight/2 - margin;
+        }
+
+        if (repeat) {
+            // 计算平铺间距,考虑旋转后的尺寸和边距
+            int xStep = (int)(rotatedWidth * 1.5); // 增加水平间距
+            int yStep = (int)(rotatedHeight * 1.5); // 增加垂直间距
+
+            // 计算起始偏移,确保覆盖边缘
+            int startOffsetX = -xStep;
+            int startOffsetY = -yStep;
+
+            // 计算结束位置,确保覆盖整个图片
+            int endX = width + xStep;
+            int endY = height + yStep;
+
+            // 根据旋转角度调整起始位置,确保完整覆盖
+            if (degree != null) {
+                // 扩展覆盖范围
+                startOffsetX -= rotatedWidth;
+                startOffsetY -= rotatedHeight;
+                endX += rotatedWidth;
+                endY += rotatedHeight;
+            }
+
+            // 绘制水印网格
+            for (int y = startOffsetY; y < endY; y += yStep) {
+                for (int x = startOffsetX; x < endX; x += xStep) {
+                    // 交错排列,使水印分布更均匀
+                    int offsetX = (y / yStep % 2 == 0) ? 0 : xStep / 2;
+                    drawTextBlock(g2d, lines, x + offsetX, y, lineHeight, degree, fontMetrics);
+                }
+            }
+        } else {
+            // 单个水印
+            drawTextBlock(g2d, lines, startX - maxTextWidth/2, startY - totalTextHeight/2,
+                    lineHeight, degree, fontMetrics);
+        }
+
+        g2d.dispose();
+        return bufferedImage;
+    }
+
+    /**
+     * 添加图片水印到图片
+     */
+    private static BufferedImage addImageWatermarkToImage(BufferedImage srcImage, BufferedImage watermarkImage, int position, float alpha) {
+        int width = srcImage.getWidth();
+        int height = srcImage.getHeight();
+        int watermarkWidth = watermarkImage.getWidth();
+        int watermarkHeight = watermarkImage.getHeight();
+
+        BufferedImage bufferedImage = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
+        Graphics2D g2d = bufferedImage.createGraphics();
+
+        // 设置渲染质量
+        g2d.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR);
+        g2d.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY);
+        g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
+
+        // 绘制原图
+        g2d.drawImage(srcImage, 0, 0, width, height, null);
+
+        // 设置水印图片透明度
+        g2d.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, alpha));
+
+        // 计算水印位置
+        int x = 0;
+        int y = 0;
+        switch (position) {
+            case 1: // 左上
+                x = 10;
+                y = 10;
+                break;
+            case 2: // 右上
+                x = width - watermarkWidth - 10;
+                y = 10;
+                break;
+            case 3: // 左下
+                x = 10;
+                y = height - watermarkHeight - 10;
+                break;
+            case 4: // 右下
+                x = width - watermarkWidth - 10;
+                y = height - watermarkHeight - 10;
+                break;
+            case 5: // 居中
+                x = (width - watermarkWidth) / 2;
+                y = (height - watermarkHeight) / 2;
+                break;
+            default:
+                x = 10;
+                y = height - watermarkHeight - 10;
+        }
+
+        // 绘制水印图片
+        g2d.drawImage(watermarkImage, x, y, watermarkWidth, watermarkHeight, null);
+        g2d.dispose();
+
+        return bufferedImage;
+    }
+
+    /**
+     * 添加文字水印并同时保存文件和返回Base64
+     *
+     * @param srcImage 源图片
+     * @param text 水印文字
+     * @param font 字体
+     * @param color 水印颜色
+     * @param alpha 透明度(0.0 ~ 1.0f)
+     * @param position 水印位置 (1:左上 2:右上 3:左下 4:右下 5:居中)
+     * @param degree 旋转角度
+     * @param outputPath 输出文件路径
+     * @return WatermarkResult 包含处理结果的对象
+     */
+    public static WatermarkResult addTextWatermarkAndSave(BufferedImage srcImage, String text, Font font,
+            Color color, float alpha, int position, Integer degree, String outputPath) {
+        WatermarkResult result = new WatermarkResult();
+        try {
+            // 添加水印
+            BufferedImage watermarkedImage = addTextWatermarkToImage(srcImage, text, font, color, alpha, position, degree);
+
+            // 保存文件并转换Base64
+            saveImageAndToBase64(watermarkedImage, outputPath, result);
+
+            return result;
+        } catch (Exception e) {
+            result.setSuccess(false);
+            result.setErrorMessage("添加水印失败:" + e.getMessage());
+            return result;
+        }
+    }
+
+    /**
+     * 添加图片水印并同时保存文件和返回Base64
+     */
+    public static WatermarkResult addImageWatermarkAndSave(BufferedImage srcImage, BufferedImage watermarkImage,
+            int position, float alpha, String outputPath) {
+        WatermarkResult result = new WatermarkResult();
+        try {
+            // 添加水印
+            BufferedImage watermarkedImage = addImageWatermarkToImage(srcImage, watermarkImage, position, alpha);
+
+            // 保存文件并转换Base64
+            saveImageAndToBase64(watermarkedImage, outputPath, result);
+
+            return result;
+        } catch (Exception e) {
+            result.setSuccess(false);
+            result.setErrorMessage("添加水印失败:" + e.getMessage());
+            return result;
+        }
+    }
+
+    /**
+     * 保存图片并转换为Base64
+     */
+    private static void saveImageAndToBase64(BufferedImage image, String outputPath, WatermarkResult result) throws IOException {
+        // 确保输出目录存在
+        File outputFile = new File(outputPath);
+        outputFile.getParentFile().mkdirs();
+
+        // 保存图片
+        ImageIO.write(image, "png", outputFile);
+        result.setSavedPath(outputPath);
+
+        // 转换为Base64
+        ByteArrayOutputStream baos = new ByteArrayOutputStream();
+        ImageIO.write(image, "png", baos);
+        String base64 = "data:image/png;base64," + Base64.getEncoder().encodeToString(baos.toByteArray());
+        result.setBase64(base64);
+        baos.close();
+
+        result.setSuccess(true);
+    }
+
+    /**
+     * 处理结果类
+     */
+    public static class WatermarkResult {
+        private String base64;
+        private String savedPath;
+        private boolean success;
+        private String errorMessage;
+
+        public WatermarkResult() {
+            this.success = true;
+        }
+
+        // Getters and Setters
+        public String getBase64() { return base64; }
+        public void setBase64(String base64) { this.base64 = base64; }
+        public String getSavedPath() { return savedPath; }
+        public void setSavedPath(String savedPath) { this.savedPath = savedPath; }
+        public boolean isSuccess() { return success; }
+        public void setSuccess(boolean success) { this.success = success; }
+        public String getErrorMessage() { return errorMessage; }
+        public void setErrorMessage(String errorMessage) {
+            this.errorMessage = errorMessage;
+            this.success = false;
+        }
+    }
+
+    /**
+     * 使用示例
+     */
+    public static void main(String[] args) {
+        try {
+            // 读取原图
+            BufferedImage sourceImage = ImageIO.read(new File("source.jpg"));
+
+            // 添加文字水印
+            Font font = new Font("微软雅黑", Font.BOLD, 30);
+            WatermarkResult textResult = addTextWatermarkAndSave(
+                sourceImage,
+                "测试水印",
+                font,
+                Color.WHITE,
+                0.5f,
+                4,
+                45,
+                "D:/watermark/output/text_watermark.png"
+            );
+
+            if (textResult.isSuccess()) {
+                System.out.println("文字水印已保存到: " + textResult.getSavedPath());
+                System.out.println("文字水印Base64: " + textResult.getBase64());
+            } else {
+                System.out.println("文字水印添加失败: " + textResult.getErrorMessage());
+            }
+
+            // 添加图片水印
+            BufferedImage watermarkImage = ImageIO.read(new File("watermark.png"));
+            WatermarkResult imageResult = addImageWatermarkAndSave(
+                sourceImage,
+                watermarkImage,
+                4,
+                0.5f,
+                "D:/watermark/output/image_watermark.png"
+            );
+
+            if (imageResult.isSuccess()) {
+                System.out.println("图片水印已保存到: " + imageResult.getSavedPath());
+                System.out.println("图片水印Base64: " + imageResult.getBase64());
+            } else {
+                System.out.println("图片水印添加失败: " + imageResult.getErrorMessage());
+            }
+
+        } catch (IOException e) {
+            e.printStackTrace();
+        }
+    }
+
+}

+ 8 - 2
gqy-framework/src/main/java/com/gqy/framework/config/ResourcesConfig.java

@@ -17,7 +17,7 @@ import com.gqy.framework.interceptor.RepeatSubmitInterceptor;
 
 /**
  * 通用配置
- * 
+ *
  * @author raycos
  */
 @Configuration
@@ -29,6 +29,12 @@ public class ResourcesConfig implements WebMvcConfigurer
     @Override
     public void addResourceHandlers(ResourceHandlerRegistry registry)
     {
+
+        /** 本地文件上传路径 */
+        registry.addResourceHandler("/static/watermark/**")
+                .addResourceLocations("file:" + System.getProperty("user.dir") + "/gqy-admin/src/main/resources/static/watermark/");
+
+
         /** 本地文件上传路径 */
         registry.addResourceHandler(Constants.RESOURCE_PREFIX + "/**")
                 .addResourceLocations("file:" + RuoYiConfig.getProfile() + "/");
@@ -70,4 +76,4 @@ public class ResourcesConfig implements WebMvcConfigurer
         // 返回新的CorsFilter
         return new CorsFilter(source);
     }
-}
+}

+ 4 - 4
gqy-framework/src/main/java/com/gqy/framework/config/SecurityConfig.java

@@ -23,7 +23,7 @@ import com.gqy.framework.security.handle.LogoutSuccessHandlerImpl;
 
 /**
  * spring security配置
- * 
+ *
  * @author raycos
  */
 @EnableMethodSecurity(prePostEnabled = true, securedEnabled = true)
@@ -35,7 +35,7 @@ public class SecurityConfig
      */
     @Autowired
     private UserDetailsService userDetailsService;
-    
+
     /**
      * 认证失败处理类
      */
@@ -53,7 +53,7 @@ public class SecurityConfig
      */
     @Autowired
     private JwtAuthenticationTokenFilter authenticationTokenFilter;
-    
+
     /**
      * 跨域过滤器
      */
@@ -114,7 +114,7 @@ public class SecurityConfig
                 requests.antMatchers("/login", "/register", "/captchaImage").permitAll()
                     // 静态资源,可匿名访问
                     .antMatchers(HttpMethod.GET, "/", "/*.html", "/**/*.html", "/**/*.css", "/**/*.js", "/profile/**").permitAll()
-                    .antMatchers("/swagger-ui.html", "/swagger-resources/**", "/webjars/**", "/*/api-docs", "/druid/**").permitAll()
+                    .antMatchers("/swagger-ui.html", "/swagger-resources/**", "/webjars/**", "/*/api-docs", "/druid/**","/document/image/**","/static/**").permitAll()
                     // 除上面外的所有请求全部需要鉴权认证
                     .anyRequest().authenticated();
             })

+ 5 - 1
gqy-system/src/main/java/com/gqy/document/service/IDcProductService.java

@@ -55,6 +55,10 @@ public interface IDcProductService {
      */
     public DcProduct selectDcProductById(Long dcpId);
 
-
+    /**
+     * 导入产品信息
+     * @return
+     */
+    public int exportJSON(String context);
 
 }

+ 35 - 0
gqy-system/src/main/java/com/gqy/document/service/impl/DcProductServiceImpl.java

@@ -1,5 +1,8 @@
 package com.gqy.document.service.impl;
 
+import com.alibaba.fastjson2.JSON;
+import com.alibaba.fastjson2.JSONObject;
+import com.gqy.common.utils.CustomJsonParser;
 import com.gqy.common.utils.bean.BeanUtils;
 import com.gqy.document.domain.*;
 import com.gqy.document.mapper.DcProductMapper;
@@ -41,6 +44,16 @@ public class DcProductServiceImpl implements IDcProductService {
     private DcPsParamMapper dcPsParamMapper;
 
 
+    /**
+     *  获取
+     * @param id
+     * @return
+     */
+    public DcProduct getDcProduct(Long id){
+        return dcProductMapper.selectDcProductById(id);
+    }
+
+
     /**
      * 删除产品及其关联信息
      * @param dcpId
@@ -306,4 +319,26 @@ public class DcProductServiceImpl implements IDcProductService {
         }
         return 0;
     }
+
+
+    /**
+     *
+     * 导入JSON
+     * @param context
+     * @return
+     */
+    public int exportJSON(String context){
+        try{
+
+            CustomJsonParser.getParamValue(context,"");
+
+
+
+
+        }catch(Exception e){
+
+        }
+
+        return  0;
+    }
 }