Commit 9c2bc2b2 by caiyt

修改二维码尺寸生成逻辑、修复扫码后金额为哦的问题

parent c10e3e67
...@@ -74,7 +74,11 @@ public class ApplicationController { ...@@ -74,7 +74,11 @@ public class ApplicationController {
Integer screenNo = redisJson.getInteger("screenNo"); Integer screenNo = redisJson.getInteger("screenNo");
Machine machine = machineService.selectMachineByCode(machineCode); Machine machine = machineService.selectMachineByCode(machineCode);
Shop shop = shopService.selectShopById(machine.getShopId()); Shop shop = shopService.selectShopById(machine.getShopId());
try {
shop.setDistance(DistanceUtil.getDistanceDesc(Double.parseDouble(shop.getLng()), Double.parseDouble(shop.getLat()), Double.parseDouble(location.getString("lng")), Double.parseDouble(location.getString("lat")))); shop.setDistance(DistanceUtil.getDistanceDesc(Double.parseDouble(shop.getLng()), Double.parseDouble(shop.getLat()), Double.parseDouble(location.getString("lng")), Double.parseDouble(location.getString("lat"))));
} catch (NumberFormatException e) {
shop.setDistance("-1");
}
redisJson.put("shop", shop); redisJson.put("shop", shop);
//推送数据给安卓 //推送数据给安卓
JSONObject jgBody = new JSONObject(); JSONObject jgBody = new JSONObject();
......
...@@ -2,199 +2,100 @@ package com.soss.common.utils; ...@@ -2,199 +2,100 @@ package com.soss.common.utils;
import com.google.zxing.BarcodeFormat; import com.google.zxing.BarcodeFormat;
import com.google.zxing.EncodeHintType; import com.google.zxing.EncodeHintType;
import com.google.zxing.MultiFormatWriter;
import com.google.zxing.common.BitMatrix; import com.google.zxing.common.BitMatrix;
import com.google.zxing.qrcode.QRCodeWriter;
import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel; import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel;
import com.soss.common.utils.sign.Base64;
import javax.imageio.ImageIO; import javax.imageio.ImageIO;
import javax.servlet.ServletOutputStream;
import java.awt.*; import java.awt.*;
import java.awt.geom.RoundRectangle2D;
import java.awt.image.BufferedImage; import java.awt.image.BufferedImage;
import java.io.ByteArrayOutputStream; import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException; import java.io.IOException;
import java.io.OutputStream; import java.util.Hashtable;
import java.net.URL;
import java.util.HashMap;
public class QRCodeUtil { public class QRCodeUtil {
/** private static int onColor = 0xFF000000; //前景色
* 默认宽度 private static int offColor = 0xFFFFFFFF; //背景色
*/ private static int margin = 1; //白边大小,取值范围0~4
private static final Integer WIDTH = 140; private static ErrorCorrectionLevel level = ErrorCorrectionLevel.L; //二维码容错率
/**
* 默认高度
*/
private static final Integer HEIGHT = 140;
/**
* LOGO 默认宽度
*/
private static final Integer LOGO_WIDTH = 22;
/**
* LOGO 默认高度
*/
private static final Integer LOGO_HEIGHT = 22;
/**
* 图片格式
*/
private static final String IMAGE_FORMAT = "png";
private static final String CHARSET = "utf-8";
/**
* 原生转码前面没有 data:image/png;base64 这些字段,返回给前端是无法被解析
*/
private static final String BASE64_IMAGE = "data:image/png;base64,%s";
/**
* 生成二维码,使用默认尺寸
*
* @param content 内容
* @return
*/
public static String getBase64QRCode(String content) {
return getBase64Image(content, WIDTH, HEIGHT, null, null, null);
}
/**
* 生成二维码,使用默认尺寸二维码,插入默认尺寸logo
*
* @param content 内容
* @param logoUrl logo地址
* @return
*/
public static String getBase64QRCode(String content, String logoUrl) {
return getBase64Image(content, WIDTH, HEIGHT, logoUrl, LOGO_WIDTH, LOGO_HEIGHT);
}
/** /**
* 生成二维码 * 生成二维码
* *
* @param content 内容 * @param content //二维码内容
* @param width 二维码宽度
* @param height 二维码高度
* @param logoUrl logo 在线地址
* @param logoWidth logo 宽度
* @param logoHeight logo 高度
* @return
*/ */
public static String getBase64QRCode(String content, Integer width, Integer height, String logoUrl, Integer logoWidth, Integer logoHeight) { public static void generateQRImage(String content, String format, ByteArrayOutputStream byteArrayOutputStream, int width, int height) {
return getBase64Image(content, width, height, logoUrl, logoWidth, logoHeight); Hashtable<EncodeHintType, Object> hints = new Hashtable<>();
} // 指定纠错等级
hints.put(EncodeHintType.ERROR_CORRECTION, level);
private static String getBase64Image(String content, Integer width, Integer height, String logoUrl, Integer logoWidth, Integer logoHeight) { // 指定编码格式
ByteArrayOutputStream os = new ByteArrayOutputStream(); hints.put(EncodeHintType.CHARACTER_SET, "UTF-8");
BufferedImage bufferedImage = crateQRCode(content, width, height, logoUrl, logoWidth, logoHeight); hints.put(EncodeHintType.MARGIN, margin); //设置白边
try { try {
ImageIO.write(bufferedImage, IMAGE_FORMAT, os); BitMatrix bitMatrix = new MultiFormatWriter().encode(content, BarcodeFormat.QR_CODE, width, height, hints);
} catch (IOException e) { bitMatrix = deleteWhite(bitMatrix);
BufferedImage image = toBufferedImage(bitMatrix);
// MatrixToImageWriter.writeToStream(bitMatrix, format, byteArrayOutputStream, config);
ImageIO.write(image, format, byteArrayOutputStream); //生成二维码图片
} catch (Exception e) {
e.printStackTrace(); e.printStackTrace();
} }
// 转出即可直接使用
return String.format(BASE64_IMAGE, Base64.encode(os.toByteArray()));
} }
/** /**
* 生成二维码 * @param matrix 二维码矩阵相关
* * @param format 二维码图片格式
* @param content 内容 * @param byteArrayOutputStream 二维码图片文件字节流
* @param width 二维码宽度 * @param logoPath logo路径
* @param height 二维码高度 * @throws IOException
* @param logoUrl logo 在线地址
* @param logoWidth logo 宽度
* @param logoHeight logo 高度
* @return
*/ */
private static BufferedImage crateQRCode(String content, Integer width, Integer height, String logoUrl, Integer logoWidth, Integer logoHeight) { public static void writeToFile(BitMatrix matrix, String format, ByteArrayOutputStream byteArrayOutputStream, String logoPath) throws IOException {
if (StringUtils.isNotBlank(content)) { BufferedImage image = toBufferedImage(matrix);
ServletOutputStream stream = null; //载入logo
HashMap<EncodeHintType, Comparable> hints = new HashMap<>(4); if (StringUtils.isNotEmpty(logoPath)) {
// 指定字符编码为utf-8 int ratioWidth = image.getWidth() * 2 / 10;
hints.put(EncodeHintType.CHARACTER_SET, CHARSET); int ratioHeight = image.getHeight() * 2 / 10;
// 指定二维码的纠错等级为中级 Image img = ImageIO.read(new File(logoPath));
hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.M); int logoWidth = img.getWidth(null) > ratioWidth ? ratioWidth : img.getWidth(null);
// 设置图片的边距 int logoHeight = img.getHeight(null) > ratioHeight ? ratioHeight : img.getHeight(null);
hints.put(EncodeHintType.MARGIN, 2); int x = (image.getWidth() - logoWidth) / 2;
try { int y = (image.getHeight() - logoHeight) / 2;
QRCodeWriter writer = new QRCodeWriter();
BitMatrix bitMatrix = writer.encode(content, BarcodeFormat.QR_CODE, width, height, hints); Graphics2D gs = image.createGraphics();
BufferedImage bufferedImage = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB); gs.drawImage(img, x, y, logoWidth, logoHeight, null);
gs.setColor(Color.black);
gs.setBackground(Color.WHITE);
gs.dispose();
img.flush();
}
ImageIO.write(image, format, byteArrayOutputStream); //生成二维码图片
}
public static BufferedImage toBufferedImage(BitMatrix matrix) {
int width = matrix.getWidth();
int height = matrix.getHeight();
BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
for (int x = 0; x < width; x++) { for (int x = 0; x < width; x++) {
for (int y = 0; y < height; y++) { for (int y = 0; y < height; y++) {
bufferedImage.setRGB(x, y, bitMatrix.get(x, y) ? 0xFF000000 : 0xFFFFFFFF); image.setRGB(x, y, matrix.get(x, y) ? onColor : offColor);
}
}
if (StringUtils.isNotBlank(logoUrl)) {
insertLogo(bufferedImage, width, height, logoUrl, logoWidth, logoHeight);
}
return bufferedImage;
} catch (Exception e) {
e.printStackTrace();
} finally {
if (stream != null) {
try {
stream.flush();
stream.close();
} catch (IOException e) {
e.printStackTrace();
} }
} }
} return image;
}
return null;
} }
/** public static BitMatrix deleteWhite(BitMatrix matrix) {
* 二维码插入logo int[] rec = matrix.getEnclosingRectangle();
* int resWidth = rec[2] + 1;
* @param source 二维码 int resHeight = rec[3] + 1;
* @param width 二维码宽度 BitMatrix resMatrix = new BitMatrix(resWidth, resHeight);
* @param height 二维码高度 resMatrix.clear();
* @param logoUrl logo 在线地址 for (int i = 0; i < resWidth; i++) {
* @param logoWidth logo 宽度 for (int j = 0; j < resHeight; j++) {
* @param logoHeight logo 高度 if (matrix.get(i + rec[0], j + rec[1]))
* @throws Exception resMatrix.set(i, j);
*/
private static void insertLogo(BufferedImage source, Integer width, Integer height, String logoUrl, Integer logoWidth, Integer logoHeight) throws Exception {
// logo 源可为 File/InputStream/URL
Image src = ImageIO.read(new URL(logoUrl));
// 插入LOGO
Graphics2D graph = source.createGraphics();
int x = (width - logoWidth) / 2;
int y = (height - logoHeight) / 2;
graph.drawImage(src, x, y, logoWidth, logoHeight, null);
Shape shape = new RoundRectangle2D.Float(x, y, logoWidth, logoHeight, 6, 6);
graph.setStroke(new BasicStroke(3f));
graph.draw(shape);
graph.dispose();
} }
/**
* 获取二维码
*
* @param content 内容
* @param output 输出流
* @throws IOException
*/
public static void getQRCode(String content, OutputStream output) throws IOException {
BufferedImage image = crateQRCode(content, WIDTH, HEIGHT, null, null, null);
ImageIO.write(image, IMAGE_FORMAT, output);
} }
return resMatrix;
/**
* 获取二维码
*
* @param content 内容
* @param logoUrl logo资源
* @param output 输出流
* @throws Exception
*/
public static void getQRCode(String content, String logoUrl, OutputStream output) throws Exception {
BufferedImage image = crateQRCode(content, WIDTH, HEIGHT, logoUrl, LOGO_WIDTH, LOGO_HEIGHT);
ImageIO.write(image, IMAGE_FORMAT, output);
} }
} }
\ No newline at end of file
...@@ -12,16 +12,13 @@ import com.github.binarywang.wxpay.bean.result.WxPayUnifiedOrderResult; ...@@ -12,16 +12,13 @@ import com.github.binarywang.wxpay.bean.result.WxPayUnifiedOrderResult;
import com.github.binarywang.wxpay.exception.WxPayException; import com.github.binarywang.wxpay.exception.WxPayException;
import com.github.binarywang.wxpay.service.WxPayService; import com.github.binarywang.wxpay.service.WxPayService;
import com.github.wxpay.sdk.WXPayUtil; import com.github.wxpay.sdk.WXPayUtil;
import com.google.zxing.BarcodeFormat;
import com.google.zxing.EncodeHintType;
import com.google.zxing.client.j2se.MatrixToImageWriter;
import com.google.zxing.common.BitMatrix; import com.google.zxing.common.BitMatrix;
import com.google.zxing.qrcode.QRCodeWriter;
import com.soss.common.core.domain.entity.SysUser; import com.soss.common.core.domain.entity.SysUser;
import com.soss.common.core.domain.model.LoginUser; import com.soss.common.core.domain.model.LoginUser;
import com.soss.common.enums.RefundState; import com.soss.common.enums.RefundState;
import com.soss.common.enums.ShopState; import com.soss.common.enums.ShopState;
import com.soss.common.exception.ServiceException; import com.soss.common.exception.ServiceException;
import com.soss.common.utils.QRCodeUtil;
import com.soss.common.utils.StringUtils; import com.soss.common.utils.StringUtils;
import com.soss.common.utils.ip.IpUtils; import com.soss.common.utils.ip.IpUtils;
import com.soss.common.utils.sign.Base64; import com.soss.common.utils.sign.Base64;
...@@ -57,6 +54,8 @@ import javax.crypto.Cipher; ...@@ -57,6 +54,8 @@ import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec; import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec; import javax.crypto.spec.SecretKeySpec;
import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequest;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.BufferedReader; import java.io.BufferedReader;
import java.io.ByteArrayInputStream; import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream; import java.io.ByteArrayOutputStream;
...@@ -65,6 +64,7 @@ import java.math.BigDecimal; ...@@ -65,6 +64,7 @@ import java.math.BigDecimal;
import java.net.InetAddress; import java.net.InetAddress;
import java.nio.charset.StandardCharsets; import java.nio.charset.StandardCharsets;
import java.security.spec.AlgorithmParameterSpec; import java.security.spec.AlgorithmParameterSpec;
import java.util.List;
import java.util.*; import java.util.*;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.ReentrantLock; import java.util.concurrent.locks.ReentrantLock;
...@@ -390,17 +390,6 @@ public class WeixinServiceImpl { ...@@ -390,17 +390,6 @@ public class WeixinServiceImpl {
//获取商户订单号 //获取商户订单号
String orderNo = notifyMap.get("out_trade_no"); String orderNo = notifyMap.get("out_trade_no");
Order order = new Order();
order.setOrderNo(orderNo);
List<Order> orders = orderService.selectOrderList(order);
if(orders.isEmpty()){
returnMap.put("return_code", "FAIL");
returnMap.put("return_msg", "没有该订单");
String returnXml = WXPayUtil.mapToXml(returnMap);
return returnXml;
}
order = orders.get(0);
//并校验返回的订单金额是否与商户侧的订单金额一致 //并校验返回的订单金额是否与商户侧的订单金额一致
// if (order1 != null && order1.get() != Long.parseLong(notifyMap.get("total_fee"))) { // if (order1 != null && order1.get() != Long.parseLong(notifyMap.get("total_fee"))) {
// log.error("金额校验失败"); // log.error("金额校验失败");
...@@ -412,11 +401,21 @@ public class WeixinServiceImpl { ...@@ -412,11 +401,21 @@ public class WeixinServiceImpl {
// } // }
//处理订单 //处理订单
if(lock.tryLock()){ if(lock.tryLock()) {
Order order = new Order();
order.setOrderNo(orderNo);
List<Order> orders = orderService.selectOrderList(order);
if (orders.isEmpty()) {
returnMap.put("return_code", "FAIL");
returnMap.put("return_msg", "没有该订单");
return WXPayUtil.mapToXml(returnMap);
}
order = orders.get(0);
try { try {
//处理重复的通知 //处理重复的通知
//接口调用的幂等性:无论接口被调用多少次,产生的结果是一致的。 //接口调用的幂等性:无论接口被调用多少次,产生的结果是一致的。
String orderStatus =order.getState(); String orderStatus = order.getState();
log.info("order current status: {}", orderStatus);
if (OrderStatusConstant.Unpaid.equals(orderStatus)) { if (OrderStatusConstant.Unpaid.equals(orderStatus)) {
//更新订单状态 //更新订单状态
order.setPayTime(new Date()); order.setPayTime(new Date());
...@@ -801,20 +800,15 @@ public class WeixinServiceImpl { ...@@ -801,20 +800,15 @@ public class WeixinServiceImpl {
} }
public String generateMiniQr(String content) { public String generateMiniQr(String content) {
QRCodeWriter qrCodeWriter = new QRCodeWriter();
// 解决中文乱码
HashMap<EncodeHintType, Object> hints = new HashMap<>(16);
hints.put(EncodeHintType.CHARACTER_SET, "utf-8");
String fileName = System.currentTimeMillis() + ".png"; String fileName = System.currentTimeMillis() + ".png";
try { try {
String[] qrSizeArr = qrSize.split("\\*"); String[] qrSizeArr = qrSize.split("\\*");
int width = Integer.parseInt(qrSizeArr[0]); int width = Integer.parseInt(qrSizeArr[0]);
int height = Integer.parseInt(qrSizeArr[1]); int height = Integer.parseInt(qrSizeArr[1]);
log.info("qr with: {} height: {}", width, height); log.info("qr with: {} height: {}", width, height);
BitMatrix bitMatrix = qrCodeWriter.encode(content, BarcodeFormat.QR_CODE, width, height, hints);
bitMatrix = deleteWhite(bitMatrix);
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream(); ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
MatrixToImageWriter.writeToStream(bitMatrix, "PNG", byteArrayOutputStream); QRCodeUtil.generateQRImage(content, "PNG", byteArrayOutputStream, width, height);
// MatrixToImageWriter.writeToStream(bitMatrix, "PNG", byteArrayOutputStream);
return ossFileService.uploadFile(new ByteArrayInputStream(byteArrayOutputStream.toByteArray()), fileName); return ossFileService.uploadFile(new ByteArrayInputStream(byteArrayOutputStream.toByteArray()), fileName);
} catch (Exception e) { } catch (Exception e) {
log.error("生成二维码失败:{}", e.getMessage(), e); log.error("生成二维码失败:{}", e.getMessage(), e);
...@@ -823,6 +817,17 @@ public class WeixinServiceImpl { ...@@ -823,6 +817,17 @@ public class WeixinServiceImpl {
} }
/** /**
* 图片放大缩小
*/
public static BufferedImage zoomInImage(BufferedImage originalImage, int width, int height) {
BufferedImage newImage = new BufferedImage(width, height, originalImage.getType());
Graphics g = newImage.getGraphics();
g.drawImage(originalImage, 0, 0, width, height, null);
g.dispose();
return newImage;
}
/**
* 删除白边 * 删除白边
*/ */
private BitMatrix deleteWhite(BitMatrix matrix) { private BitMatrix deleteWhite(BitMatrix matrix) {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment