提交 70787f41 authored 作者: zjm's avatar zjm

合并分支 'bug' 到 'master'

fix(装备模块,RFID模块): 解决了库房位置出现了两条,新增了条码打印的接口 查看合并请求 !74
......@@ -1151,10 +1151,11 @@ public class DeviceLibraryServiceImpl implements DeviceLibraryService {
if (!CollectionUtils.isEmpty(deviceIds)){
//添加装备日志
deviceIds.forEach(integer -> {
DeviceLogDto deviceLogDto= new DeviceLogDto(integer,"将存放位置修改为"+
updateStorageLocationVo.getStorageLocation(),null,userId);
deviceLogDtos.add(deviceLogDto);
});
if (!updateStorageLocationVo.getStorageLocation().equals(getOne(integer).getStorageLocation())){
DeviceLogDto deviceLogDto= new DeviceLogDto(integer,"将存放位置修改为"+
updateStorageLocationVo.getStorageLocation(),null,userId);
deviceLogDtos.add(deviceLogDto);
}});
deviceLibraryDao.updateStorageLocation(updateStorageLocationVo.getStorageLocation(),deviceIds);
}else {
throw new ApiException("请选择要修改的装备");
......
......@@ -100,6 +100,17 @@
<groupId>com.tykj.dev</groupId>
<artifactId>blockcha</artifactId>
</dependency>
<dependency>
<groupId>com.google.zxing</groupId>
<artifactId>core</artifactId>
<version>3.3.3</version>
</dependency>
<dependency>
<groupId>com.google.zxing</groupId>
<artifactId>javase</artifactId>
<version>3.3.3</version>
</dependency>
</dependencies>
</project>
package com.tykj.dev.rfid.entity.vo;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
/**
* @author zsp
*/
@Data
@ApiModel("条码打印机,打印VO")
public class QRCodePrintVo {
@ApiModelProperty(name = "装备的id")
private Integer deviceId;
@ApiModelProperty(name = "型号")
private String model;
@ApiModelProperty(name = "名称")
private String name;
@ApiModelProperty(name = "序列号")
private String seqNumber;
}
package com.tykj.dev.rfid.service;
import com.tykj.dev.rfid.entity.vo.PrintVo;
import com.tykj.dev.rfid.entity.vo.QRCodePrintVo;
import com.tykj.dev.rfid.entity.vo.RfidCreateVo;
import com.tykj.dev.rfid.entity.vo.RfidPrintVo;
......@@ -52,4 +53,9 @@ public interface RfidService {
*/
List<RfidPrintVo> getRfidNumber(List<RfidCreateVo> list);
/**
* 条码打印机 批量打印
*/
void printByQRcode(List<QRCodePrintVo> qrCodePrintVos);
}
......@@ -4,11 +4,11 @@ import com.tykj.dev.device.library.service.DeviceLibraryService;
import com.tykj.dev.device.library.subject.domin.DeviceLibrary;
import com.tykj.dev.misc.exception.ApiException;
import com.tykj.dev.misc.utils.ResultUtil;
import com.tykj.dev.rfid.entity.vo.PrintVo;
import com.tykj.dev.rfid.entity.vo.RfidCreateVo;
import com.tykj.dev.rfid.entity.vo.RfidPrintVo;
import com.tykj.dev.rfid.entity.vo.SplitStringInfo;
import com.tykj.dev.rfid.entity.vo.*;
import com.tykj.dev.rfid.service.RfidService;
import com.tykj.dev.rfid.utils.DrawImageUtil;
import com.tykj.dev.rfid.utils.Image2Zpl;
import com.tykj.dev.rfid.utils.PrinterUtil;
import com.zebra.sdk.comm.Connection;
import com.zebra.sdk.comm.ConnectionException;
import com.zebra.sdk.comm.TcpConnection;
......@@ -22,6 +22,7 @@ import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
......@@ -92,6 +93,7 @@ public class RfidServiceImpl implements RfidService {
}
try {
Connection connection = new TcpConnection("10.153.4.16", 6101);
// Connection connection = new TcpConnection("192.168.101.100", 9100);
connection.open();
for (PrintVo printVo : printVos) {
printer = ZebraPrinterFactory.getInstance(connection);
......@@ -312,6 +314,18 @@ public class RfidServiceImpl implements RfidService {
return rfidPrintVos;
}
@Override
public void printByQRcode(List<QRCodePrintVo> qrCodePrintVos) {
if (!qrCodePrintVos.isEmpty()){
throw new ApiException("打印列表为空");
}
qrCodePrintVos.forEach(qrCodePrintVo ->{
BufferedImage bufferedImage = DrawImageUtil.drawImage(qrCodePrintVo.getDeviceId(),
qrCodePrintVo.getModel(),qrCodePrintVo.getName(),qrCodePrintVo.getSeqNumber());
PrinterUtil.execute(Image2Zpl.image2Zpl(bufferedImage));
});
}
/**
* 描述:生成装备的RFID表面号
*
......
package com.tykj.dev.rfid.utils;
import com.google.zxing.*;
import com.google.zxing.client.j2se.BufferedImageLuminanceSource;
import com.google.zxing.client.j2se.MatrixToImageWriter;
import com.google.zxing.common.BitMatrix;
import com.google.zxing.common.HybridBinarizer;
import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel;
import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.io.OutputStream;
import java.util.HashMap;
import java.util.Map;
/**
* 条形码生成工具
*/
public class BarCodeUtil {
/**
* 保存格式
*/
private static String format = "png";
/**
* 生成条形码图片文件
*/
public static void createBarCodeImgFile(String text, Integer width, Integer height, String barPath) {
try {
Map<EncodeHintType, Object> hints = getDecodeHintType();
BitMatrix bitMatrix = new MultiFormatWriter().encode(text, BarcodeFormat.CODE_128, width, height, hints);
File file = new File(barPath);
BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
ImageIO.write(image, format, file);
MatrixToImageWriter.writeToFile(bitMatrix, format, file);
} catch (WriterException | IOException e) {
e.printStackTrace();
}
}
/**
* 生成条形码图片对象
*/
public static BufferedImage createBarCodeImg(String text, Integer width, Integer height) {
try {
Map<EncodeHintType, Object> hints = getDecodeHintType();
BitMatrix bitMatrix = new MultiFormatWriter().encode(text, BarcodeFormat.CODE_128, width, height, hints);
BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
for (int x = 0; x < width; x++) {
for (int y = 0; y < height; y++) {
image.setRGB(x, y, rgb(bitMatrix.get(x, y)));
}
}
return image;
} catch (WriterException e) {
e.printStackTrace();
}
return null;
}
/**
* 生成条形码输出流
*/
private static void createBarCode(String text, Integer width, Integer height, OutputStream out) {
try {
Map<EncodeHintType, Object> hints = getDecodeHintType();
BitMatrix bitMatrix = new MultiFormatWriter().encode(text, BarcodeFormat.CODE_128, width, height, hints);
MatrixToImageWriter.writeToStream(bitMatrix, format, out);
} catch (WriterException | IOException e) {
e.printStackTrace();
}
}
/**
* 针对条形码进行解析
*/
public static String decodeBar(String imgPath) {
BufferedImage image;
Result result;
try {
image = ImageIO.read(new File(imgPath));
if (image == null) {
System.out.println("the decode image may be not exit.");
}
LuminanceSource source = new BufferedImageLuminanceSource(image);
BinaryBitmap bitmap = new BinaryBitmap(new HybridBinarizer(source));
result = new MultiFormatReader().decode(bitmap, null);
System.out.println(result.getText());
return result.getText();
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
/**
* 二维码的格式参数
*/
private static Map<EncodeHintType, Object> getDecodeHintType() {
// 用于设置QR二维码参数
Map<EncodeHintType, Object> hints = new HashMap<>();
//设置QR二维码的纠错级别(H为最高级别)具体级别信息
//二维码容错率 L = ~7% /M = ~15% /Q = ~25% /H = ~30% 容错率越高,二维码的有效像素点就越多
hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.L);
//白边大小,取值范围0~4
Integer margin = 1;
hints.put(EncodeHintType.MARGIN, margin);
// 设置编码方式
hints.put(EncodeHintType.CHARACTER_SET, "utf-8");
return hints;
}
private static Integer rgb(boolean point) {
return point ? 0 : 16777215;
}
}
package com.tykj.dev.rfid.utils;
import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
/**
* 完整标签生成工具
*/
public class DrawImageUtil {
private static Integer width = 300;
private static Integer height = 200;
public static BufferedImage drawImage(Integer id, String string1, String string2, String string3) {
//创建图片对象
BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
//基于图片对象打开绘图
Graphics2D graphics = image.createGraphics();
//绘图逻辑 START (基于业务逻辑进行绘图处理)
graphics.setBackground(Color.WHITE);
graphics.setColor(Color.BLACK);
graphics.clearRect(0, 0, width, height);
//偏移量
int offsetX = 20;
int offsetY = 40;
//留白率 例如40就是留白1/40
int blankRange = 40;
//计算条形码尺寸
Integer barCodeWidth = width - (width / blankRange) * 2;//320
Integer barCodeHeight = (height - offsetY) / 5;//32
//计算字体尺寸
int fontSize = Math.min(((height - offsetY) / 5), (width - width / blankRange - offsetX) / maxLength(string1, string2, string3));
graphics.setFont(new Font("Default", Font.BOLD, fontSize));
//写入条形码
graphics.drawImage(BarCodeUtil.createBarCodeImg(String.valueOf(id), barCodeWidth, barCodeHeight), null, width / blankRange, offsetY + height / blankRange);
//写入字体
graphics.drawString(string1, offsetX + width / blankRange, barCodeHeight + offsetY + (fontSize + fontSize / 10));
graphics.drawString(string2, offsetX + width / blankRange, barCodeHeight + offsetY + 2 * (fontSize + fontSize / 10));
graphics.drawString(string3, offsetX + width / blankRange, barCodeHeight + offsetY + 3 * (fontSize + fontSize / 10));
image.flush();
return image;
}
public static void writeImage(BufferedImage bufferedImage, String path) {
try {
ImageIO.write(bufferedImage, "png", new File(path));
} catch (IOException e) {
e.printStackTrace();
}
}
private static int maxLength(String string1, String string2, String string3) {
int max;
max = string1.length();
if (string2.length() > string1.length()) {
max = string2.length();
}
if (string3.length() > string2.length()) {
max = string3.length();
}
return max;
}
}
package com.tykj.dev.rfid.utils;
import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.awt.image.DataBufferByte;
import java.io.File;
import java.io.IOException;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
* 转换器工具:将图片对象转换为ZPL码 用于打印
*
* 在 erp中单独使用
* 实现思路:
* 1、获取图片的二值化字节数组 这一步是关键
* 2、将字节数组转为十六进制
* 3、压缩十六进制字符串 结尾为1、0或者与上一行相同的;相同的连续字符压缩
* 4、拼凑ZPL编码,宽度需要扩大,因为需要时8个点(1字节)的整数倍
* Created by guzy on 17/11/12.
*/
public class Image2Zpl {
static Pattern ZEROS = Pattern.compile("0+$"), ONES = Pattern.compile("1+$"), MULTI_W = Pattern.compile("([0-9A-Z])\\1{2,}");
public static void main(String[] args) throws IOException {
BufferedImage read = ImageIO.read(new File("test.png"));
System.out.println(image2Zpl(read));
}
public static String image2Zpl(BufferedImage image) {
//获取图片的字节数组
DataBufferByte data = (DataBufferByte) getBinaryGrayImage(image).getRaster().getDataBuffer();
byte[] imgData = data.getData();
int newW = (image.getWidth() + 7) / 8;//实际每行字节大小,8个点,每个点1位,共8位
String[] strs = byte2HexStr(imgData, newW);
int bytes = imgData.length;
return String.format("^XA^GFA,%d,%d,%d,%s^FS^XZ", bytes, bytes, newW, compress(strs));
}
/**
* 获取二值化图,并取反
*
* @param srcImage
* @return
*/
private static BufferedImage getBinaryGrayImage(BufferedImage srcImage) {
BufferedImage dstImage = new BufferedImage(srcImage.getWidth(), srcImage.getHeight(), BufferedImage.TYPE_BYTE_BINARY);
dstImage.getGraphics().drawImage(srcImage, 0, 0, null);
for (int y = 0; y < dstImage.getHeight(); y++) {
for (int x = 0; x < dstImage.getWidth(); x++) {
Color color = new Color(dstImage.getRGB(x, y));
//获取该点的像素的RGB的颜色
Color newColor = new Color(255 - color.getRed(), 255 - color.getGreen(), 255 - color.getBlue());
dstImage.setRGB(x, y, newColor.getRGB());
}
}
return dstImage;
}
/**
* 压缩图片数据
*
* @param data
* @return
*/
private static String compress(String[] data) {
StringBuilder sb = new StringBuilder();
String pre = null;
for (String d : data) {
String a = d;
Matcher m = ZEROS.matcher(a);
if (m.find()) {
a = m.replaceFirst(",");
}
m = ONES.matcher(a);
if (m.find()) {
a = m.replaceFirst("!");
}
a = minimizeSameWord(a);
if (pre != null && a.equals(pre)) {
a = ":";
} else {
pre = a;
}
sb.append(a);
}
return sb.toString();
}
/**
* 十六进制串中相同字母压缩
*
* @param str
* @return
*/
private static String minimizeSameWord(String str) {
Matcher matcher = MULTI_W.matcher(str);
while (matcher.find()) {
String group = matcher.group();
int len = group.length();
String c = "";
if (len > 20) {
c = Character.toString((char) ('f' + len / 20));
}
if (len % 20 > 0) {
c = c + Character.toString((char) ('F' + len % 20));
}
str = str.replaceFirst(group, c + group.charAt(0));
}
return str;
}
/**
* 字节数组转为十六进制
*
* @param b
* @param rowSize
* @return
*/
private static String[] byte2HexStr(byte[] b, int rowSize) {
int len = b.length / rowSize;
String[] arr = new String[len];
for (int n = 0; n < len; n++) {
StringBuffer hs = new StringBuffer();
for (int j = 0; j < rowSize; j++) {
String stmp = Integer.toHexString(b[n * rowSize + j] & 0XFF);
if (stmp.length() == 1) hs.append("0");
hs.append(stmp);
}
arr[n] = hs.toString().toUpperCase();
}
return arr;
}
}
package com.tykj.dev.rfid.utils;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.InetSocketAddress;
import java.net.Socket;
import static java.util.Objects.isNull;
import static java.util.Objects.nonNull;
/**
* 打印机工具 调用打印机并传输ZPL码 打印图片
*/
public class PrinterUtil {
private static String address = "192.168.101.100";
private static int portNumber = 9100;
private static Socket socket = null;
private static PrintWriter printWriter;
private static BufferedReader bufferedReader;
private static void connect() {
if (isNull(socket)) {
try {
socket = new Socket(address, portNumber);
} catch (IOException e) {
e.printStackTrace();
}
}
if (nonNull(socket) && !socket.isConnected()) {
try {
socket.connect(new InetSocketAddress(address, portNumber));
} catch (IOException e) {
e.printStackTrace();
}
}
}
public static void execute(String code) {
connect();
try {
bufferedReader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
printWriter = new PrintWriter(socket.getOutputStream());
printWriter.println(
code
);
printWriter.flush();
} catch (IOException e) {
e.printStackTrace();
}
}
public static void close() {
if (nonNull(socket)) {
try {
socket.close();
printWriter.close();
bufferedReader.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论