wangyunpeng 4 semanas atrás
pai
commit
d71961878e

+ 13 - 0
common-module/pom.xml

@@ -17,6 +17,19 @@
         <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
     </properties>
 
+    <dependencies>
+        <dependency>
+            <groupId>com.google.zxing</groupId>
+            <artifactId>core</artifactId>
+            <version>3.4.1</version>
+        </dependency>
+        <dependency>
+            <groupId>com.google.zxing</groupId>
+            <artifactId>javase</artifactId>
+            <version>3.4.1</version>
+        </dependency>
+    </dependencies>
+
     <build>
         <plugins>
             <plugin>

+ 139 - 0
common-module/src/main/java/com/tzld/piaoquan/growth/common/utils/BaseUtils.java

@@ -0,0 +1,139 @@
+package com.tzld.piaoquan.growth.common.utils;
+
+import org.apache.http.util.TextUtils;
+import org.springframework.beans.BeanUtils;
+import org.springframework.util.StringUtils;
+
+import java.math.BigDecimal;
+import java.math.RoundingMode;
+import java.util.Objects;
+import java.util.UUID;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+public class BaseUtils {
+
+    public static void copyProperties(Object orig, Object dest) {
+        // spring的BeanUtils性能较好
+        BeanUtils.copyProperties(orig, dest);
+    }
+
+    public static String getUUID() {
+        return UUID.randomUUID().toString();
+    }
+
+    public static String getUUIDStr() {
+        return UUID.randomUUID().toString().replaceAll("-", "");
+    }
+
+    private static String[] chars = new String[]{"a", "b", "c", "d", "e", "f",
+            "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s",
+            "t", "u", "v", "w", "x", "y", "z", "0", "1", "2", "3", "4", "5",
+            "6", "7", "8", "9", "A", "B", "C", "D", "E", "F", "G", "H", "I",
+            "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V",
+            "W", "X", "Y", "Z"};
+
+    public static String getShortUUIDStr() {
+        StringBuffer shortBuffer = new StringBuffer();
+        String uuid = UUID.randomUUID().toString().replace("-", "");
+        for (int i = 0; i < 8; i++) {
+            String str = uuid.substring(i * 4, i * 4 + 4);
+            int x = Integer.parseInt(str, 16);
+            shortBuffer.append(chars[x % 0x3E]);
+        }
+        return shortBuffer.toString();
+    }
+
+    public static String getShortUUIDStr_6() {
+        StringBuffer shortBuffer = new StringBuffer();
+        String uuid = UUID.randomUUID().toString().replace("-", "");
+        System.out.println("uuid = " + uuid.length() + " , chars = " + chars.length);
+        for (int i = 0; i < 6; i++) {
+            String str = uuid.substring(i * 5, i * 5 + 5);
+            int x = Integer.parseInt(str, 16);
+            shortBuffer.append(chars[x % 0x3E]);
+        }
+        return shortBuffer.toString();
+    }
+
+    /**
+     * 带时间戳的uuid
+     *
+     * @return
+     */
+    public static String getTimestampUUIDStr() {
+        return UUID.randomUUID().toString().replaceAll("-", "") + System.currentTimeMillis();
+    }
+
+    public static boolean isUidAvailable(Long uid) {
+        return Objects.nonNull(uid) && uid >= 0;
+    }
+
+    public static boolean checkEmailAddressAvailable(String email) {
+        String check = "^[a-zA-Z0-9_-]+@[a-zA-Z0-9_-]+(\\.[a-zA-Z0-9_-]+)+$";
+        Pattern regex = Pattern.compile(check);
+        Matcher matcher = regex.matcher(email);
+        return matcher.matches();
+    }
+
+    public static int getInt(String intValue, int defaultValue) {
+        try {
+            return Integer.parseInt(intValue);
+        } catch (NumberFormatException e) {
+            e.printStackTrace();
+        }
+        return defaultValue;
+    }
+
+    public static boolean isContainChinese(String str) {
+        if (TextUtils.isEmpty(str)) {
+            return false;
+        }
+        try {
+            Pattern p = Pattern.compile("[\u4E00-\u9FA5|\\!|\\,|\\。|\\(|\\)|\\《|\\》|\\“|\\”|\\?|\\:|\\;|\\【|\\】]");
+            Matcher m = p.matcher(str);
+            if (m.find()) {
+                return true;
+            }
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+        return false;
+    }
+
+    public static String calcRate(Integer a, Integer b) {
+        if (a == null || b == null || b == 0) {
+            return "0";
+        }
+        return new BigDecimal(a).divide(new BigDecimal(b), 2, RoundingMode.HALF_UP).toString();
+    }
+
+    public static boolean isNumberStr(String str){
+        Pattern pattern = Pattern.compile("[0-9]*");
+        return pattern.matcher(str).matches();
+    }
+
+    public static String getFirstGroupPlanExeId(String planExeId) {
+        if (StringUtils.hasText(planExeId) && planExeId.contains("_")) {
+            return planExeId.substring(0, planExeId.indexOf("_"));
+        }
+        return planExeId;
+    }
+
+    public static boolean isFirstGroupPlanExeId(String planExeId) {
+        if (StringUtils.hasText(planExeId) && planExeId.contains("_")) {
+            return false;
+        }
+        return true;
+    }
+
+    public static void main(String[] args) {
+        System.out.println(checkEmailAddressAvailable("a-a_a@q-q.A"));
+        System.out.println(getUUIDStr());
+        System.out.println(getShortUUIDStr());
+        System.out.println(getShortUUIDStr_6());
+        System.out.println(isNumberStr("20240201052729691500183"));
+        System.out.println(getFirstGroupPlanExeId("20240314125002672235936_2"));
+        System.out.println("20240314125002672235936_2".substring("20240314125002672235936_2".indexOf("_") + 1));
+    }
+}

+ 26 - 0
common-module/src/main/java/com/tzld/piaoquan/growth/common/utils/FileUtils.java

@@ -2,6 +2,12 @@ package com.tzld.piaoquan.growth.common.utils;
 
 import org.springframework.web.multipart.MultipartFile;
 
+import java.io.File;
+import java.io.IOException;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+
 public class FileUtils {
 
     public static String getExtension(MultipartFile file) {
@@ -19,4 +25,24 @@ public class FileUtils {
 
         return fileName.substring(lastIndex).toLowerCase();
     }
+
+    public static void deleteFileByIO(String filePath) {
+        File file = new File(filePath);
+        File[] list = file.listFiles();
+        if (list != null) {
+            for (File temp : list) {
+                deleteFileByIO(temp.getAbsolutePath());
+            }
+        }
+        file.delete();
+    }
+
+    public static void saveFileContent(String filePath, byte[] contentBytes) throws IOException {
+        Path path = Paths.get(filePath);
+        Path parentDir = path.getParent();
+        if (!Files.exists(parentDir)) {
+            Files.createDirectories(parentDir);
+        }
+        Files.write(path, contentBytes);
+    }
 }

+ 257 - 0
common-module/src/main/java/com/tzld/piaoquan/growth/common/utils/QrCodes.java

@@ -0,0 +1,257 @@
+package com.tzld.piaoquan.growth.common.utils;
+
+import com.google.zxing.*;
+import com.google.zxing.client.j2se.BufferedImageLuminanceSource;
+import com.google.zxing.common.BitMatrix;
+import com.google.zxing.common.HybridBinarizer;
+import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel;
+import okhttp3.Call;
+import okhttp3.OkHttpClient;
+import okhttp3.Request;
+import okhttp3.Response;
+import org.apache.commons.lang.StringUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import javax.imageio.ImageIO;
+import java.awt.*;
+import java.awt.image.BufferedImage;
+import java.io.*;
+import java.nio.charset.Charset;
+import java.nio.charset.StandardCharsets;
+import java.util.Base64;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Objects;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * @description: 生成二维码
+ * @author: TanJingyu
+ * @create:2023-06-12 11:17:01
+ **/
+public class QrCodes {
+    private static final Logger logger = LoggerFactory.getLogger(QrCodes.class);
+    /**
+     * 定义二维码图片的宽度
+     */
+    public static final int DEFAULT_WIDTH = 500;
+    /**
+     * 定义二维码图片的高度
+     */
+    public static final int DEFAULT_HEIGHT = 500;
+    /**
+     * 定义LOGO图片的宽度
+     */
+    public static final int DEFAULT_LOGO_WIDTH = 100;
+    /**
+     * 定义LOGO图片的高度
+     */
+    public static final int DEFAULT_LOGO_HEIGHT = 100;
+    /**
+     * 定义二维码的边距,默认一个单位
+     */
+    public static final int DEFAULT_MARGIN = 1;
+    /**
+     * 定义二维码生成后的预估大小,越准确的设置,越能避免byteArrayOutPutStream中数组的多次扩容
+     */
+    public static final int DEFAULT_ESTIMATE_SIZE = 9216;
+    /**
+     * 定义编码
+     */
+    public static final Charset DEFAULT_CHARSET = StandardCharsets.UTF_8;
+    /**
+     * 定义二维码图像的后缀
+     */
+    public static final String DEFAULT_FORMAT = "png";
+
+
+    public static String createForBase64Str(String url) {
+        return createForBase64Str(url, null);
+    }
+
+    public static String createForBase64Str(String url, String logoLocation) {
+        return createForBase64Str(url, logoLocation, DEFAULT_FORMAT, DEFAULT_HEIGHT, DEFAULT_WIDTH, DEFAULT_LOGO_WIDTH, DEFAULT_LOGO_HEIGHT, DEFAULT_MARGIN, DEFAULT_ESTIMATE_SIZE, DEFAULT_CHARSET);
+    }
+
+
+    /**
+     * 前后端分离模式,推荐将二维码图片的二进制数组经base64成字符串返回给前端,这样有时可以避免前端再次请求后端
+     *
+     * @param url          二维码的真实地址
+     * @param logoLocation 二维码中间logo在后端项目中的位置,resource下边
+     * @param format       生成二维码的图片格式
+     * @param height       二维码图片的高度
+     * @param width        二维码图片的宽度
+     * @param logoWidth    中间logo宽度
+     * @param logoHeight   中间logo高度
+     * @param margin       二维码图片边距
+     * @param estimateSize 估计二维码图片的大小会是多大?越精准的估计,越能避免byteArrayOutPutStream中缓存数组的扩容
+     * @param charset      编码
+     */
+    public static String createForBase64Str(String url, String logoLocation, String format, int height, int width, int logoWidth, int logoHeight, int margin, int estimateSize, Charset charset) {
+        try {
+            /*生成二维码*/
+            // 定义Map集合封装二维码配置信息
+            Map<EncodeHintType, Object> hints = new HashMap<>();
+            // 设置二维码图片的内容编码
+            hints.put(EncodeHintType.CHARACTER_SET, charset.displayName());
+            // 设置二维码图片的上、下、左、右间隙
+            hints.put(EncodeHintType.MARGIN, margin);
+            // 设置二维码的纠错级别
+            hints.put(EncodeHintType.ERROR_CORRECTION,
+                    ErrorCorrectionLevel.H);
+            //创建二维码字节转换对象
+            //第一个参数:二维码图片中的内容
+            //第二个参数:二维码格式器
+            //第三个参数:生成二维码图片的宽度
+            //第四个参数:生成二维码图片的高度
+            //第五个参数:生成二维码需要配置信息
+            BitMatrix matrix = new
+                    MultiFormatWriter().encode(url,
+                    BarcodeFormat.QR_CODE, width, height, hints);
+
+
+
+            /*生成放置二维码和中间logo的底图,并将二维码画上去*/
+            // 获取二维码图片真正的宽度
+            int matrix_width = matrix.getWidth();
+            // 获取二维码图片真正的高度
+            int matrix_height = matrix.getHeight();
+            // 定义一张空白的缓冲流图片
+            BufferedImage image = new
+                    BufferedImage(matrix_width, matrix_height,
+                    BufferedImage.TYPE_INT_RGB);
+            // 把二维码字节转换对象 转化 到缓冲流图片上
+            for (int x = 0; x < matrix_width; x++) {
+                for (int y = 0; y < matrix_height; y++) {
+                    // 通过x、y坐标获取一点的颜色 true: 黑色  false: 白色
+                    int rgb = matrix.get(x, y) ? 0x000000 : 0xFFFFFF;
+//                    int rgb = matrix.get(x, y) ? 0x008000 : 0xFFFFFF;
+                    image.setRGB(x, y, rgb);
+                }
+            }
+
+
+
+            /*处理logo,把logo画到底图中间*/
+            InputStream logoStream = null;
+            if (StringUtils.isNotBlank(logoLocation)) {
+                logoStream = QrCodes.class.getClassLoader().getResourceAsStream(logoLocation);
+                if (Objects.isNull(logoStream)) {
+                    logger.warn("生成二维码失败,未找到logo图");
+                    return "";
+                }
+            }
+            if (Objects.nonNull(logoStream)) {
+                BufferedImage logo = ImageIO.read(logoStream);
+                // 获取缓冲流图片的画笔
+                Graphics2D g = (Graphics2D) image.getGraphics();
+                // 在二维码图片中间绘制公司logo
+                g.drawImage(logo, (matrix_width - logoWidth) / 2,
+                        (matrix_height - logoHeight) / 2,
+                        logoWidth, logoHeight, null);
+
+                // 设置画笔的颜色
+                g.setColor(Color.WHITE);
+                // 设置画笔的粗细
+                g.setStroke(new BasicStroke(5.0f));
+                // 设置消除锯齿
+                g.setRenderingHint(RenderingHints
+                        .KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
+                // 绘制圆角矩形
+                g.drawRoundRect((matrix_width - logoWidth) / 2,
+                        (matrix_height - logoHeight) / 2,
+                        logoWidth, logoHeight, 10, 10);
+            }
+
+
+            /*base64字符串返回图片*/
+            ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream(estimateSize);
+            ImageIO.write(image, format, byteArrayOutputStream);
+            return Base64.getEncoder().encodeToString(byteArrayOutputStream.toByteArray());
+        } catch (Exception e) {
+            logger.error("生成二维码出错: {}", e.getMessage());
+            e.printStackTrace();
+            return "";
+        }
+    }
+
+    public static String checkQRCode(String filePath){
+        long start = System.currentTimeMillis();
+        try {
+            // 读取二维码图片到缓冲区
+            BufferedImage image = ImageIO.read(new File(filePath));
+            LuminanceSource source = new BufferedImageLuminanceSource(image);
+            Binarizer binarizer = new HybridBinarizer(source);
+            BinaryBitmap binaryBitmap = new BinaryBitmap(binarizer);
+            Map<DecodeHintType, Object> hints = new HashMap<DecodeHintType, Object>();
+            hints.put(DecodeHintType.CHARACTER_SET, "UTF-8");
+            Result result = new MultiFormatReader().decode(binaryBitmap, hints);// 对图像进行解码
+            logger.info("checkQRCode ======>>encode Type: " + result.getBarcodeFormat() + " ======>>content:" + result.getText());
+            return result.getText();
+        } catch (Exception e) {
+            logger.error("checkQRCodeError" + e.getMessage());
+            return null;
+        }
+    }
+
+    public static String downloadAndCheckQRCode(String url, String filePath) {
+        try {
+            File image = new File(filePath);
+            downloadFile(url, image);
+            return QrCodes.checkQRCode(filePath);
+        } catch (Exception e) {
+            logger.error("downloadAndCheckQRCode Error url:{} cost:{}", url, e);
+        } finally {
+            FileUtils.deleteFileByIO(filePath);
+        }
+        return null;
+    }
+
+    public static BufferedImage resizeImage(BufferedImage originalImage, int targetWidth, int targetHeight) throws IOException {
+        Image resultingImage = originalImage.getScaledInstance(targetWidth, targetHeight, Image.SCALE_AREA_AVERAGING);
+        BufferedImage outputImage = new BufferedImage(targetWidth, targetHeight, BufferedImage.TYPE_INT_RGB);
+        outputImage.getGraphics().drawImage(resultingImage, 0, 0, null);
+        return outputImage;
+    }
+
+    public static void downloadFile(String url, File file) throws Exception {
+        Request request = new Request.Builder()
+                .url(url)
+                .build();
+        OkHttpClient client = new OkHttpClient().newBuilder()
+                .connectTimeout(3, TimeUnit.MINUTES)
+                .readTimeout(1, TimeUnit.MINUTES)
+                .writeTimeout(1, TimeUnit.MINUTES).build();
+        Call call = client.newCall(request);
+        Response response = call.execute();
+        InputStream is = response.body().byteStream();
+        FileOutputStream outputStream = new FileOutputStream(file);
+        byte[] buffer = new byte[4096];
+        int bytesRead;
+        while ((bytesRead = is.read(buffer)) != -1) {
+            outputStream.write(buffer, 0, bytesRead);
+        }
+        is.close();
+    }
+
+
+
+
+    public static void main(String[] args) {
+        String filePath = "/Users/wangyunpeng/IdeaProjects/aigc-admin/datalog/weblog/aigc-admin/";
+        String fileName = BaseUtils.getUUIDStr();
+        try {
+            File image = new File(filePath + fileName);
+            downloadFile("https://mmbiz.qpic.cn/sz_mmbiz_png/rGQMLMianRiaZgicELeh23DhLhjTTY2BPRqp3OwGDtXIAp7Za75iazicK29p2LKfnjdZVRsgyTkXASdttsINd9erkew/640?wx_fmt=png&from=appmsg", image);
+            System.out.println(QrCodes.checkQRCode(filePath + fileName));
+        } catch (Exception e) {
+
+        } finally {
+//            FileUtils.deleteFileByIO(filePath + fileName);
+        }
+    }
+}
+
+