diff --git a/lab-service-api/lab-lims-api/src/main/java/org/springblade/lims/capital/entity/ProductStoreDetial.java b/lab-service-api/lab-lims-api/src/main/java/org/springblade/lims/capital/entity/ProductStoreDetial.java index eccb58b..a26fdf1 100644 --- a/lab-service-api/lab-lims-api/src/main/java/org/springblade/lims/capital/entity/ProductStoreDetial.java +++ b/lab-service-api/lab-lims-api/src/main/java/org/springblade/lims/capital/entity/ProductStoreDetial.java @@ -64,5 +64,9 @@ public class ProductStoreDetial extends BaseEntity { @ApiModelProperty(value = "处理内容") private String content; + private Long goodsId; + + private Integer pNum; + } diff --git a/lab-service-api/lab-lims-api/src/main/java/org/springblade/lims/entry/DetermineFormula.java b/lab-service-api/lab-lims-api/src/main/java/org/springblade/lims/entry/DetermineFormula.java index b31b7d9..2d6c9e3 100644 --- a/lab-service-api/lab-lims-api/src/main/java/org/springblade/lims/entry/DetermineFormula.java +++ b/lab-service-api/lab-lims-api/src/main/java/org/springblade/lims/entry/DetermineFormula.java @@ -8,6 +8,7 @@ import org.springblade.core.mp.base.BaseEntity; import org.springframework.data.annotation.Id; import java.io.Serializable; +import java.util.Map; /** * @author swj @@ -33,5 +34,7 @@ public class DetermineFormula extends BaseEntity implements Serializable { private static final long serialVersionUID = 1L; + private Map map; + } diff --git a/lab-service/lab-capital/src/main/java/org/springblade/lims/goods/controller/ApplyController.java b/lab-service/lab-capital/src/main/java/org/springblade/lims/goods/controller/ApplyController.java index 5a80e7d..d0f3ae4 100644 --- a/lab-service/lab-capital/src/main/java/org/springblade/lims/goods/controller/ApplyController.java +++ b/lab-service/lab-capital/src/main/java/org/springblade/lims/goods/controller/ApplyController.java @@ -385,6 +385,14 @@ public class ApplyController extends BladeController { goods.setNum(goods.getNum() + detail.getReturnNum()); goodsService.updateById(goods); + //批次数量回填 + LambdaQueryWrapper wrapper = new LambdaQueryWrapper<>(); + wrapper.eq(ProductStoreDetial::getGoodsId, detail.getProductId()) + .eq(ProductStoreDetial::getPNum, detail.getBatchNum()); + ProductStoreDetial productStoreDetail = productStoreDetialService.getOne(wrapper); + productStoreDetail.setNum(productStoreDetail.getNum() + detail.getReturnNum()); + productStoreDetialService.updateById(productStoreDetail); + if (detail.getIsReturn() != 1) { ApplyDetail byId = applyDetailService.getById(detail.getId()); if (byId != null) { diff --git a/lab-service/lab-file/src/main/java/org/springblade/file/controller/QualityFileAssistentController.java b/lab-service/lab-file/src/main/java/org/springblade/file/controller/QualityFileAssistentController.java index 8d70958..7f13a20 100644 --- a/lab-service/lab-file/src/main/java/org/springblade/file/controller/QualityFileAssistentController.java +++ b/lab-service/lab-file/src/main/java/org/springblade/file/controller/QualityFileAssistentController.java @@ -34,6 +34,6 @@ public class QualityFileAssistentController extends BladeController { @DeleteMapping("/delete") public R delete(QualityFileAssistent file){ - return R.data(qualityFileAssistentService.removeById(file)); + return R.data(qualityFileAssistentService.deleteById(file.getId())); } } diff --git a/lab-service/lab-file/src/main/java/org/springblade/file/service/IQualityFileAssistentService.java b/lab-service/lab-file/src/main/java/org/springblade/file/service/IQualityFileAssistentService.java index b9b0300..394c171 100644 --- a/lab-service/lab-file/src/main/java/org/springblade/file/service/IQualityFileAssistentService.java +++ b/lab-service/lab-file/src/main/java/org/springblade/file/service/IQualityFileAssistentService.java @@ -9,4 +9,6 @@ import org.springblade.core.mp.base.BaseService; */ public interface IQualityFileAssistentService extends BaseService { boolean addOrUpdate(QualityFileAssistent file); + + boolean deleteById(Long id); } diff --git a/lab-service/lab-file/src/main/java/org/springblade/file/service/impl/QualityFileAssistentServiceImpl.java b/lab-service/lab-file/src/main/java/org/springblade/file/service/impl/QualityFileAssistentServiceImpl.java index 0bf399b..26bbad3 100644 --- a/lab-service/lab-file/src/main/java/org/springblade/file/service/impl/QualityFileAssistentServiceImpl.java +++ b/lab-service/lab-file/src/main/java/org/springblade/file/service/impl/QualityFileAssistentServiceImpl.java @@ -1,10 +1,17 @@ package org.springblade.file.service.impl; +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import lombok.AllArgsConstructor; +import org.checkerframework.checker.units.qual.A; import org.springblade.core.mp.base.BaseServiceImpl; import org.springblade.file.entity.QualityFileAssistent; +import org.springblade.file.entity.QualityStorageFileRel; import org.springblade.file.mapper.QualityFileAssistentMapper; import org.springblade.file.service.IQualityFileAssistentService; +import org.springblade.file.service.IQualityStorageFileRelService; +import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; /** * @Description @@ -12,7 +19,11 @@ import org.springframework.stereotype.Service; * @Date 2022/9/22 0022 18:16 */ @Service +@AllArgsConstructor public class QualityFileAssistentServiceImpl extends BaseServiceImpl implements IQualityFileAssistentService { + + private final IQualityStorageFileRelService qualityStorageFileRelService; + @Override public boolean addOrUpdate(QualityFileAssistent file) { @@ -23,4 +34,22 @@ public class QualityFileAssistentServiceImpl extends BaseServiceImpl ass = new LambdaQueryWrapper<>(); + ass.eq(QualityStorageFileRel::getQualityFileAssistantId , id); + boolean remove = qualityStorageFileRelService.remove(ass); + if(remove){ + return true; + }else{ + return false; + } + } + return b; + } + } diff --git a/lab-service/lab-lims/src/main/java/org/springblade/lims/controller/EntrustController.java b/lab-service/lab-lims/src/main/java/org/springblade/lims/controller/EntrustController.java index 2e782bd..6044099 100644 --- a/lab-service/lab-lims/src/main/java/org/springblade/lims/controller/EntrustController.java +++ b/lab-service/lab-lims/src/main/java/org/springblade/lims/controller/EntrustController.java @@ -23,6 +23,7 @@ import io.swagger.annotations.ApiOperation; import oracle.jdbc.proxy.annotation.Post; import org.apache.poi.ss.usermodel.Workbook; import org.apache.poi.xwpf.usermodel.XWPFDocument; +import org.springblade.common.utils.ZipCompressUtil; import org.springblade.core.secure.utils.AuthUtil; import org.springblade.lims.entry.*; import org.springblade.lims.service.*; @@ -34,12 +35,15 @@ import org.springblade.core.tool.api.R; import org.springblade.lims.service.impl.EntrustCustomerServiceImpl; import org.springblade.resource.enums.SysTypeEnum; import org.springblade.resource.feign.IMessageClient; +import org.springblade.system.cache.DictBizCache; +import org.springblade.system.enums.DictBizEnum; import org.springblade.system.feign.ISysClient; import org.springblade.system.user.entity.User; import org.springblade.system.user.feign.IUserClient; import org.springframework.web.bind.annotation.*; import javax.imageio.ImageIO; +import javax.servlet.ServletOutputStream; import javax.servlet.http.HttpServletResponse; import java.awt.*; import java.awt.image.BufferedImage; @@ -1682,9 +1686,8 @@ public class EntrustController extends BladeController { * 24.二维码生成 */ @GetMapping("/QrcodeUtils") - public void QrcodeUtils(String content) throws Exception { + public void QrcodeUtils(String content , HttpServletResponse response) throws Exception { BufferedImage img = QrcodeUtils.generateQRCodeImage(content, 400, ClassLoader.getSystemResourceAsStream("logo.png")); - // File outFile = Files.createTempFile("qrcode_with_logo_", ".png").toFile(); Map result = new HashMap<>(); ImageEntity farView = new ImageEntity(); @@ -1694,34 +1697,38 @@ public class EntrustController extends BladeController { FileInputStream fis = null; try { -// fis = new FileInputStream(new File(s1)); -// byte[] bytes = readInputStream(fis); ByteArrayOutputStream bos = new ByteArrayOutputStream(); ImageIO.write(img, "png",bos ); byte[] bytes = bos.toByteArray(); farView.setData(bytes); - //farView.setData(bytes); } catch (Exception e) { e.printStackTrace(); } result.put("img", farView); - //ImageIO.write(img, "png", outFile); - // Desktop.getDesktop().open(outFile); - } - /** - * 读输入流 - */ - private static byte[] readInputStream(InputStream inStream) throws Exception { - ByteArrayOutputStream outStream = new ByteArrayOutputStream(); - byte[] buffer = new byte[1024]; - int len = 0; - while ((len = inStream.read(buffer)) != -1) { - outStream.write(buffer, 0, len); + String url = DictBizCache.getKey(DictBizEnum.PRINT_URL.getName(), "imagePrint"); + XWPFDocument doc = null; + try { + doc = WordExportUtil.exportWord07(url, result); + String filename = "二维码.docx"; + + response.setContentType("application/octet-stream"); + response.setHeader("content-disposition", "attachment;filename=二维码.docx"); + + doc.write(response.getOutputStream()); + } catch (Exception e) { + e.printStackTrace(); + } finally { + if (null != doc) { + try { + doc.close(); + } catch (IOException e) { + e.printStackTrace(); + } + } } - inStream.close(); - return outStream.toByteArray(); } + /** * 24.获取委托单 */ diff --git a/lab-service/lab-lims/src/main/java/org/springblade/lims/service/impl/EntrustServiceImpl.java b/lab-service/lab-lims/src/main/java/org/springblade/lims/service/impl/EntrustServiceImpl.java index 80da5ec..35fbd18 100644 --- a/lab-service/lab-lims/src/main/java/org/springblade/lims/service/impl/EntrustServiceImpl.java +++ b/lab-service/lab-lims/src/main/java/org/springblade/lims/service/impl/EntrustServiceImpl.java @@ -167,6 +167,8 @@ public class EntrustServiceImpl extends BaseServiceImpl @Value("${repairPrint}") private String repairPrint; + @Value("${imagePrint}") + private String imagePrint; @Override @Transactional(rollbackFor = Exception.class) diff --git a/lab-service/lab-lims/src/main/java/org/springblade/lims/utils/qrcode/BufferedImageLuminanceSource.java b/lab-service/lab-lims/src/main/java/org/springblade/lims/utils/qrcode/BufferedImageLuminanceSource.java new file mode 100644 index 0000000..787522e --- /dev/null +++ b/lab-service/lab-lims/src/main/java/org/springblade/lims/utils/qrcode/BufferedImageLuminanceSource.java @@ -0,0 +1,113 @@ +package org.springblade.lims.utils.qrcode; + +import com.google.zxing.LuminanceSource; + +import java.awt.*; +import java.awt.geom.AffineTransform; +import java.awt.image.BufferedImage; + +/** + *
+ * Created by Binary Wang on 2017-01-05.
+ * @author binarywang(Binary Wang)
+ * 
+ */ +public final class BufferedImageLuminanceSource extends LuminanceSource { + + private final BufferedImage image; + private final int left; + private final int top; + + public BufferedImageLuminanceSource(BufferedImage image) { + this(image, 0, 0, image.getWidth(), image.getHeight()); + } + + public BufferedImageLuminanceSource(BufferedImage image, int left, int top, + int width, int height) { + super(width, height); + + int sourceWidth = image.getWidth(); + int sourceHeight = image.getHeight(); + if (left + width > sourceWidth || top + height > sourceHeight) { + throw new IllegalArgumentException("Crop rectangle does not fit within image data."); + } + + for (int y = top; y < top + height; y++) { + for (int x = left; x < left + width; x++) { + if ((image.getRGB(x, y) & 0xFF000000) == 0) { + image.setRGB(x, y, 0xFFFFFFFF);// = white + } + } + } + + this.image = new BufferedImage(sourceWidth, sourceHeight, + BufferedImage.TYPE_BYTE_GRAY); + this.image.getGraphics().drawImage(image, 0, 0, null); + this.left = left; + this.top = top; + } + + @Override + public byte[] getRow(int y, byte[] row) { + if (y < 0 || y >= getHeight()) { + throw new IllegalArgumentException( + "Requested row is outside the image: " + y); + } + int width = getWidth(); + if (row == null || row.length < width) { + row = new byte[width]; + } + this.image.getRaster().getDataElements(this.left, this.top + y, width, + 1, row); + return row; + } + + @Override + public byte[] getMatrix() { + int width = getWidth(); + int height = getHeight(); + int area = width * height; + byte[] matrix = new byte[area]; + this.image.getRaster().getDataElements(this.left, this.top, width, + height, matrix); + return matrix; + } + + @Override + public boolean isCropSupported() { + return true; + } + + @Override + public LuminanceSource crop(int left, int top, int width, int height) { + return new com.github.binarywang.utils.qrcode.BufferedImageLuminanceSource(this.image, this.left + left, + this.top + top, width, height); + } + + @Override + public boolean isRotateSupported() { + return true; + } + + @Override + public LuminanceSource rotateCounterClockwise() { + + int sourceWidth = this.image.getWidth(); + int sourceHeight = this.image.getHeight(); + + AffineTransform transform = new AffineTransform(0.0, -1.0, 1.0, 0.0, + 0.0, sourceWidth); + + BufferedImage rotatedImage = new BufferedImage(sourceHeight, + sourceWidth, BufferedImage.TYPE_BYTE_GRAY); + + Graphics2D g = rotatedImage.createGraphics(); + g.drawImage(this.image, transform, null); + g.dispose(); + + int width = getWidth(); + return new com.github.binarywang.utils.qrcode.BufferedImageLuminanceSource(rotatedImage, this.top, + sourceWidth - (this.left + width), getHeight(), width); + } + +} diff --git a/lab-service/lab-lims/src/main/java/org/springblade/lims/utils/qrcode/MatrixToImageWriter.java b/lab-service/lab-lims/src/main/java/org/springblade/lims/utils/qrcode/MatrixToImageWriter.java new file mode 100644 index 0000000..b6c3136 --- /dev/null +++ b/lab-service/lab-lims/src/main/java/org/springblade/lims/utils/qrcode/MatrixToImageWriter.java @@ -0,0 +1,55 @@ +package org.springblade.lims.utils.qrcode; + +import com.google.zxing.common.BitMatrix; + +import javax.imageio.ImageIO; +import java.awt.image.BufferedImage; +import java.io.File; +import java.io.IOException; +import java.io.OutputStream; + +/** + *
+ * Created by Binary Wang on 2017-01-05.
+ * @author binarywang(Binary Wang)
+ * 
+ */ +public final class MatrixToImageWriter { + + private static final int BLACK = 0xFF000000; + private static final int WHITE = 0xFFFFFFFF; + + private MatrixToImageWriter() { + } + + 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 y = 0; y < height; y++) { + image.setRGB(x, y, matrix.get(x, y) ? BLACK : WHITE); + } + } + + return image; + } + + public static void writeToFile(BitMatrix matrix, String format, File file) + throws IOException { + BufferedImage image = toBufferedImage(matrix); + if (!ImageIO.write(image, format, file)) { + throw new IOException("Could not write an image of format " + format + " to " + file); + } + } + + public static void writeToStream(BitMatrix matrix, String format, OutputStream stream) + throws IOException { + BufferedImage image = toBufferedImage(matrix); + if (!ImageIO.write(image, format, stream)) { + throw new IOException("Could not write an image of format " + format); + } + } + +} diff --git a/lab-service/lab-lims/src/main/java/org/springblade/lims/utils/qrcode/MatrixToLogoImageConfig.java b/lab-service/lab-lims/src/main/java/org/springblade/lims/utils/qrcode/MatrixToLogoImageConfig.java new file mode 100644 index 0000000..eff5f90 --- /dev/null +++ b/lab-service/lab-lims/src/main/java/org/springblade/lims/utils/qrcode/MatrixToLogoImageConfig.java @@ -0,0 +1,56 @@ +package org.springblade.lims.utils.qrcode; + +import java.awt.*; + +/** + *
+ * Created by Binary Wang on 2017-01-05.
+ * @author binarywang(Binary Wang)
+ * 
+ */ +public class MatrixToLogoImageConfig { + /** + * logo默认边框颜色 + */ + public static final Color DEFAULT_BORDERCOLOR = Color.WHITE; + /** + * logo默认边框宽度 + */ + public static final int DEFAULT_BORDER = 5; + /** + * logo大小默认为照片的1/5 + */ + public static final int DEFAULT_LOGOPART = 5; + + private final int border; + private final Color borderColor; + private final int logoPart; + + public MatrixToLogoImageConfig() { + this(DEFAULT_BORDERCOLOR, DEFAULT_LOGOPART); + } + + public MatrixToLogoImageConfig(Color borderColor, int logoPart) { + this(borderColor, logoPart, DEFAULT_BORDER); + } + + public MatrixToLogoImageConfig(Color borderColor, int logoPart, int border) { + this.borderColor = borderColor; + this.logoPart = logoPart; + this.border = border; + } + + + public Color getBorderColor() { + return this.borderColor; + } + + public int getBorder() { + return this.border; + } + + public int getLogoPart() { + return this.logoPart; + } + +} diff --git a/lab-service/lab-lims/src/main/java/org/springblade/lims/utils/qrcode/QrcodeUtils.java b/lab-service/lab-lims/src/main/java/org/springblade/lims/utils/qrcode/QrcodeUtils.java new file mode 100644 index 0000000..9a8bf04 --- /dev/null +++ b/lab-service/lab-lims/src/main/java/org/springblade/lims/utils/qrcode/QrcodeUtils.java @@ -0,0 +1,243 @@ +package org.springblade.lims.utils.qrcode; + +import com.github.binarywang.utils.qrcode.BufferedImageLuminanceSource; +import com.github.binarywang.utils.qrcode.MatrixToImageWriter; +import com.github.binarywang.utils.qrcode.MatrixToLogoImageConfig; +import com.google.common.collect.Maps; +import com.google.zxing.*; +import com.google.zxing.common.BitMatrix; +import com.google.zxing.common.HybridBinarizer; +import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel; +import lombok.experimental.UtilityClass; +import lombok.extern.slf4j.Slf4j; + +import javax.imageio.ImageIO; +import java.awt.*; +import java.awt.geom.RoundRectangle2D; +import java.awt.image.BufferedImage; +import java.io.*; +import java.nio.charset.StandardCharsets; +import java.nio.file.Files; +import java.util.Map; + +/** + *
+ * Created by Binary Wang on 2017-01-05.
+ * @author binarywang(Binary Wang)
+ * 
+ */ +@Slf4j +@UtilityClass +public class QrcodeUtils { + /** + * 生成二维码的默认边长,因为是正方形的,所以高度和宽度一致 + */ + private static final int DEFAULT_LENGTH = 400; + /** + * 生成二维码的格式 + */ + private static final String FORMAT = "jpg"; + + /** + * 根据内容生成二维码数据 + * + * @param content 二维码文字内容[为了信息安全性,一般都要先进行数据加密] + * @param length 二维码图片宽度和高度 + */ + public static BitMatrix createQrcodeMatrix(String content, int length) { + return createQrcodeMatrix(content, length, ErrorCorrectionLevel.H); + } + + public static BitMatrix createQrcodeMatrix(String content, int length, ErrorCorrectionLevel level) { + Map hints = Maps.newEnumMap(EncodeHintType.class); + // 设置字符编码 + hints.put(EncodeHintType.CHARACTER_SET, StandardCharsets.UTF_8.name()); + // 指定纠错等级 + hints.put(EncodeHintType.ERROR_CORRECTION, level); + + try { + return new MultiFormatWriter().encode(content, BarcodeFormat.QR_CODE, length, length, hints); + } catch (WriterException e) { + throw new RuntimeException("内容为:【" + content + "】的二维码生成失败!", e); + } + } + + /** + * 根据指定边长创建生成的二维码,允许配置logo属性 + * + * @param content 二维码内容 + * @param length 二维码的高度和宽度 + * @param logoFile logo 文件对象,可以为空 + * @param logoConfig logo配置,可设置logo展示长宽,边框颜色 + * @return 二维码图片的字节数组 + */ + public static byte[] createQrcode(String content, int length, File logoFile, MatrixToLogoImageConfig logoConfig) + throws Exception { + if (logoFile != null && !logoFile.exists()) { + throw new IllegalArgumentException("请提供正确的logo文件!"); + } + + try (InputStream logo = logoFile == null ? null : new FileInputStream(logoFile)) { + return createQrcode(content, length, logo, logoConfig); + } + } + + public static byte[] createQrcode(String content, int length, InputStream logo, MatrixToLogoImageConfig logoConfig) throws Exception { + BufferedImage img = generateQRCodeImage(content, length, logo, logoConfig); + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + ImageIO.write(img, FORMAT, baos); + return baos.toByteArray(); + } + + /** + * 根据指定边长创建生成的二维码 + * + * @param content 二维码内容 + * @param length 二维码的高度和宽度 + * @param logoFile logo 文件对象,可以为空 + * @return 二维码图片的字节数组 + */ + public static byte[] createQrcode(String content, int length, File logoFile) throws Exception { + return createQrcode(content, length, logoFile, new MatrixToLogoImageConfig()); + } + + /** + * 创建生成默认高度(400)的二维码图片 + * 可以指定是否贷logo + * + * @param content 二维码内容 + * @param logoFile logo 文件对象,可以为空 + * @return 二维码图片的字节数组 + */ + public static byte[] createQrcode(String content, File logoFile) throws Exception { + return createQrcode(content, DEFAULT_LENGTH, logoFile); + } + + public static BufferedImage generateQRCodeImage(String content, int length, InputStream logo, MatrixToLogoImageConfig logoConfig) throws Exception { + // 生成二维码图像 + BitMatrix qrCodeMatrix = createQrcodeMatrix(content, length); + BufferedImage img = MatrixToImageWriter.toBufferedImage(qrCodeMatrix); + try { + if (logo != null) { + overlapImage(img, FORMAT, logo, logoConfig); + } + } catch (Exception e) { + throw new RuntimeException("为二维码添加LOGO时失败!", e); + } + return img; + } + + public static BufferedImage generateQRCodeImage(String content, int length, File logoFile, MatrixToLogoImageConfig logoConfig) throws Exception { + if (logoFile != null && !logoFile.exists()) { + throw new IllegalArgumentException("请提供正确的logo文件!"); + } + try (InputStream logo = Files.newInputStream(logoFile.toPath())) { + return generateQRCodeImage(content, length, logo, logoConfig); + } + } + + public static BufferedImage generateQRCodeImage(String content, int length, InputStream logo) throws Exception { + return generateQRCodeImage(content, length, logo, new MatrixToLogoImageConfig()); + } + + public static BufferedImage generateQRCodeImage(String content, int length, File logoFile) throws Exception { + return generateQRCodeImage(content, length, logoFile, new MatrixToLogoImageConfig()); + } + + public static BufferedImage generateQRCodeImage(String content, InputStream logo) throws Exception { + return generateQRCodeImage(content, DEFAULT_LENGTH, logo); + } + + public static BufferedImage generateQRCodeImage(String content, File logoFile) throws Exception { + return generateQRCodeImage(content, DEFAULT_LENGTH, logoFile); + } + + /** + * 将logo添加到二维码中间 + * + * @param image 生成的二维码图片对象 + * @param logo logo文件对象 + * @param ignoredFormat 图片格式 + */ + private static void overlapImage(final BufferedImage image, String ignoredFormat, final InputStream logo, + MatrixToLogoImageConfig logoConfig) throws IOException { + BufferedImage logoImg = ImageIO.read(logo); + logoImg = clipRound(logoImg); + Graphics2D g = logoImg.createGraphics(); + // 考虑到logo图片贴到二维码中,建议大小不要超过二维码的1/5; + int width = image.getWidth() / logoConfig.getLogoPart(); + int height = image.getHeight() / logoConfig.getLogoPart(); + int radius = width / 10; + // logo起始位置,此目的是为logo居中显示 + int x = (image.getWidth() - width) / 2; + int y = (image.getHeight() - height) / 2; + + // 创建一个支持有透明度的图像缓冲区 + BufferedImage buffer = g.getDeviceConfiguration().createCompatibleImage(image.getWidth(), image.getHeight(), Transparency.TRANSLUCENT); + g.dispose(); + + // 绘制阴影 + g = buffer.createGraphics(); + g.setComposite(AlphaComposite.getInstance(AlphaComposite.XOR, 0.1f)); + g.setColor(Color.BLACK); + g.fillRoundRect(x + 10, y + 10, width - 20, height, radius, radius); + g.dispose(); + + // 绘制LOGO到缓冲区 + g = buffer.createGraphics(); + g.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC, 1)); + g.drawImage(logoImg, x, y, width, height, null); + + // 给logo画边框 + // 构造一个具有指定线条宽度以及 cap 和 join 风格的默认值的实心 BasicStroke + g.setStroke(new BasicStroke(logoConfig.getBorder())); + g.setColor(logoConfig.getBorderColor()); + g.drawRoundRect(x, y, width, height, radius, radius); + g.setStroke(new BasicStroke(1)); + g.setColor(Color.GRAY); + g.drawRoundRect(x + logoConfig.getBorder() / 2, y + logoConfig.getBorder() / 2, width - logoConfig.getBorder(), + height - logoConfig.getBorder(), radius, radius); + g.dispose(); + + // 将带阴影的图像绘制到二维码上 + g = image.createGraphics(); + g.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_ATOP, 1.0f)); + g.drawImage(buffer, 0, 0, image.getWidth(), image.getHeight(), null); + g.dispose(); + } + + /** + * 为LOGO剪出圆角 + * + * @param srcImage LOGO图像 + */ + private static BufferedImage clipRound(BufferedImage srcImage) { + int width = srcImage.getWidth(); + int height = srcImage.getHeight(); + int radius = width / 10; + + BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB); + Graphics2D g = image.createGraphics(); + g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); + g.setClip(new RoundRectangle2D.Double(0, 0, width, height, radius, radius)); + g.drawImage(srcImage, 0, 0, null); + g.dispose(); + return image; + } + + /** + * 解析二维码 + * + * @param file 二维码文件内容 + * @return 二维码的内容 + */ + public static String decodeQrcode(File file) throws IOException, NotFoundException { + BufferedImage image = ImageIO.read(file); + LuminanceSource source = new BufferedImageLuminanceSource(image); + Binarizer binarizer = new HybridBinarizer(source); + BinaryBitmap binaryBitmap = new BinaryBitmap(binarizer); + Map hints = Maps.newEnumMap(DecodeHintType.class); + hints.put(DecodeHintType.CHARACTER_SET, StandardCharsets.UTF_8.name()); + return new MultiFormatReader().decode(binaryBitmap, hints).getText(); + } +}