shikeyin
2024-01-11 65da8373531677b1c37a98f53eaa30c892f35e5a
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
package com.ishop.mobile.api;
 
import com.fasterxml.jackson.databind.node.ObjectNode;
import com.iplatform.base.PlatformRuntimeException;
import com.iplatform.base.WechatConstants;
import com.iplatform.base.util.VerifyImgUtil;
import com.iplatform.core.BeanContextAware;
import com.ishop.mobile.BaseApi;
import com.ishop.mobile.util.WechatUtils;
import com.ishop.model.vo.QrCodeVo;
import com.walker.infrastructure.utils.Base64;
import com.walker.infrastructure.utils.FileCopyUtils;
import com.walker.infrastructure.utils.StringUtils;
import com.walker.web.ResponseValue;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;
 
import java.io.File;
import java.text.MessageFormat;
import java.util.HashMap;
import java.util.Map;
 
@RestController
@RequestMapping("/front/qrcode")
public class QrcodeApi extends BaseApi {
 
    @RequestMapping(value = "/get/wechat", method = RequestMethod.POST)
    public ResponseValue getWechatQrCode(@RequestBody Map<String, Object> data){
        if(data == null || data.size() == 0){
            return ResponseValue.error("请输入二维码参数");
        }
        StringBuilder scene = new StringBuilder();
        String page = StringUtils.EMPTY_STRING;
        try {
            for (Map.Entry<String, Object> m : data.entrySet()) {
                if (m.getKey().equals("path")) {
                    //前端路由, 不需要拼参数
                    page = m.getValue().toString();
                    continue;
                }
                if (scene.length() > 0) {
                    scene.append(StringUtils.DEFAULT_SPLIT_SEPARATOR);
                }
                // 2023-09-17 由于微信对于scene限制32位字符,所以只把json中value用逗号拼接,降低长度。取的时候也按字段顺序取。
//                scene.append(m.getKey()).append(StringUtils.SEPARATOR_COLON).append(m.getValue());
                scene.append(m.getValue());
            }
        } catch (PlatformRuntimeException ex){
            logger.error("生成二维码参数错误:" + data, ex);
            return ResponseValue.error(ex.getMessage());
        }
 
        QrCodeVo vo = new QrCodeVo();
        String imageBase64 = this.createQrCode(page, scene.length() > 0 ? scene.toString() : StringUtils.EMPTY_STRING);
        vo.setCode(imageBase64);
        return ResponseValue.success(vo);
    }
 
    /**
     * 获取小程序图片二维码Base64内容。
     * @param page
     * @param scene
     * @return
     * @date 2023-09-17
     */
    private String createQrCode(String page, String scene){
        logger.debug("page = {}, scene = {}", page, scene);
        String miniAccessToken = this.acquireMiniAccessToken();
        String url = MessageFormat.format(WechatConstants.WECHAT_MINI_QRCODE_UNLIMITED_URL, miniAccessToken);
        HashMap<String, Object> map = new HashMap<>();
        map.put("scene", scene);
//        map.put("page", page);
        map.put("path", page);
        map.put("width", 200);
        RestTemplate restTemplate = BeanContextAware.getBeanByType(RestTemplate.class);
 
 
        byte[] bytes = restTemplate.postForEntity(url, map, byte[].class).getBody();
        if(bytes == null || bytes.length == 0){
            throw new PlatformRuntimeException("微信平台接口异常(createQrCode),没任何数据返回!");
        }
        String entity = new String(bytes);
        if(entity.indexOf("errcode") >= 0){
            ObjectNode data = WechatUtils.acquireObjectNode(entity);
            if (data.get("errcode").asText().equals("40001")) {
                logger.warn("小程序已获取accessToken失效,需要重新调用接口,error = {}", data);
                this.getWechatCache().removeMiniAccessToken();
                miniAccessToken = this.acquireMiniAccessToken();
                url = MessageFormat.format(WechatConstants.WECHAT_MINI_QRCODE_UNLIMITED_URL, miniAccessToken);
                bytes = restTemplate.postForEntity(url, map, byte[].class).getBody();
                entity = new String(bytes);
                if(entity.indexOf("errcode") >= 0){
                    logger.error("微信生成小程序码重试异常:" + entity);
//                    JSONObject data2 = JSONObject.parseObject(response);
                    // 保存到微信异常表
//                    wxExceptionDispose(data2, "微信小程序重试生成小程序码异常");
                } else {
                    return VerifyImgUtil.getBase64Image(new String(Base64.encodeBase64(bytes)));
                }
            }
            throw new PlatformRuntimeException("微信生成二维码异常:" + entity);
        }
        try {
//            return CrmebUtil.getBase64Image(org.apache.commons.codec.binary.Base64.encodeBase64String(bytes));
//            FileCopyUtils.copy(bytes, new File("e:/demo.png"));
            return VerifyImgUtil.getBase64Image(new String(Base64.encodeBase64(bytes)));
//            return VerifyImgUtil.getBase64Image(org.apache.commons.codec.binary.Base64.encodeBase64String(bytes));
        } catch (Exception e) {
            e.printStackTrace();
            throw new PlatformRuntimeException("微信小程序码转换Base64异常");
        }
    }
 
    /**
     * 远程图片转base64
     * @param url
     * @return
     * @date 2023-07-09
     */
    @RequestMapping(value = "/url/to/base64", method = RequestMethod.POST)
    public ResponseValue urlToBase64(String url){
        if(StringUtils.isEmpty(url)){
            return ResponseValue.error("url为空,无法转换");
        }
        logger.debug("...........url = " + url);
        if(!StringUtils.isHttpLink(url)){
            url = this.getCdnUrl() + url;
        }
        return ResponseValue.success(this.getQrcodeService().urlToBase64(url));
    }
}