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));
|
}
|
}
|