From ef3e01353c7ed1f32324868e51b1d2de398ebad5 Mon Sep 17 00:00:00 2001 From: mashuai Date: Tue, 22 Oct 2024 15:38:00 +0800 Subject: [PATCH] =?UTF-8?q?=E6=96=B0=E8=B4=AD=E7=BB=91=E5=AE=9A?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- bonus-common-biz/pom.xml | 17 + .../biz/config/BackstageApplication.java | 63 ++ .../common/biz/config/DateTimeHelper.java | 603 ++++++++++++++++++ .../bonus/common/biz/config/QrCodeUtils.java | 180 ++++++ .../controller/PurchaseBindController.java | 12 + .../material/purchase/dto/PurchaseDto.java | 14 +- .../purchase/mapper/PurchaseBindMapper.java | 28 + .../service/IPurchaseBindService.java | 8 + .../service/impl/PurchaseBindServiceImpl.java | 218 ++++++- .../material/purchase/vo/PurchaseVo.java | 5 +- .../material/purchase/PurchaseBindMapper.xml | 87 ++- 11 files changed, 1224 insertions(+), 11 deletions(-) create mode 100644 bonus-common-biz/src/main/java/com/bonus/common/biz/config/BackstageApplication.java create mode 100644 bonus-common-biz/src/main/java/com/bonus/common/biz/config/DateTimeHelper.java create mode 100644 bonus-common-biz/src/main/java/com/bonus/common/biz/config/QrCodeUtils.java diff --git a/bonus-common-biz/pom.xml b/bonus-common-biz/pom.xml index 9b98d0fe..30315ab2 100644 --- a/bonus-common-biz/pom.xml +++ b/bonus-common-biz/pom.xml @@ -176,6 +176,23 @@ org.springframework.data spring-data-redis + + + com.google.zxing + core + 3.3.0 + + + com.google.zxing + javase + 3.3.0 + + + + org.apache.commons + commons-compress + 1.22 + diff --git a/bonus-common-biz/src/main/java/com/bonus/common/biz/config/BackstageApplication.java b/bonus-common-biz/src/main/java/com/bonus/common/biz/config/BackstageApplication.java new file mode 100644 index 00000000..af87c3fa --- /dev/null +++ b/bonus-common-biz/src/main/java/com/bonus/common/biz/config/BackstageApplication.java @@ -0,0 +1,63 @@ +package com.bonus.common.biz.config; + +/** + * 二维码类路径 + * @Author ma_sh + * @create 2024/10/22 15:18 + */ +public class BackstageApplication { + + private final static String CS_LOGIN_PATH = "ahjj.jypxks.com:9988"; + // private final static String CS_LOGIN_PATH = "112.30.107.201:9988"; + //测试环境 + //private final static String CS_LOGIN_PATH = "192.168.0.14:2011"; + + private final static String CS_USER_NAME = "root"; + + private final static String CS_PASSWORD = "bonusadmin"; + + private final static String CS_EP_ID = "system"; + + private final static String url = "http://ahjj.jypxks.com:9988/imw/"; + // private final static String url = "http://192.168.0.6:18082/imt_cs/"; + //private final static String url = "http://192.168.0.14:2011/imw_cs/"; + + + + private final static String imageUrlPrefix = "http://ahjj.jypxks.com:9988/imw/images/"; + + //测试环境 + //private final static String imageUrlPrefix = "http://192.168.0.14:2011/imt_cs/images/"; + + private final static String fileUrlPrefix = "http://ahjj.jypxks.com:9988/imw/maTypeFile/"; + //测试环境 + // private final static String fileUrlPrefix = "http://192.168.0.14:2011/imt_cs/maTypeFile/"; + + public static String getCsLoginPath() { + return CS_LOGIN_PATH; + } + + public static String getCsUserName() { + return CS_USER_NAME; + } + + public static String getCsPassword() { + return CS_PASSWORD; + } + + public static String getCsEpId() { + return CS_EP_ID; + } + + public static String getUrl() { + return url; + } + + public static String getImageUrlPrefix(){ + return imageUrlPrefix; + } + + public static String getFileurlprefix() { + return fileUrlPrefix; + } +} diff --git a/bonus-common-biz/src/main/java/com/bonus/common/biz/config/DateTimeHelper.java b/bonus-common-biz/src/main/java/com/bonus/common/biz/config/DateTimeHelper.java new file mode 100644 index 00000000..0e28aa89 --- /dev/null +++ b/bonus-common-biz/src/main/java/com/bonus/common/biz/config/DateTimeHelper.java @@ -0,0 +1,603 @@ +package com.bonus.common.biz.config; + +import java.text.DateFormat; +import java.text.ParseException; +import java.text.SimpleDateFormat; +import java.util.Calendar; +import java.util.Date; + +/** + * @Author ma_sh + * @create 2024/10/22 14:36 + */ +public class DateTimeHelper { + + private static final SimpleDateFormat FULL_SDF = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); + + /** + * 获取当前时间的年份 + * + * @return + */ + public static String getNowYear() { + return format(new Date(), "yyyy"); + } + + public static String getNowMonthAndDay() { + return format(new Date(), "MM-dd"); + } + + public static String getYear(Date d) { + int year = d.getYear() + 1900; + return year + ""; + } + + + + /** + * 格式化 时间 + * + * @param format + * @return + */ + public static String format(Date d, String format) { + SimpleDateFormat df = new SimpleDateFormat(format); + return df.format(d); + } + + public static String format(String str, String format, String disFormat) { + Date d = parse(str, format); + return format(d, disFormat); + } + + /** + * 格式化 时间 + * + * @param format + * @return + */ + public static String format(Date d, DateFormat format) { + return format.format(d); + } + + /** + * 格式化 时间 + * + * @param format + * @return Date + * @throws ParseException + */ + public static Date parse(String dateStr, String format) { + SimpleDateFormat df = new SimpleDateFormat(format); + try { + return df.parse(dateStr); + } catch (ParseException e) { + return new Date(); + } + } + + public static Date parse(String dateStr, String format, Date d) { + try { + SimpleDateFormat df = new SimpleDateFormat(format); + return df.parse(dateStr); + } catch (Exception e) { + return d; + } + } + + /** + * 解析时间 + * + * @return Date + * @throws ParseException + */ + public static Date parse(String dateStr, DateFormat format) throws ParseException { + return format.parse(dateStr); + } + + public static Date parseDate(String dateStr) throws ParseException { + SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd"); + return sdf.parse(dateStr); + } + + /** + * 获取当前时间的年月 + * + * @return + */ + public static String getPrevMonth() { + return minusMonth(new Date(), 1); + } + + /** + * 获取当前时间的上个年月 + * + * @return + */ + public static String getNowMonth() { + return format(new Date(), "yyyy-MM"); + } + + /** + * 获取当前时间的上个年月格式化 + * + * @return + */ + public static String getNowMonthFomart() { + return format(new Date(), "yyyyMM"); + } + + /** + * 获取当前时间的前一天 + * + * @return + */ + public static String getPreDate(String dateStr) { + Date date = parse(dateStr, "yyyy-MM-dd"); + Calendar c = Calendar.getInstance(); + c.setTime(date); + c.add(Calendar.DAY_OF_MONTH, -1); + return format(c.getTime(), "yyyy-MM-dd"); + } + + /** + * 获取当前时间的上一个月 + * + * @return + */ + public static String getPreMonthDate() { + Date date = new Date(); + Calendar calendar = Calendar.getInstance(); + calendar.setTime(date); // 设置为当前时间 + calendar.set(Calendar.MONTH, calendar.get(Calendar.MONTH) - 1); // 设置为上一个月 + date = calendar.getTime(); + return format(date, "yyyy-MM-dd"); + } + + public static String getPreMonth() { + Date date = new Date(); + Calendar calendar = Calendar.getInstance(); + calendar.set(Calendar.MONTH, calendar.get(Calendar.MONTH) - 1); // 设置为上一个月 + date = calendar.getTime(); + return format(date, "yyyy-MM"); + } + + /** + * 获取当前时间的前两个月 + * + * @return + */ + public static String getTwoMonthDate() { + Date date = new Date(); + Calendar calendar = Calendar.getInstance(); + calendar.setTime(date); // 设置为当前时间 + calendar.set(Calendar.MONTH, calendar.get(Calendar.MONTH) - 2); // 设置为前两个月 + date = calendar.getTime(); + return format(date, "yyyy-MM-dd"); + } + + /** + * 获取当前时间的上一年 + * + * @return + */ + public static String getPreYearDate() { + Date date = new Date(); + Calendar calendar = Calendar.getInstance(); + calendar.setTime(date); // 设置为当前时间 + calendar.set(Calendar.YEAR, calendar.get(Calendar.YEAR) - 1); // 设置为上一年 + date = calendar.getTime(); + return format(date, "yyyy-MM-dd"); + } + + /** + * 获取当前时间的年月日 + * + * @return + */ + public static String getNowDate() { + return format(new Date(), "yyyy-MM-dd"); + } + + public static String getNowDateFomart() { + return format(new Date(), "yyyyMMdd"); + } + + /** + * 明年的昨天 + * + * @param dateStr + * @return + */ + public static String getNextYearDate(String dateStr) { + Date date = parse(dateStr, "yyyy-MM-dd"); + Calendar c = Calendar.getInstance(); + c.setTime(date); + c.add(Calendar.YEAR, 1); + c.add(Calendar.DAY_OF_MONTH, -1); + return format(c.getTime(), "yyyy-MM-dd"); + } + + /** + * 获取前年 + * + * @param dateStr + * @return + */ + public static String getBeforeYearDate(String dateStr) { + Date date = parse(dateStr, "yyyy-MM-dd"); + Calendar c = Calendar.getInstance(); + c.setTime(date); + c.add(Calendar.YEAR, -1); +// c.add(Calendar.DAY_OF_MONTH, 1); + return format(c.getTime(), "yyyy-MM-dd"); + } + + /** + * 获取明天时间的年月日 + * + * @return + */ + public static String getTomorrowDate(String nowDate) { + Date date = parse(nowDate, "yyyy-MM-dd"); + Calendar c = Calendar.getInstance(); + c.setTime(date); + c.add(Calendar.DATE, 1); + return format(c.getTime(), "yyyy-MM-dd"); + } + + /** + * 获取当前时间 + * + * @return + */ + public static String getNowTime() { + return format(new Date(), "yyyy-MM-dd HH:mm:ss"); + } + + public static String getNowTimeFomart() { + return format(new Date(), "yyyyMMddHHmmss"); + } + + public static String getNextYear() { + return format(new Date(), "yyyy-MM-dd HH:mm:ss"); + } + + /** + * + * @return + */ + public static String minusMonth(Date date, int c) { + SimpleDateFormat df = new SimpleDateFormat("yyyy-MM"); + try { + Calendar cal = Calendar.getInstance(); + cal.setTime(date); + cal.add(Calendar.MONTH, -c); + return format(cal.getTime(), df); + } catch (Exception e) { + return format(date, df); + } + } + + /** + * + * @param month + * @return + */ + public static String minusMonth(String month, int c) { + try { + SimpleDateFormat df = new SimpleDateFormat("yyyy-MM"); + Date date = parse(month, df); + + Calendar cal = Calendar.getInstance(); + cal.setTime(date); + cal.add(Calendar.MONTH, -c); + + return format(cal.getTime(), df); + } catch (Exception e) { + return month; + } + } + + /** + * + * @return + */ + public static Date minus(Date d, int type, int c) { + try { + Calendar cal = Calendar.getInstance(); + cal.setTime(d); + cal.add(type, -c); + return cal.getTime(); + } catch (Exception e) { + return new Date(); + } + } + + /** + * 得到前一个月 + * + * @param month + * @return + */ + public static String prevMonth(String month) { + return minusMonth(month, 1); + } + + /** + * 得到前一个月 + * + * @param month + * @return + */ + public static String prevMonth(String month, int c) { + return minusMonth(month, c); + } + + public static float duration(String startTime, String stopTime) { + Date sd = DateTimeHelper.parse(startTime, "yyyy-MM-dd HH:mm"); + long sl = sd.getTime(); + + Date ed = DateTimeHelper.parse(stopTime, "yyyy-MM-dd HH:mm"); + long el = ed.getTime(); + + float l = el - sl; + if (l <= 0) { + l = 0; + } + l = l / (1000 * 60); + return l; + } + + public static String getStartYearMonthBySeason(String year, int season) { + switch (season) { + case 1: + return getYearMonth(year, "01"); + case 2: + return getYearMonth(year, "04"); + case 3: + return getYearMonth(year, "07"); + case 4: + return getYearMonth(year, "10"); + default: + return getYearMonth(year, "01"); + } + } + + private static String getYearMonth(String year, String month) { + return year + "-" + month; + } + + public static String getEndYearMonthBySeason(String year, int season) { + switch (season) { + case 1: + return getYearMonth(year, "03"); + case 2: + return getYearMonth(year, "06"); + case 3: + return getYearMonth(year, "09"); + case 4: + return getYearMonth(year, "12"); + default: + return getYearMonth(year, "03"); + } + } + + public static String getAddNumDay(String giveTime, int addDay) { + String time = giveTime; + Date date = new Date(); + SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd"); + Calendar calendar = Calendar.getInstance(); + try { + date = sdf.parse(time); + } catch (ParseException e) { + e.printStackTrace(); + } + calendar.setTime(date); + calendar.add(Calendar.DAY_OF_MONTH, +addDay);// +1今天的时间加一天 + date = calendar.getTime(); + time = sdf.format(date); + return time; + } + + /** + * date2比date1多的天数 + * + * @param date1 + * @param date2 + * @return + */ + public static int differentDays(Date date1, Date date2) { + Calendar cal1 = Calendar.getInstance(); + cal1.setTime(date1); + + Calendar cal2 = Calendar.getInstance(); + cal2.setTime(date2); + int day1 = cal1.get(Calendar.DAY_OF_YEAR); + int day2 = cal2.get(Calendar.DAY_OF_YEAR); + + int year1 = cal1.get(Calendar.YEAR); + int year2 = cal2.get(Calendar.YEAR); + if (year1 != year2) // 同一年 + { + int timeDistance = 0; + for (int i = year1; i < year2; i++) { + if (i % 4 == 0 && i % 100 != 0 || i % 400 == 0) // 闰年 + { + timeDistance += 366; + } else // 不是闰年 + { + timeDistance += 365; + } + } + + return timeDistance + (day2 - day1); + } else // 不同年 + { +// System.out.println("判断day2 - day1 : " + (day2 - day1)); + return day2 - day1; + } + } + + /** + * 通过时间秒毫秒数判断两个时间的间隔 + * + * @param date1 + * @param date2 + * @return + */ + public static int differentDaysByMillisecond(Date date1, Date date2) { + int days = (int) ((date2.getTime() - date1.getTime()) / (1000 * 3600 * 24)); + return days; + } + + public static int calcDate(String dateStr, String dateStr2) { + SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd"); + try { + Date date = format.parse(dateStr); + Date date2 = format.parse(dateStr2); + return DateTimeHelper.differentDays(date, date2); + } catch (Exception e) { + e.printStackTrace(); + } + return 0; + } + + // 判断时间date1是否在时间date2之前 + // 时间格式 2005-4-21 + public static boolean isDateBefore(String date1, String date2) { + try { + SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd"); + Date bt = sdf.parse(date1); + Date et = sdf.parse(date2); + if (bt.before(et)) { + return true; + } else { + return false; + } + + } catch (ParseException e) { + System.out.print("[SYS] " + e.getMessage()); + return false; + } + } + + public static boolean isFirstDay() { + Calendar c = Calendar.getInstance(); + c.setTime(new Date()); + return c.get(Calendar.DAY_OF_MONTH) == 1; + } + + public static String getFirstDay() { + SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd"); + // 获取当前月第一天: + Calendar c = Calendar.getInstance(); + c.add(Calendar.MONTH, 0); + c.set(Calendar.DAY_OF_MONTH, 1);// 设置为1号,当前日期既为本月第一天 + String first = format.format(c.getTime()); + return first; + } + + public static String getLastDay() { + SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd"); + // 获取当前月最后一天 + Calendar ca = Calendar.getInstance(); + ca.set(Calendar.DAY_OF_MONTH, ca.getActualMaximum(Calendar.DAY_OF_MONTH)); + String last = format.format(ca.getTime()); + return last; + } + + public static String getPreFirstDay() { + SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd"); + // 获取当前月第一天: + Calendar c = Calendar.getInstance(); + c.add(Calendar.MONTH, -1); + c.set(Calendar.DAY_OF_MONTH, 1);// 设置为1号,当前日期既为本月第一天 + String first = format.format(c.getTime()); + return first; + } + + public static String getPreLastDay() { + SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd"); + // 获取当前月最后一天 + Calendar c = Calendar.getInstance(); + c.add(Calendar.MONTH, -1); + c.set(Calendar.DAY_OF_MONTH, c.getActualMaximum(Calendar.DAY_OF_MONTH)); + String last = format.format(c.getTime()); + return last; + } + + // 计算两个日期相差年数 + public static int yearDateDiff(String startDate, String endDate) { + int year = 0; + try { + + SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd"); + Calendar bef = Calendar.getInstance(); + Calendar aft = Calendar.getInstance(); + bef.setTime(sdf.parse(startDate)); + + aft.setTime(sdf.parse(endDate)); + year = aft.get(Calendar.YEAR) - bef.get(Calendar.YEAR); + + } catch (ParseException e) { + e.printStackTrace(); + } + return year; + } + + public static boolean isInXMinutes(String createTime, int x) { + try { + Date date = FULL_SDF.parse(createTime); + Date now = new Date(); + long diff = now.getTime() - date.getTime(); + return diff <= x * 60 * 1000; + } catch (ParseException e) { + e.printStackTrace(); + return false; + } + } + + public static boolean isMonthStartAndEnd(String startDateStr, String endDateStr) { + try { + SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd"); + Date startDate = sdf.parse(startDateStr); + Date endDate = sdf.parse(endDateStr); + Calendar startCal = Calendar.getInstance(); + startCal.setTime(startDate); + Calendar endCal = Calendar.getInstance(); + endCal.setTime(endDate); + Calendar today = Calendar.getInstance(); + today.setTime(new Date()); + if (startCal.get(Calendar.DAY_OF_MONTH) == 1 + && endCal.get(Calendar.DAY_OF_MONTH) == endCal.getActualMaximum(Calendar.DAY_OF_MONTH) + && startCal.get(Calendar.YEAR) == endCal.get(Calendar.YEAR) + && startCal.get(Calendar.MONTH) == endCal.get(Calendar.MONTH) && startCal.before(today) + && endCal.before(today)) { + return true; + } else { + return false; + } + } catch (Exception e) { + e.printStackTrace(); + return false; + } + } + + /** + * 判断当前时间是否为当月的最后一天 + * + * @return + */ + public static boolean isLastDayOfMonth() { + String day = getLastDay(); + String currentDay = getNowDate(); + if (day.equals(currentDay)) { + return true; + } else { + return false; + } + } + +} + diff --git a/bonus-common-biz/src/main/java/com/bonus/common/biz/config/QrCodeUtils.java b/bonus-common-biz/src/main/java/com/bonus/common/biz/config/QrCodeUtils.java new file mode 100644 index 00000000..9ab5c30a --- /dev/null +++ b/bonus-common-biz/src/main/java/com/bonus/common/biz/config/QrCodeUtils.java @@ -0,0 +1,180 @@ +package com.bonus.common.biz.config; + +import com.google.zxing.BarcodeFormat; +import com.google.zxing.EncodeHintType; +import com.google.zxing.MultiFormatWriter; +import com.google.zxing.client.j2se.MatrixToImageConfig; +import com.google.zxing.client.j2se.MatrixToImageWriter; +import com.google.zxing.common.BitMatrix; +import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel; +import org.apache.commons.compress.archivers.zip.ZipArchiveEntry; +import org.apache.commons.compress.archivers.zip.ZipArchiveOutputStream; + +import javax.imageio.ImageIO; +import java.awt.*; +import java.awt.image.BufferedImage; +import java.io.File; +import java.io.FileOutputStream; +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.Hashtable; + +/** + * @Author ma_sh + * @create 2024/10/22 14:40 + */ +public class QrCodeUtils { + + /** 二维码宽度 */ + private static int width = 280; + + /** 二维码高度 */ + private static int height = 280; + + /** 前景色 */ + private static int onColor = 0xFF000000; + + /** 背景色 */ + private static int offColor = 0xFFFFFFFF; + + /** 白边大小,取值范围0~4 */ + private static int margin = 0; + + /** 二维码容错率 */ + private static ErrorCorrectionLevel level = ErrorCorrectionLevel.L; + + /** + * 生成带logo的二维码图片 + * + * @param txt //二维码内容 + * @param logoPath //logo绝对物理路径 + * @param imgPath //二维码保存绝对物理路径 + * @param imgName //二维码文件名称 + * @param suffix //图片后缀名 + * @throws Exception + */ + public static void generateQRImage(String txt, String logoPath, String imgPath, String imgName, String suffix) + throws Exception { + File filePath = new File(imgPath); + if (!filePath.exists()) { + filePath.mkdirs(); + } + if (imgPath.endsWith("/")) { + imgPath += imgName; + } else { + imgPath += "/" + imgName; + } + Hashtable hints = new Hashtable(); + hints.put(EncodeHintType.CHARACTER_SET, "utf-8"); + hints.put(EncodeHintType.ERROR_CORRECTION, level); + // 设置白边 + hints.put(EncodeHintType.MARGIN, margin); + BitMatrix bitMatrix = new MultiFormatWriter().encode(txt, BarcodeFormat.QR_CODE, width, height, hints); + File qrcodeFile = new File(imgPath); + writeToFile(bitMatrix, suffix, qrcodeFile, logoPath); + } + + /** + * 生成二维码 + * + * @param txt //二维码内容 + * @param imgPath //二维码保存物理路径 + * @param imgName //二维码文件名称 + * @param suffix //图片后缀名 + */ + public static void generateQRImage(String txt, String imgPath, String imgName, String suffix) { + + File filePath = new File(imgPath); + if (!filePath.exists()) { + filePath.mkdirs(); + } + File imageFile = new File(imgPath, imgName); + Hashtable hints = new Hashtable<>(); + // 指定纠错等级 + hints.put(EncodeHintType.ERROR_CORRECTION, level); + // 指定编码格式 + hints.put(EncodeHintType.CHARACTER_SET, "UTF-8"); + // 设置白边 + hints.put(EncodeHintType.MARGIN, margin); + try { + MatrixToImageConfig config = new MatrixToImageConfig(onColor, offColor); + BitMatrix bitMatrix = new MultiFormatWriter().encode(txt, BarcodeFormat.QR_CODE, width, height, hints); + // bitMatrix = deleteWhite(bitMatrix); + MatrixToImageWriter.writeToPath(bitMatrix, suffix, imageFile.toPath(), config); + } catch (Exception e) { + e.printStackTrace(); + } + } + + /** + * @param matrix 二维码矩阵相关 + * @param format 二维码图片格式 + * @param file 二维码图片文件 + * @param logoPath logo路径 + * @throws IOException + */ + public static void writeToFile(BitMatrix matrix, String format, File file, String logoPath) throws IOException { + BufferedImage image = toBufferedImage(matrix); + Graphics2D gs = image.createGraphics(); + + int ratioWidth = image.getWidth() * 2 / 10; + int ratioHeight = image.getHeight() * 2 / 10; + // 载入logo + Image img = ImageIO.read(new File(logoPath)); + int logoWidth = img.getWidth(null) > ratioWidth ? ratioWidth : img.getWidth(null); + int logoHeight = img.getHeight(null) > ratioHeight ? ratioHeight : img.getHeight(null); + + int x = (image.getWidth() - logoWidth) / 2; + int y = (image.getHeight() - logoHeight) / 2; + + gs.drawImage(img, x, y, logoWidth, logoHeight, null); + gs.setColor(Color.black); + gs.setBackground(Color.WHITE); + gs.dispose(); + img.flush(); + if (!ImageIO.write(image, format, file)) { + throw new IOException("Could not write an image of format " + format + " to " + file); + } + } + + /** + * 压缩目录中的图片到ZIP文件 + * + * @param sourceDir 源目录 + * @param zipFilePath ZIP文件路径 + * @throws IOException 如果压缩过程失败 + */ + public static void zipImages(Path sourceDir, Path zipFilePath) throws IOException { + try (FileOutputStream fos = new FileOutputStream(zipFilePath.toFile()); + ZipArchiveOutputStream zos = new ZipArchiveOutputStream(fos)) { + + Files.walk(sourceDir) + .filter(Files::isRegularFile) + .forEach(file -> { + try { + ZipArchiveEntry zipEntry = new ZipArchiveEntry(file.toFile(), sourceDir.relativize(file).toString()); + zos.putArchiveEntry(zipEntry); + Files.copy(file, zos); + zos.closeArchiveEntry(); + } catch (IOException e) { + e.printStackTrace(); + } + }); + } + } + + 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) ? onColor : offColor); + } + } + return image; + } +} + diff --git a/bonus-modules/bonus-material/src/main/java/com/bonus/material/purchase/controller/PurchaseBindController.java b/bonus-modules/bonus-material/src/main/java/com/bonus/material/purchase/controller/PurchaseBindController.java index eac40258..bb12972f 100644 --- a/bonus-modules/bonus-material/src/main/java/com/bonus/material/purchase/controller/PurchaseBindController.java +++ b/bonus-modules/bonus-material/src/main/java/com/bonus/material/purchase/controller/PurchaseBindController.java @@ -13,6 +13,7 @@ import io.swagger.annotations.ApiOperation; import org.springframework.web.bind.annotation.*; import javax.annotation.Resource; +import javax.servlet.http.HttpServletResponse; import java.util.List; /** @@ -76,4 +77,15 @@ public class PurchaseBindController extends BaseController { public AjaxResult getInfo(PurchaseDto dto) { return purchaseBindService.selectPurchaseCheckInfoById(dto); } + + /** + * 二维码生成下载一体操作 + * @param response + * @param purchaseDto + */ + @PostMapping(value = "/downloadQrCode") + @RequiresPermissions("purchase:bpmPurchaseInfo:query") + public void downloadQrCode(HttpServletResponse response, PurchaseDto purchaseDto) { + purchaseBindService.downloadQrCode(response, purchaseDto); + } } diff --git a/bonus-modules/bonus-material/src/main/java/com/bonus/material/purchase/dto/PurchaseDto.java b/bonus-modules/bonus-material/src/main/java/com/bonus/material/purchase/dto/PurchaseDto.java index c7328e57..b0dc37cc 100644 --- a/bonus-modules/bonus-material/src/main/java/com/bonus/material/purchase/dto/PurchaseDto.java +++ b/bonus-modules/bonus-material/src/main/java/com/bonus/material/purchase/dto/PurchaseDto.java @@ -1,9 +1,12 @@ package com.bonus.material.purchase.dto; import com.bonus.common.core.web.domain.BaseEntity; +import com.fasterxml.jackson.annotation.JsonFormat; import io.swagger.annotations.ApiModelProperty; +import lombok.Builder; import lombok.Data; +import java.util.Date; import java.util.List; /** @@ -11,7 +14,8 @@ import java.util.List; * @create 2024/10/21 13:58 */ @Data -public class PurchaseDto extends BaseEntity { +@Builder +public class PurchaseDto { @ApiModelProperty(value = "id") private String taskId; @@ -63,4 +67,12 @@ public class PurchaseDto extends BaseEntity { @ApiModelProperty(value = "提交绑定数据集合") private List dtoList; + + private String createBy; + + private Date createTime; + + private String updateBy; + + private Date updateTime; } diff --git a/bonus-modules/bonus-material/src/main/java/com/bonus/material/purchase/mapper/PurchaseBindMapper.java b/bonus-modules/bonus-material/src/main/java/com/bonus/material/purchase/mapper/PurchaseBindMapper.java index 036cc052..1b425465 100644 --- a/bonus-modules/bonus-material/src/main/java/com/bonus/material/purchase/mapper/PurchaseBindMapper.java +++ b/bonus-modules/bonus-material/src/main/java/com/bonus/material/purchase/mapper/PurchaseBindMapper.java @@ -2,6 +2,7 @@ package com.bonus.material.purchase.mapper; import com.bonus.material.purchase.dto.PurchaseDto; import com.bonus.material.purchase.vo.PurchaseVo; +import org.apache.ibatis.annotations.Param; import java.util.List; @@ -45,4 +46,31 @@ public interface PurchaseBindMapper { * @return */ int add(PurchaseDto purchaseDto); + + /** + * 查询二维码code + * @param genMonth + * @return + */ + List select(String genMonth); + + /** + * 查询状态 + * @param purchaseDto + * @return + */ + Integer selectStatus(PurchaseDto purchaseDto); + + /** + * 更新状态 + * @param id + * @param purchaseId + */ + void updateStatus(@Param("id") String id, @Param("purchaseId") String purchaseId); + + /** + * 二维码数据保存 + * @param dto + */ + void insert(PurchaseDto dto); } diff --git a/bonus-modules/bonus-material/src/main/java/com/bonus/material/purchase/service/IPurchaseBindService.java b/bonus-modules/bonus-material/src/main/java/com/bonus/material/purchase/service/IPurchaseBindService.java index bbf32b58..a1886cce 100644 --- a/bonus-modules/bonus-material/src/main/java/com/bonus/material/purchase/service/IPurchaseBindService.java +++ b/bonus-modules/bonus-material/src/main/java/com/bonus/material/purchase/service/IPurchaseBindService.java @@ -4,6 +4,7 @@ import com.bonus.common.core.web.domain.AjaxResult; import com.bonus.material.purchase.dto.PurchaseDto; import com.bonus.material.purchase.vo.PurchaseVo; +import javax.servlet.http.HttpServletResponse; import java.util.List; /** @@ -39,4 +40,11 @@ public interface IPurchaseBindService { * @return */ AjaxResult bind(PurchaseDto dto); + + /** + * 下载二维码 + * @param response + * @param purchaseDto + */ + void downloadQrCode(HttpServletResponse response, PurchaseDto purchaseDto); } diff --git a/bonus-modules/bonus-material/src/main/java/com/bonus/material/purchase/service/impl/PurchaseBindServiceImpl.java b/bonus-modules/bonus-material/src/main/java/com/bonus/material/purchase/service/impl/PurchaseBindServiceImpl.java index 3c640cfd..8cf66d18 100644 --- a/bonus-modules/bonus-material/src/main/java/com/bonus/material/purchase/service/impl/PurchaseBindServiceImpl.java +++ b/bonus-modules/bonus-material/src/main/java/com/bonus/material/purchase/service/impl/PurchaseBindServiceImpl.java @@ -1,7 +1,11 @@ package com.bonus.material.purchase.service.impl; +import com.bonus.common.biz.config.BackstageApplication; +import com.bonus.common.biz.config.DateTimeHelper; +import com.bonus.common.biz.config.QrCodeUtils; import com.bonus.common.biz.constant.MaterialConstants; import com.bonus.common.biz.enums.HttpCodeEnum; +import com.bonus.common.core.constant.SecurityConstants; import com.bonus.common.core.utils.DateUtils; import com.bonus.common.core.web.domain.AjaxResult; import com.bonus.common.security.utils.SecurityUtils; @@ -9,23 +13,36 @@ import com.bonus.material.purchase.dto.PurchaseDto; import com.bonus.material.purchase.mapper.PurchaseBindMapper; import com.bonus.material.purchase.service.IPurchaseBindService; import com.bonus.material.purchase.vo.PurchaseVo; +import com.bonus.system.api.RemoteUserService; +import com.bonus.system.api.domain.SysUser; +import com.fasterxml.jackson.databind.DeserializationFeature; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.google.zxing.WriterException; +import lombok.extern.slf4j.Slf4j; import org.apache.commons.collections4.CollectionUtils; import org.springframework.stereotype.Service; import javax.annotation.Resource; -import java.util.Iterator; -import java.util.List; +import javax.servlet.http.HttpServletResponse; +import java.io.*; +import java.util.*; +import java.util.zip.ZipEntry; +import java.util.zip.ZipOutputStream; /** * @Author ma_sh * @create 2024/10/21 18:42 */ @Service +@Slf4j public class PurchaseBindServiceImpl implements IPurchaseBindService { @Resource private PurchaseBindMapper purchaseBindMapper; + @Resource + private RemoteUserService remoteUserService; + /** * 查询所有绑定信息 * @param dto @@ -53,10 +70,35 @@ public class PurchaseBindServiceImpl implements IPurchaseBindService { iterator.remove(); } } + extracted(list); } return list; } + /** + * 远程调用方法抽取 + * @param list + */ + private void extracted(List list) { + for (PurchaseVo purchaseVo : list) { + try { + AjaxResult ajaxResult = remoteUserService.getInfo(Long.parseLong(purchaseVo.getCreateBy()), SecurityConstants.INNER); + if (ajaxResult.isSuccess()) { + // ajaxResult.get("data") 返回的是 LinkedHashMap + LinkedHashMap rawDataList = (LinkedHashMap) ajaxResult.get("data"); + ObjectMapper objectMapper = new ObjectMapper(); + objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); + if (rawDataList != null) { + SysUser sysUser = objectMapper.convertValue(rawDataList, SysUser.class); + purchaseVo.setCreateBy(sysUser.getNickName() == null ? "" : sysUser.getNickName()); + } + } + } catch (IllegalArgumentException e) { + log.error("远程调用查询失败:", e.getMessage()); + } + } + } + /** * 查询绑定信息 * @param dto @@ -110,4 +152,176 @@ public class PurchaseBindServiceImpl implements IPurchaseBindService { } return AjaxResult.error(HttpCodeEnum.FAIL.getCode(), HttpCodeEnum.FAIL.getMsg()); } + + /** + * 下载二维码 + * @param response + * @param purchaseDto + */ + @Override + public void downloadQrCode(HttpServletResponse response, PurchaseDto purchaseDto) { + //生成二维码 + Set addedEntries = new HashSet<>(); + if (purchaseDto.getPurchaseId() == null) { + throw new RuntimeException("内层id为空"); + } + String genMonth = DateTimeHelper.getNowMonth(); + List codeList = purchaseBindMapper.select(genMonth); + try (OutputStream os = response.getOutputStream(); + ZipOutputStream zos = new ZipOutputStream(os)) { + Integer status = purchaseBindMapper.selectStatus(purchaseDto); + if (status == null) { + return; + } + //内层二维码下载 + handlePurchaseId(addedEntries, purchaseDto, codeList, status, zos, genMonth); + zos.flush(); + } catch (WriterException | IOException e) { + e.printStackTrace(); + } + } + + /** + * 内层二维码下载 + * @param purchaseDto + * @param codeList + * @param status + * @param zos + * @param genMonth + * @throws IOException + * @throws WriterException + */ + private void handlePurchaseId(Set addedEntries, PurchaseDto purchaseDto, List codeList, Integer status, ZipOutputStream zos, String genMonth) throws IOException, WriterException { + if (status == 1) { + Select(addedEntries, purchaseDto, zos); + } else { + int num = getInitialNum(codeList); + List details = purchaseBindMapper.getDetails(purchaseDto); + if (CollectionUtils.isNotEmpty(details)) { + PurchaseVo detail = details.get(0); + purchaseDto.setTaskId(detail.getTaskId().toString()); + getString(addedEntries, purchaseDto, genMonth, num, zos, detail.getMaterialModel(), detail.getMaterialName(), detail.getTypeId(), detail.getCheckNum()); + extractedUpStatus(purchaseDto); + } + } + } + + /** + * 方法抽取 + * @param purchaseDto + * @param genMonth + * @param num + * @param zos + * @param materialModel + * @param materialName + * @param typeId + * @param checkNum + * @throws WriterException + * @throws IOException + */ + private void getString(Set addedEntries, PurchaseDto purchaseDto, String genMonth, int num, ZipOutputStream zos, String materialModel, String materialName, Integer typeId, Integer checkNum) throws WriterException, IOException { + for (int j = 1; j <= checkNum; j++) { + genMonth = genMonth.replace("-", ""); + String code = genMonth + "-" + String.format("%5d", num + j).replace(" ", "0"); + // 新购管理-二维码打印-新增 + String url = BackstageApplication.getUrl() + "backstage/machine/qrCodePage?qrcode=" + code; + // // 二维码的图片格式 + String format = "jpg"; + //设置路径 + String mkdirsName = "images"; + // linux 系统路径 + String saveDirectory = "/data/imw/" + mkdirsName + "/"; + String os = System.getProperty("os.name"); + if (os.toLowerCase().startsWith("win")) { + //本地路径 + saveDirectory = "D://files/" + mkdirsName + "/"; + } + // 生成二维码 + File files = new File(saveDirectory); + if (!files.exists()) { + files.mkdirs(); + } + QrCodeUtils.generateQRImage(url, saveDirectory, code + ".jpg", format); + String qrUrl = saveDirectory + code + ".jpg"; + PurchaseDto dto = PurchaseDto.builder().taskId(purchaseDto.getTaskId()).typeId(typeId).qrCode(code).qrUrl(qrUrl).createBy(SecurityUtils.getUserId().toString()).build(); + purchaseBindMapper.insert(dto); + extracted( addedEntries, zos, materialModel, materialName, code, qrUrl); + } + } + + /** + * 修改任务表方法抽取 + * @param purchaseDto + */ + private void extractedUpStatus(PurchaseDto purchaseDto) { + //修改任务表的是否下载状态 + purchaseBindMapper.updateStatus(purchaseDto.getTaskId(), purchaseDto.getPurchaseId()); + } + + /** + * 获取初始化num + * @param codeList + * @return + */ + private int getInitialNum(List codeList) { + if (com.alibaba.nacos.common.utils.CollectionUtils.isNotEmpty(codeList)) { + PurchaseVo purchaseVo = codeList.get(0); + return Integer.parseInt(purchaseVo.getQrCode().split("-")[1]); + } + return 0; + } + + /** + * 查询方法抽取 + * @param purchaseDto + * @param zos + * @throws IOException + */ + private void Select(Set addedEntries, PurchaseDto purchaseDto, ZipOutputStream zos) throws IOException { + List list = purchaseBindMapper.selectPurchaseCheckInfoById(purchaseDto); + if (com.alibaba.nacos.common.utils.CollectionUtils.isNotEmpty(list)) { + for (PurchaseVo purchaseVo : list) { + String materialModel = purchaseVo.getMaterialModel(); + String materialName = purchaseVo.getMaterialName(); + String path = purchaseVo.getQrUrl(); + String qrCode = purchaseVo.getQrCode(); + path = path.replace("filePath", "/data/imw"); + extracted(addedEntries, zos, materialModel, materialName, qrCode, path); + } + } + } + + /** + * 二维码下载方法抽取 + * @param zos + * @param materialModel + * @param materialName + * @param code + * @param path + * @throws IOException + */ + private void extracted(Set addedEntries, ZipOutputStream zos, String materialModel, String materialName, String code, String path) throws IOException { + // 判断路径是否存在 + File imageFile = new File(path); + if (!imageFile.exists()) { + return; + } + String entryName = "[" + materialModel + "-" + materialName + "]" + code + ".jpg"; + if (addedEntries.contains(entryName)) { + System.out.println("Duplicate entry skipped: " + entryName); + return; + } + addedEntries.add(entryName); + + zos.setLevel(0); + zos.putNextEntry(new ZipEntry(entryName)); + try (InputStream fis = new FileInputStream(imageFile)) { + byte[] buffer = new byte[1024]; + int r; + while ((r = fis.read(buffer)) != -1) { + zos.write(buffer, 0, r); + } + } + zos.closeEntry(); + } } diff --git a/bonus-modules/bonus-material/src/main/java/com/bonus/material/purchase/vo/PurchaseVo.java b/bonus-modules/bonus-material/src/main/java/com/bonus/material/purchase/vo/PurchaseVo.java index 99d1e42d..76bd58e0 100644 --- a/bonus-modules/bonus-material/src/main/java/com/bonus/material/purchase/vo/PurchaseVo.java +++ b/bonus-modules/bonus-material/src/main/java/com/bonus/material/purchase/vo/PurchaseVo.java @@ -102,6 +102,9 @@ public class PurchaseVo { @ApiModelProperty(value = "出厂编号") private String outFacCode; - @ApiModelProperty(value = "二维码") + @ApiModelProperty(value = "二维码code") private String qrCode; + + @ApiModelProperty(value = "二维码路径") + private String qrUrl; } diff --git a/bonus-modules/bonus-material/src/main/resources/mapper/material/purchase/PurchaseBindMapper.xml b/bonus-modules/bonus-material/src/main/resources/mapper/material/purchase/PurchaseBindMapper.xml index 490968c2..ba191d87 100644 --- a/bonus-modules/bonus-material/src/main/resources/mapper/material/purchase/PurchaseBindMapper.xml +++ b/bonus-modules/bonus-material/src/main/resources/mapper/material/purchase/PurchaseBindMapper.xml @@ -44,6 +44,48 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" + + INSERT INTO purchase_macode_info + + + qr_code, + + + type_id, + + + qr_url, + + + task_id, + + + create_by, + + create_time, + del_flag + + + + #{qrCode}, + + + #{typeId}, + + + #{qrUrl}, + + + #{id}, + + + #{createBy}, + + NOW(), + 0 + + + UPDATE purchase_check_details SET input_num = #{purchaseNum} @@ -65,6 +107,18 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" type_id = #{typeId} + + UPDATE purchase_check_details + SET is_download = '1' + WHERE del_flag = '0' + + and task_id = #{id} + + + and id = #{purchaseId} + + + SELECT pm.task_id AS taskId, + pcd.id AS purchaseId, mt1.type_name AS materialName, mt.type_name AS materialModel, pm.ma_code AS maCode, @@ -113,7 +168,8 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" pm.type_id AS typeId, pm.out_fac_code AS outFacCode, pcd.production_time AS productDate, - pm.qr_code AS qrCode + pm.qr_code AS qrCode, + pm.qr_url AS qrUrl FROM purchase_macode_info pm LEFT JOIN purchase_check_details pcd ON pm.task_id = pcd.task_id @@ -121,12 +177,15 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" LEFT JOIN ma_type mt1 ON mt.parent_id = mt1.type_id WHERE 1=1 - + AND pm.task_id = #{taskId} - + AND pm.type_id = #{typeId} + + AND pcd.id = #{purchaseId} + SELECT - pcd.task_id as taskId, - pcd.status as STATUS + qr_code as qrCode FROM - purchase_check_details pcd - where pcd.task_id = #{taskId} + purchase_macode_info + WHERE + DATE_FORMAT(create_time, '%Y-%m') = #{genMonth} + ORDER BY + qr_code DESC + + \ No newline at end of file