xdd 1 روز پیش
والد
کامیت
33644fc3e0
1فایلهای تغییر یافته به همراه214 افزوده شده و 80 حذف شده
  1. 214 80
      fs-user-app/src/main/java/com/fs/app/controller/store/UserScrmController.java

+ 214 - 80
fs-user-app/src/main/java/com/fs/app/controller/store/UserScrmController.java

@@ -39,9 +39,11 @@ import org.springframework.beans.factory.annotation.Value;
 import org.springframework.validation.annotation.Validated;
 import org.springframework.web.bind.annotation.*;
 
+import javax.imageio.ImageIO;
 import javax.servlet.http.HttpServletRequest;
 import javax.validation.Valid;
 import java.awt.*;
+import java.awt.image.BufferedImage;
 import java.io.File;
 import java.io.FileInputStream;
 import java.io.IOException;
@@ -128,14 +130,27 @@ public class UserScrmController extends AppBaseController {
     @GetMapping("/getTuiImg")
     public R getTuiImg(HttpServletRequest request){
         log.info("获取推荐海报 headers: {}", ServletUtil.getHeaderMap(request));
-
         log.info("开始获取推荐海报");
+
+        InputStream templateStream = null;
+        InputStream fontStream = null;
+
         try {
             String userId = getUserId();
             log.info("获取用户ID: {}", userId);
+
+            if (StringUtils.isEmpty(userId)) {
+                log.error("用户ID为空");
+                return R.error("用户ID不能为空");
+            }
+
             FsUserScrm user = userService.selectFsUserById(Long.parseLong(userId));
-            log.info("查询到用户信息: 用户ID={}, 昵称={}", userId, user.getNickname());
+            if (user == null) {
+                log.error("未找到用户信息,用户ID: {}", userId);
+                return R.error("用户信息不存在");
+            }
 
+            log.info("查询到用户信息: 用户ID={}, 昵称={}", userId, user.getNickname());
             if(StringUtils.isEmpty(user.getUserCode())){
                 log.info("用户邀请码为空,开始生成新的邀请码");
                 FsUserScrm userMap = new FsUserScrm();
@@ -145,104 +160,223 @@ public class UserScrmController extends AppBaseController {
                 user.setUserCode(userMap.getUserCode());
                 log.info("成功生成并更新用户邀请码: {}", userMap.getUserCode());
             }
+            File templateSourceFile = new File(getTuiImg);
+            File fontSourceFile = new File(getTuiFont);
+
+            if (!templateSourceFile.exists() || !templateSourceFile.isFile()) {
+                log.error("海报模板文件不存在: {}", getTuiImg);
+                return R.error("海报模板文件不存在");
+            }
+
+            if (!fontSourceFile.exists() || !fontSourceFile.isFile()) {
+                log.error("字体文件不存在: {}", getTuiFont);
+                return R.error("字体文件不存在");
+            }
+            String tempDir = System.getProperty("java.io.tmpdir") + File.separator + "poster_temp";
+            File tempDirFile = new File(tempDir);
+            if (!tempDirFile.exists()) {
+                tempDirFile.mkdirs();
+            }
+
+            File tempTemplateFile = new File(tempDir, "template_" + userId + "_" + System.currentTimeMillis() + ".jpg");
+            File tempFontFile = new File(tempDir, "font_" + userId + "_" + System.currentTimeMillis() + ".ttf");
 
-            File newFile = new File(getTuiImg);
-            File newFileT = new File(getTuiFont);
             try {
                 log.info("开始加载海报模板图片");
-                InputStream stream = new FileInputStream(getTuiImg);
-                FileUtils.copyInputStreamToFile(stream, newFile);
-                log.info("海报模板图片加载成功: {}", newFile.getAbsolutePath());
-
-                if(!newFileT.exists()){
-                    log.info("开始加载字体文件");
-                    InputStream streamT = new FileInputStream(getTuiFont);
-                    FileUtils.copyInputStreamToFile(streamT, newFileT);
-                    log.info("字体文件加载成功: {}", newFileT.getAbsolutePath());
+                templateStream = new FileInputStream(templateSourceFile);
+                FileUtils.copyInputStreamToFile(templateStream, tempTemplateFile);
+                log.info("海报模板图片加载成功: {}", tempTemplateFile.getAbsolutePath());
+                if (!isValidImageFile(tempTemplateFile)) {
+                    log.error("模板图片文件无效或损坏");
+                    return R.error("模板图片文件无效");
                 }
+                log.info("开始加载字体文件");
+                fontStream = new FileInputStream(fontSourceFile);
+                FileUtils.copyInputStreamToFile(fontStream, tempFontFile);
+                log.info("字体文件加载成功: {}", tempFontFile.getAbsolutePath());
+
             } catch (IOException e) {
                 log.error("加载资源文件失败: {}", e.getMessage(), e);
-                throw new CustomException(e.getMessage());
+                return R.error("加载资源文件失败: " + e.getMessage());
+            }
+            return generatePoster(user, tempTemplateFile, tempFontFile, userId);
+
+        } catch (NumberFormatException e) {
+            log.error("用户ID格式错误: {}", e.getMessage(), e);
+            return R.error("用户ID格式错误");
+        } catch (Exception e){
+            log.error("获取推荐海报失败: {}", e.getMessage(), e);
+            return R.error("操作异常: " + e.getMessage());
+        } finally {
+            closeQuietly(templateStream);
+            closeQuietly(fontStream);
+        }
+    }
+
+    /**
+     * 生成海报的核心方法
+     */
+    private R generatePoster(FsUserScrm user, File templateFile, File fontFile, String userId) {
+        File outputFile = null;
+        File qrFile = null;
+
+        try {
+            String outputDir = fsConfig.getTuiImgPath();
+            File outputDirFile = new File(outputDir);
+            if (!outputDirFile.exists()) {
+                outputDirFile.mkdirs();
+            }
+
+            String outputPath = outputDir + "/tui-" + userId + ".jpg";
+            outputFile = new File(outputPath);
+            log.info("开始生成用户海报,输出路径: {}", outputPath);
+            Font font;
+            try {
+                font = Font.createFont(Font.TRUETYPE_FONT, fontFile);
+                font = font.deriveFont(Font.PLAIN, 50f);
+                log.info("字体加载成功");
+            } catch (Exception e) {
+                log.error("字体加载失败: {}", e.getMessage(), e);
+                font = new Font(Font.SANS_SERIF, Font.PLAIN, 50);
+                log.info("使用系统默认字体作为备选");
             }
+            String nickname = user.getNickname();
+            if (StringUtils.isEmpty(nickname)) {
+                nickname = "用户";
+            }
+
+            log.info("开始向海报添加用户昵称文本: {}", nickname);
             try {
-                String url = fsConfig.getTuiImgPath()+"/tui-"+getUserId()+".jpg";
-                log.info("开始生成用户海报,输出路径: {}", url);
-
-                File outputFile = new File(url);
-                if(!outputFile.exists()) {
-                    try {
-                        outputFile.createNewFile();
-                        log.info("创建海报输出文件成功");
-                    } catch (IOException e) {
-                        log.error("创建海报输出文件失败: {}", e.getMessage(), e);
-                        e.printStackTrace();
-                    }
+                FileUtils.copyFile(templateFile, outputFile);
+
+                BufferedImage templateImage = ImageIO.read(templateFile);
+                if (templateImage == null) {
+                    log.error("无法读取模板图片");
+                    return R.error("模板图片读取失败");
                 }
 
-                Font font = Font.createFont(Font.TRUETYPE_FONT, newFileT);
-                Font f = font.deriveFont(Font.PLAIN,50);
-                log.info("开始向海报添加用户昵称文本");
-                ImgUtil.pressText(
-                        newFile,
-                        outputFile,
-                        user.getNickname()+"邀您加入",
-                        Color.BLACK,
-                        f,
-                        -60,
-                        900,
-                        0.8f
+                BufferedImage resultImage = new BufferedImage(
+                        templateImage.getWidth(),
+                        templateImage.getHeight(),
+                        BufferedImage.TYPE_INT_RGB
                 );
 
-                log.info("开始向海报添加邀请码文本: {}", user.getUserCode());
-                ImgUtil.pressText(
-                        outputFile,
-                        outputFile,
-                        "邀请码:"+user.getUserCode(),
-                        Color.BLACK,
-                        f,
-                        -40,
-                        1000,
-                        0.8f
-                );
+                Graphics2D g2d = resultImage.createGraphics();
+                try {
+                    g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
+                    g2d.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
+
+                    g2d.drawImage(templateImage, 0, 0, null);
+
+                    g2d.setFont(font);
+                    g2d.setColor(Color.BLACK);
 
-                String qrPath = fsConfig.getTuiImgPath()+"/qr-"+getUserId()+".png";
-                File qr = new File(qrPath);
-                log.info("开始生成二维码图片: {}", qrPath);
-                if(!qr.exists()) {
-                    try {
-                        qr.createNewFile();
-                        log.info("创建二维码输出文件成功");
-                    } catch (IOException e) {
-                        log.error("创建二维码输出文件失败: {}", e.getMessage(), e);
-                        e.printStackTrace();
-                    }
+                    String nicknameText = nickname + "邀您加入";
+                    FontMetrics fm = g2d.getFontMetrics();
+                    int textWidth = fm.stringWidth(nicknameText);
+                    int x = (templateImage.getWidth() - textWidth) / 2;
+                    int y = 900;
+
+                    g2d.drawString(nicknameText, x, y);
+
+                    String inviteText = "邀请码:" + user.getUserCode();
+                    int inviteTextWidth = fm.stringWidth(inviteText);
+                    int inviteX = (templateImage.getWidth() - inviteTextWidth) / 2;
+                    int inviteY = 1000;
+
+                    g2d.drawString(inviteText, inviteX, inviteY);
+
+                } finally {
+                    g2d.dispose();
                 }
 
-                String qrContent = fsConfig.getUrl()+"/distribution?userCode="+user.getUserCode();
-                log.info("生成二维码内容: {}", qrContent);
-                QrCodeUtil.generate(qrContent, 300, 300, FileUtil.file(qrPath));
+                ImageIO.write(resultImage, "jpg", outputFile);
+                log.info("文本添加完成");
 
+            } catch (Exception e) {
+                log.error("添加文本时出现异常: {}", e.getMessage(), e);
+                return R.error("添加文本失败: " + e.getMessage());
+            }
+            String qrPath = fsConfig.getTuiImgPath() + "/qr-" + userId + ".png";
+            qrFile = new File(qrPath);
+            log.info("开始生成二维码图片: {}", qrPath);
+            try {
+                String qrContent = fsConfig.getUrl() + "/distribution?userCode=" + user.getUserCode();
+                log.info("生成二维码内容: {}", qrContent);
+                QrCodeUtil.generate(qrContent, 300, 300, qrFile);
+                log.info("二维码生成成功");
+            } catch (Exception e) {
+                log.error("生成二维码失败: {}", e.getMessage(), e);
+                return R.error("生成二维码失败: " + e.getMessage());
+            }
+            try {
                 log.info("开始将二维码图片合并到海报");
-                ImgUtil.pressImage(
-                        outputFile,
-                        outputFile,
-                        ImgUtil.read(qr),
-                        -400,
-                        900,
-                        1f
-                );
+                BufferedImage posterImage = ImageIO.read(outputFile);
+                BufferedImage qrImage = ImageIO.read(qrFile);
+
+                if (posterImage == null || qrImage == null) {
+                    log.error("读取图片失败,无法合并二维码");
+                    return R.error("图片读取失败");
+                }
+
+                Graphics2D g2d = posterImage.createGraphics();
+                try {
+                    g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
+
+                    int qrX = posterImage.getWidth() - qrImage.getWidth() - 50;
+                    int qrY = 900;
+
+                    g2d.drawImage(qrImage, qrX, qrY, null);
+                } finally {
+                    g2d.dispose();
+                }
+
+                ImageIO.write(posterImage, "jpg", outputFile);
+                log.info("二维码合并完成");
 
-                String resultUrl = "profile/tui/tui-"+getUserId()+".jpg";
-                log.info("海报生成完成,返回URL: {}", resultUrl);
-                return R.ok().put("url", resultUrl);
             } catch (Exception e) {
-                log.error("生成海报过程出现异常: {}", e.getMessage(), e);
-                e.printStackTrace();
-                return R.error("操作异常");
+                log.error("合并二维码时出现异常: {}", e.getMessage(), e);
+                return R.error("合并二维码失败: " + e.getMessage());
+            }
+            String resultUrl = "profile/tui/tui-" + userId + ".jpg";
+            log.info("海报生成完成,返回URL: {}", resultUrl);
+            return R.ok().put("url", resultUrl);
+
+        } catch (Exception e) {
+            log.error("生成海报过程出现异常: {}", e.getMessage(), e);
+            return R.error("生成海报失败: " + e.getMessage());
+        } finally {
+            cleanupTempFiles(qrFile);
+        }
+    }
+    private boolean isValidImageFile(File imageFile) {
+        try {
+            BufferedImage image = ImageIO.read(imageFile);
+            return image != null && image.getWidth() > 0 && image.getHeight() > 0;
+        } catch (Exception e) {
+            log.error("验证图片文件失败: {}", e.getMessage());
+            return false;
+        }
+    }
+    private void closeQuietly(InputStream stream) {
+        if (stream != null) {
+            try {
+                stream.close();
+            } catch (IOException e) {
+                log.warn("关闭流时出现异常: {}", e.getMessage());
+            }
+        }
+    }
+    private void cleanupTempFiles(File... files) {
+        for (File file : files) {
+            if (file != null && file.exists()) {
+                try {
+                    file.delete();
+                    log.debug("删除临时文件: {}", file.getAbsolutePath());
+                } catch (Exception e) {
+                    log.warn("删除临时文件失败: {}", e.getMessage());
+                }
             }
-        } catch (Exception e){
-            log.error("获取推荐海报失败: {}", e.getMessage(), e);
-            return R.error("操作异常");
         }
     }