微信小程序码生成工具

1. 所需依赖

<dependency>
	<groupId>com.squareup.okhttp3</groupId>
	<artifactId>okhttp</artifactId>
</dependency>

<dependency>
	<groupId>com.alibaba</groupId>
	<artifactId>fastjson</artifactId>
	<version>1.2.83</version>
</dependency>

<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>

<dependency>
	<groupId>org.springframework</groupId>
	<artifactId>spring-test</artifactId>
</dependency>

2. 配置文件

# 微信小程序配置
wxApp:
  appId: xxx
  appSecret: xxx
  envVersion: trial
  uploadPagePath: bundle/pages/picture-upload/picture-upload

3. 创建二维码生成工具类

package org.jeecg.modules.system.util;

import com.alibaba.fastjson.JSONObject;
import okhttp3.*;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang3.StringUtils;
import org.jeecg.common.util.RedisUtil;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.io.*;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.HashMap;
import java.util.Map;

/**
 * 微信小程序码生成工具
 */
@Component
public class WxAppQRCodeUtils {

    private static final OkHttpClient HTTP_CLIENT = new OkHttpClient().newBuilder().build();

    //获取token地址
    private static final String API_GET_TOKEN = "https://api.weixin.qq.com/cgi-bin/token";
    //获取小程序码接口
    private static final String API_POST_QR_CODE = "https://api.weixin.qq.com/wxa/getwxacodeunlimit?access_token=";

    //redisKey微信小程序token前缀
    private static final String WX_TOKEN_PREFIX = "WxAppToken_";

    @Resource
    private RedisUtil redisUtil;

    /**
     * 生成并返回小程序码
     * @param appId 小程序id
     * @param appSecret secret
     * @param page 页面路径(根路径前不要填加 /,不能携带参数)
     * @param scene  携带参数
     * @param envVersion 要打开的小程序版本。正式版为 "release",体验版为 "trial",开发版为 "develop"。默认是正式版
     * @param checkPath 默认是true,检查page 是否存在,为 true 时 page 必须是已经发布的小程序存在的页面(否则报错);为 false 时允许小程序未发布或者 page 不存在
     */
    public byte[] getQRCodeByte(String appId, String appSecret, String page, String scene, String envVersion, Boolean checkPath) {
        byte[] qrCodeBytes = null;
        try {
            HttpURLConnection conn = (HttpURLConnection) new URL(API_POST_QR_CODE + getToken(appId, appSecret)).openConnection();
            conn.setRequestMethod("POST");
            conn.setRequestProperty("Content-Type", "application/json");
            conn.setDoOutput(true);
            if (StringUtils.isBlank(envVersion)) {
                envVersion = "release";
            }
            Map<String, Object> paramMap = new HashMap<>();
            paramMap.put("scene", scene);
            paramMap.put("page", page);
            paramMap.put("check_path", checkPath);
            paramMap.put("env_version", envVersion);
            String param = GsonUtils.toJson(paramMap);
            conn.getOutputStream().write(param.getBytes("UTF-8"));
            InputStream is = conn.getInputStream();
            qrCodeBytes = IOUtils.toByteArray(is);
            is.close();
            conn.disconnect();
        }catch (Exception e) {
            e.printStackTrace();
        }
        return qrCodeBytes;
    }

   

    /**
     * 根据appid及secret获取token
     * @param appId 小程序id
     * @param appSecret secret
     * @return token
     */
    private String getToken(String appId, String appSecret) {
        String token = null;
        String redisKey = WX_TOKEN_PREFIX + appId;
        if (redisUtil.hasKey(redisKey)) {
            return redisUtil.get(redisKey).toString();
        }
        try {
            Request request = new Request.Builder()
                    .url(API_GET_TOKEN + "?grant_type=client_credential&appid=" + appId + "&secret=" + appSecret)
                    .build();
            Response response = HTTP_CLIENT.newCall(request).execute();
            assert response.body() != null;
            JSONObject result = JSONObject.parseObject(response.body().string());
            token = result.getString("access_token");
            redisUtil.set(redisKey, token, Long.parseLong(result.getString("expires_in")));
        }catch (Exception e) {
            e.printStackTrace();
        }
        return token;
    }


}

4. 文件处理工具类

package org.jeecg.modules.system.util;

import org.jeecg.common.util.CommonUtils;
import org.springframework.mock.web.MockMultipartFile;
import org.springframework.web.multipart.MultipartFile;

import java.io.*;
import java.net.URL;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.ArrayList;
import java.util.Base64;
import java.util.UUID;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * 文件处理工具类
 */
public class ImageFileUtils {


    /**
     * 图片base64转MultipartFile
     * @param base64Str
     * @return
     * @throws IOException
     */
    public static MultipartFile convertByBase64(String base64Str) throws IOException {
        // 解码base64字符串
        byte[] data = Base64.getDecoder().decode(base64Str);

        // 创建临时文件
        Path tempFilePath = Files.createTempFile("tempfile", ".tmp");
        Files.write(tempFilePath, data);

        String uuid = UUID.randomUUID().toString();

        // 创建MultipartFile实例
        MultipartFile multipartFile = new MockMultipartFile(uuid, uuid + ".png", "image/png", Files.newInputStream(tempFilePath));

        // 删除临时文件
        Files.delete(tempFilePath);

        return multipartFile;
    }

