feat:盖章修改

This commit is contained in:
dzc committed 2026-05-13 10:38:16 +08:00
1 parent 00287ca3b7
commit c9f39910f9
2 files changed
+73 -29

No files matched your search

@@ -67,12 +67,12 @@ import org.springframework.web.multipart.MultipartFile;
import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.ByteArrayOutputStream;
import java.io.InputStream;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.net.URL;
import java.net.URLConnection;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.HashMap;
@@ -415,42 +415,86 @@ public class WalletRechargeInvoiceServiceImpl extends ServiceImpl<WalletRecharge
if (ObjectUtil.isEmpty(imageBaseUrl)) {
throw new RuntimeException("请配置图片基础路径");
}
if (ObjectUtil.isEmpty(invoice.getPicUrl())) {
log.error("|{}|盖章失败,发票图片为空,invoice:|{}|", TAG, JSONUtil.toJsonStr(invoice));
return null;
}
// 开始盖章
String picUrl = String.format("%s%s", imageBaseUrl, invoice.getPicUrl());
// 发票底图宽高 3969 x 2154
int baseMapWidth = 3969, baseMapHeight = 2154;
// 盖章图片宽高
int stampOrgWidth = 600, stampOrgHeight = 600;
String picUrl = invoice.getPicUrl();
if (!picUrl.startsWith("http://") && !picUrl.startsWith("https://")) {
if (imageBaseUrl.endsWith("/") && picUrl.startsWith("/")) {
picUrl = imageBaseUrl + picUrl.substring(1);
} else if (!imageBaseUrl.endsWith("/") && !picUrl.startsWith("/")) {
picUrl = imageBaseUrl + "/" + picUrl;
} else {
picUrl = imageBaseUrl + picUrl;
}
}
int stampWidth = 500, stampHeight = 500;
try {
// 读取底图
BufferedImage baseImage = ImageIO.read(new URL(picUrl));
URLConnection connection = new URL(picUrl).openConnection();
connection.setConnectTimeout(5000);
connection.setReadTimeout(5000);
BufferedImage baseImage;
try (InputStream inputStream = connection.getInputStream()) {
baseImage = ImageIO.read(inputStream);
}
if (ObjectUtil.isEmpty(baseImage)) {
log.error("|{}|盖章失败,底图解析失败,picUrl:|{}|invoice:|{}|", TAG, picUrl, JSONUtil.toJsonStr(invoice));
return null;
}
// 读取盖章图片
BufferedImage stampImage = ImageIO.read(ResourceUtil.getResource("image/receiptStamp.png"));
stampImage.getScaledInstance(stampWidth, stampHeight, Image.SCALE_SMOOTH);
BufferedImage stampImage;
try (InputStream inputStream = ResourceUtil.getStream("image/receiptStamp.png")) {
stampImage = ImageIO.read(inputStream);
}
if (ObjectUtil.isEmpty(stampImage)) {
log.error("|{}|盖章失败,盖章图片资源不存在,invoice:|{}|", TAG, JSONUtil.toJsonStr(invoice));
return null;
}
BufferedImage scaledStamp = new BufferedImage(stampWidth, stampHeight, BufferedImage.TYPE_INT_ARGB);
Graphics2D stampG2d = scaledStamp.createGraphics();
stampG2d.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR);
stampG2d.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY);
stampG2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
stampG2d.drawImage(stampImage, 0, 0, stampWidth, stampHeight, null);
stampG2d.dispose();
// 创建新的图像上下文
Graphics2D g2d = baseImage.createGraphics();
// 设置抗锯齿
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
g2d.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR);
g2d.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY);
int baseMapWidth = baseImage.getWidth();
int baseMapHeight = baseImage.getHeight();
int x = (int) (stampWidth + baseMapWidth * 0.15 + 80);
int y = baseMapHeight - stampHeight - 50;
g2d.drawImage(stampImage, x, y, stampWidth, stampHeight, null);
x = Math.max(0, Math.min(x, baseMapWidth - stampWidth));
y = Math.max(0, Math.min(y, baseMapHeight - stampHeight));
g2d.drawImage(scaledStamp, x, y, null);
g2d.dispose();
String newPicUrl = invoice.getPicUrl().replaceFirst("(\\.\\w+)$", "_stamped$1");
File tempFile = File.createTempFile(newPicUrl, ".png");
ImageIO.write(baseImage, "PNG", tempFile);
// 保存到本地用于测试
// ImageIO.write(baseImage, "PNG", new File("test.png"));
// 上传图片
MultipartFile multipartFile = new MockMultipartFile("file", newPicUrl, "image/png", new FileInputStream(tempFile));
R upload = remoteFileService.innerUpload(multipartFile, null, null, null);
Map data = (Map) upload.getData();
String url = (String) data.get("url");
return url;
} catch (IOException e) {
e.printStackTrace();
log.error("|{}|盖章失败,IO异常,invoice:|{}|error:|{}|", TAG, JSONUtil.toJsonStr(invoice), e.getMessage());
String fileName = "invoice_stamped_" + invoice.getId() + ".png";
byte[] imageBytes;
try (ByteArrayOutputStream outputStream = new ByteArrayOutputStream()) {
ImageIO.write(baseImage, "PNG", outputStream);
imageBytes = outputStream.toByteArray();
}
MultipartFile multipartFile = new MockMultipartFile("file", fileName, "image/png", imageBytes);
R<?> upload = remoteFileService.innerUpload(multipartFile, null, null, null);
if (ObjectUtil.isEmpty(upload) || !upload.isOk() || ObjectUtil.isEmpty(upload.getData())) {
log.error("|{}|盖章失败,上传失败,upload:|{}|invoice:|{}|", TAG, JSON.toJSONString(upload), JSONUtil.toJsonStr(invoice));
return null;
}
Object dataObj = upload.getData();
if (!(dataObj instanceof Map<?, ?> data)) {
log.error("|{}|盖章失败,上传返回结构异常,data:|{}|invoice:|{}|", TAG, JSON.toJSONString(dataObj), JSONUtil.toJsonStr(invoice));
return null;
}
Object urlObj = data.get("url");
return ObjectUtil.isEmpty(urlObj) ? null : String.valueOf(urlObj);
} catch (Exception e) {
log.error("|{}|盖章失败,异常,invoice:|{}|", TAG, JSONUtil.toJsonStr(invoice), e);
return null;
}
}
@@ -582,4 +626,4 @@ public class WalletRechargeInvoiceServiceImpl extends ServiceImpl<WalletRecharge
}
}
}
}
}
@@ -22,7 +22,7 @@ public class InvoiceTest {
@Test
@Transactional
public void test() {
WalletRechargeInvoiceEntity detail = invoiceService.getById(1937849346822692865L);
WalletRechargeInvoiceEntity detail = invoiceService.getById(2054386187932225537L);
if (ObjectUtil.isNotEmpty(detail)) {
invoiceService.stamp(detail);
}