diff --git a/cash-service/account-service/src/main/java/com/czg/service/account/service/impl/ShopTableServiceImpl.java b/cash-service/account-service/src/main/java/com/czg/service/account/service/impl/ShopTableServiceImpl.java index 5bed26952..42e18dc95 100644 --- a/cash-service/account-service/src/main/java/com/czg/service/account/service/impl/ShopTableServiceImpl.java +++ b/cash-service/account-service/src/main/java/com/czg/service/account/service/impl/ShopTableServiceImpl.java @@ -93,48 +93,60 @@ public class ShopTableServiceImpl extends ServiceImpl records = shopTableCodeService.queryChain().orderBy(ShopTableCode::getId, false).page(new Page<>(1, 1)).getRecords(); - Map codeMap = shopTableCodeService.queryChain().eq(ShopTableCode::getShopId, shopId).select(ShopTableCode::getTableCode, ShopTableCode::getId) - .list().stream().collect(Collectors.toMap(ShopTableCode::getTableCode, ShopTableCode::getId)); - + // 获取当前店铺下的最大ID,确保只查询当前shopId的记录 + List records = shopTableCodeService.queryChain() + .eq(ShopTableCode::getShopId, shopId) + .orderBy(ShopTableCode::getId, false) + .page(new Page<>(1, 1)) + .getRecords(); long maxId = records.isEmpty() ? 0 : records.getFirst().getId(); - // 设置 ZIP 响应头 - response.setContentType("application/octet-stream"); - response.setHeader("Content-Disposition", "attachment; filename=shop_qrcodes_" + shopId + ".zip"); + // 获取当前店铺下所有已存在的tableCode,避免重复 + Map codeMap = shopTableCodeService.queryChain() + .eq(ShopTableCode::getShopId, shopId) + .select(ShopTableCode::getTableCode, ShopTableCode::getId) + .list() + .stream() + .collect(Collectors.toMap(ShopTableCode::getTableCode, ShopTableCode::getId)); - ArrayList codeList = new ArrayList<>(); + // 预生成所有二维码数据和记录,避免在写入ZIP过程中出现异常 + List codeList = new ArrayList<>(); + List qrBytesList = new ArrayList<>(); + List fileNames = new ArrayList<>(); - // 使用 ZipOutputStream 直接将二维码写入 ZIP - try (ZipOutputStream zipOut = new ZipOutputStream(response.getOutputStream())) { - for (int i = 0; i < num; i++) { - String tableCode = generateCode(1, shopId, ++maxId, codeMap); - codeMap.put(tableCode, maxId); + for (int i = 0; i < num; i++) { + String tableCode = generateCode(1, shopId, ++maxId, codeMap); + codeMap.put(tableCode, maxId); - codeList.add(new ShopTableCode().setShopId(shopId).setTableCode(tableCode)); + codeList.add(new ShopTableCode() + .setShopId(shopId) + .setTableCode(tableCode)); - // 生成二维码并写入 ByteArrayOutputStream - ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream(); - // 生成二维码 - BufferedImage qrImage = QrCodeUtil.generate(tableCode, 300, 300); - // 转换为字节数组 - ImgUtil.write(qrImage, ImgUtil.IMAGE_TYPE_PNG, byteArrayOutputStream); - byte[] qrBytes = byteArrayOutputStream.toByteArray(); - - // 创建一个新的 ZipEntry - zipOut.putNextEntry(new ZipEntry(tableCode + ".png")); - zipOut.write(qrBytes); - zipOut.closeEntry(); // 确保当前文件条目被关闭 - } - - // 刷新并完成文件输出 - zipOut.flush(); - zipOut.finish(); + // 生成二维码图片 + BufferedImage qrImage = QrCodeUtil.generate(tableCode, 300, 300); + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + ImgUtil.write(qrImage, ImgUtil.IMAGE_TYPE_PNG, baos); + qrBytesList.add(baos.toByteArray()); + fileNames.add(tableCode + ".png"); } - // 保存二维码信息 + // 先保存数据库记录,确保生成ZIP前无异常 shopTableCodeService.saveBatch(codeList); + + // 设置响应头 + response.setContentType("application/zip"); + response.setHeader("Content-Disposition", "attachment; filename=shop_qrcodes_" + shopId + ".zip"); + + // 写入ZIP文件 + try (ZipOutputStream zipOut = new ZipOutputStream(response.getOutputStream())) { + for (int i = 0; i < num; i++) { + ZipEntry entry = new ZipEntry(fileNames.get(i)); + zipOut.putNextEntry(entry); + zipOut.write(qrBytesList.get(i)); + zipOut.closeEntry(); + } + zipOut.finish(); + } }