|
|
@@ -0,0 +1,75 @@
|
|
|
+package shop.alien.store.service.impl;
|
|
|
+
|
|
|
+import com.google.zxing.BarcodeFormat;
|
|
|
+import com.google.zxing.WriterException;
|
|
|
+import com.google.zxing.client.j2se.MatrixToImageWriter;
|
|
|
+import com.google.zxing.common.BitMatrix;
|
|
|
+import com.google.zxing.qrcode.QRCodeWriter;
|
|
|
+import lombok.RequiredArgsConstructor;
|
|
|
+import lombok.extern.slf4j.Slf4j;
|
|
|
+import org.apache.commons.lang3.StringUtils;
|
|
|
+import org.springframework.stereotype.Service;
|
|
|
+import shop.alien.store.service.ReservationVerificationQrService;
|
|
|
+import shop.alien.util.ali.AliOSSUtil;
|
|
|
+
|
|
|
+import java.io.ByteArrayInputStream;
|
|
|
+import java.io.ByteArrayOutputStream;
|
|
|
+import java.io.IOException;
|
|
|
+import java.io.InputStream;
|
|
|
+
|
|
|
+/**
|
|
|
+ * 预订订单核销码二维码:使用 ZXing 生成二维码图片并上传 OSS
|
|
|
+ *
|
|
|
+ * @author system
|
|
|
+ */
|
|
|
+@Slf4j
|
|
|
+@Service
|
|
|
+@RequiredArgsConstructor
|
|
|
+public class ReservationVerificationQrServiceImpl implements ReservationVerificationQrService {
|
|
|
+
|
|
|
+ private static final int QR_SIZE = 300;
|
|
|
+ private static final String OSS_DIR = "qrcode/reservation/verification/";
|
|
|
+
|
|
|
+ private final AliOSSUtil aliOSSUtil;
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public String generateQrImageAndUploadToOss(String verificationCode) {
|
|
|
+ if (StringUtils.isBlank(verificationCode)) {
|
|
|
+ log.warn("核销码为空,跳过二维码生成");
|
|
|
+ return null;
|
|
|
+ }
|
|
|
+ byte[] pngBytes = generateQrCodePng(verificationCode.trim());
|
|
|
+ if (pngBytes == null || pngBytes.length == 0) {
|
|
|
+ return null;
|
|
|
+ }
|
|
|
+ String ossPath = OSS_DIR + sanitizeForOssPath(verificationCode.trim()) + "_" + System.currentTimeMillis() + ".png";
|
|
|
+ try (InputStream in = new ByteArrayInputStream(pngBytes)) {
|
|
|
+ String url = aliOSSUtil.uploadFile(in, ossPath);
|
|
|
+ if (StringUtils.isNotBlank(url)) {
|
|
|
+ log.info("核销码二维码已上传 OSS, verificationCode={}, url={}", verificationCode, url);
|
|
|
+ return url;
|
|
|
+ }
|
|
|
+ } catch (IOException e) {
|
|
|
+ log.error("核销码二维码上传 OSS 异常, verificationCode={}", verificationCode, e);
|
|
|
+ }
|
|
|
+ return null;
|
|
|
+ }
|
|
|
+
|
|
|
+ private byte[] generateQrCodePng(String content) {
|
|
|
+ try {
|
|
|
+ QRCodeWriter writer = new QRCodeWriter();
|
|
|
+ BitMatrix matrix = writer.encode(content, BarcodeFormat.QR_CODE, QR_SIZE, QR_SIZE);
|
|
|
+ ByteArrayOutputStream out = new ByteArrayOutputStream();
|
|
|
+ MatrixToImageWriter.writeToStream(matrix, "PNG", out);
|
|
|
+ return out.toByteArray();
|
|
|
+ } catch (WriterException | IOException e) {
|
|
|
+ log.error("生成核销码二维码图片失败, content={}", content, e);
|
|
|
+ return null;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ private static String sanitizeForOssPath(String code) {
|
|
|
+ if (code == null) return "";
|
|
|
+ return code.replaceAll("[^a-zA-Z0-9_-]", "_");
|
|
|
+ }
|
|
|
+}
|