    /**
     * 根据图片url地址转换base64
     * @param imageUrl
     * @return
     */
    public static String convertByImgUrl(String imageUrl) {
        try (InputStream inputStream = new URL(imageUrl).openStream(); ByteArrayOutputStream outputStream = new ByteArrayOutputStream()) {
            byte[] buffer = new byte[1024];
            int bytesRead;
            while ((bytesRead = inputStream.read(buffer)) != -1) {
                outputStream.write(buffer, 0, bytesRead);
            }
            byte[] imageBytes = outputStream.toByteArray();
            return Base64.getEncoder().encodeToString(imageBytes);
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }

    /**
     * 图片url转File
     * @param imageUrl
     * @return
     */
    public static File getFile(String imageUrl) {
        //对本地文件命名
        String fileName = UUID.randomUUID() + ".png";
        File file = null;

        URL urlfile;
        InputStream inStream = null;
        OutputStream os = null;
        try {
            file = File.createTempFile("net_url", fileName);
            //下载
            urlfile = new URL(imageUrl);
            inStream = urlfile.openStream();
            os = new FileOutputStream(file);

            int bytesRead = 0;
            byte[] buffer = new byte[8192];
            while ((bytesRead = inStream.read(buffer, 0, 8192)) != -1) {
                os.write(buffer, 0, bytesRead);
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                if (null != os) {
                    os.close();
                }
                if (null != inStream) {
                    inStream.close();
                }

            } catch (Exception e) {
                e.printStackTrace();
            }
        }

        return file;
    }

    /**
     * 解析出图片 url
     *
     * @param content md文本(源 md 文本使用 html 的 <img> 标签 src 属性引用图片)
     * @return 提取 src 属性值
     */
    public static ArrayList<String> extractUrls(String content) {
        ArrayList<String> imgUrls = new ArrayList<>();
        Pattern compile = Pattern.compile("!\\[.*?\\]\\((.*?)\\)");
        Matcher matcher = compile.matcher(content);
        while (matcher.find()) {
            String group = matcher.group(1);
            String replace = group.replace("src=", "").replace("\"", "");
            imgUrls.add(replace);
        }
        return imgUrls;
    }

    /**
     * 解析markdown中图片url,下载上传文件并替换url
     * @param source 源文件
     * @return
     */
    public static String getMarkDownImageContent(String source) {
        String content = source;
        try {
            ArrayList<String> imgUrls = extractUrls(source);
            for (String img : imgUrls) {
                String imgUrl = CommonUtils.upload(convertByImageUrl(img), "upload/aiChat", "alioss");
                content = content.replace(img, imgUrl);
            }
        }catch (Exception e) {
            e.printStackTrace();
        }
        return content;
    }

    /**
     * 图片url转MultipartFile
     * @param imageUrl
     * @return
     * @throws IOException
     */
    public static MultipartFile convertByImageUrl(String imageUrl) throws IOException {
        URL url = new URL(imageUrl);
        InputStream inputStream = url.openStream();

        // 获取图片文件名
        String fileName = UUID.randomUUID().toString();

        // 使用Spring的MockMultipartFile类来创建MultipartFile
        return new MockMultipartFile(fileName, fileName + ".png", "text/plain", inputStream);
    }

    /**
     * byte[] 转 MultipartFile
     * @param imageBytes
     * @return
     * @throws IOException
     */
    public static MultipartFile toMultipartFile(byte[] imageBytes) throws IOException {
        String filename = UUID.randomUUID().toString();
        return new MultipartFile() {
            @Override
            public String getName() {
                return filename;
            }

            @Override
            public String getOriginalFilename() {
                return filename + ".png";
            }

            @Override
            public String getContentType() {
                // 根据实际情况设置内容类型,例如图片可以设置为"image/jpeg"
                return "image/jpeg";
            }

            @Override
            public boolean isEmpty() {
                return imageBytes == null || imageBytes.length == 0;
            }

            @Override
            public long getSize() {
                return imageBytes.length;
            }

            @Override
            public byte[] getBytes() throws IOException {
                return imageBytes;
            }

            @Override
            public InputStream getInputStream() throws IOException {
                return new ByteArrayInputStream(imageBytes);
            }

            @Override
            public void transferTo(java.io.File dest) throws IOException, IllegalStateException {
                new java.io.FileOutputStream(dest).write(imageBytes);
            }
        };
    }
}

5. 编写接口测试

    @Value("${wxApp.appId}")
    private String appId;

    @Value("${wxApp.appSecret}")
    private String appSecret;

    @Value("${wxApp.envVersion}")
    private String envVersion;

    @Value("${wxApp.uploadPagePath}")
    private String uploadPagePath;


/**
     * 获取微信小程序码
     * @param aiChatQrCodeReq
     * @return
     * @throws IOException
     */
    @ApiOperation(value="获取微信小程序码")
    @PostMapping("/getWxAppQRCode")
    public Result<String> getWxAppQRCode(String text, HttpServletRequest request) throws IOException {
            byte[] imgBytes = wxAppQRCodeUtils.getQRCodeByte(appId, appSecret, uploadPagePath, text, envVersion, false);
            MultipartFile file = ImageFileUtils.toMultipartFile(imgBytes);
            String imgUrl = CommonUtils.upload(file, "upload/aiChat/wxAppQrCode", "alioss");
            return Result.ok(imgUrl);
    }

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值