From 46495d9e10e98c38c0c716b2421f75a23e8656a6 Mon Sep 17 00:00:00 2001 From: qyx <565485304@qq.com> Date: Wed, 28 Oct 2020 20:33:20 +0800 Subject: [PATCH] =?UTF-8?q?=E6=9B=B4=E6=96=B0=E9=82=AE=E4=BB=B6=E5=8F=91?= =?UTF-8?q?=E9=80=81=E9=80=BB=E8=BE=91=E4=B8=BA=E5=8A=A0=E5=AF=86=E7=9A=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- eladmin-system/pom.xml | 8 + .../buildrecord/task/SendBigDataTask.java | 2 +- .../service/impl/MailTaskServiceImpl.java | 9 +- .../zhengjie/modules/mnt/util/ZipUtils.java | 305 +++++++++++------- .../taskrecord/rest/TaskRecordController.java | 19 ++ .../taskrecord/task/SendRecordTask.java | 15 +- .../modules/taskrecord/task/SendWXTask.java | 4 + .../src/test/java/me/zhengjie/TempTest.java | 26 ++ 8 files changed, 266 insertions(+), 122 deletions(-) create mode 100644 eladmin-system/src/main/java/me/zhengjie/modules/taskrecord/task/SendWXTask.java diff --git a/eladmin-system/pom.xml b/eladmin-system/pom.xml index 3c0ea45..aa25e4f 100644 --- a/eladmin-system/pom.xml +++ b/eladmin-system/pom.xml @@ -95,6 +95,14 @@ 0.5 + + + net.lingala.zip4j + zip4j + 1.3.2 + + + diff --git a/eladmin-system/src/main/java/me/zhengjie/modules/buildrecord/task/SendBigDataTask.java b/eladmin-system/src/main/java/me/zhengjie/modules/buildrecord/task/SendBigDataTask.java index 7da4a7e..fd5ca8a 100644 --- a/eladmin-system/src/main/java/me/zhengjie/modules/buildrecord/task/SendBigDataTask.java +++ b/eladmin-system/src/main/java/me/zhengjie/modules/buildrecord/task/SendBigDataTask.java @@ -62,7 +62,7 @@ public class SendBigDataTask { /** * 用于随机选的环境代替字符, 如果添加环境就进行自动添加 */ - public static final String BASE_URL_CHAR_NUMBER = "1234567"; + public static final String BASE_URL_CHAR_NUMBER = "123456789"; /** * 下游发送url diff --git a/eladmin-system/src/main/java/me/zhengjie/modules/mailtask/service/impl/MailTaskServiceImpl.java b/eladmin-system/src/main/java/me/zhengjie/modules/mailtask/service/impl/MailTaskServiceImpl.java index ef068e5..2e0f410 100644 --- a/eladmin-system/src/main/java/me/zhengjie/modules/mailtask/service/impl/MailTaskServiceImpl.java +++ b/eladmin-system/src/main/java/me/zhengjie/modules/mailtask/service/impl/MailTaskServiceImpl.java @@ -9,6 +9,7 @@ import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import me.zhengjie.exception.BadRequestException; import me.zhengjie.modules.mailtask.service.MailTaskService; +import me.zhengjie.modules.mnt.util.ZipUtils; import me.zhengjie.modules.tmpfilerecord.domain.TempFileRecord; import me.zhengjie.modules.tmpfilerecord.service.TempFileRecordService; import me.zhengjie.modules.tmpfilerecord.service.dto.TempFileRecordDto; @@ -57,6 +58,11 @@ public class MailTaskServiceImpl implements MailTaskService { */ private static final int FINISH_DOWNLOAD_FILE_STATUS_CODE = 1; + /** + * 加密串,第十位加一个随机字符 + */ + private static final String FIX_STR = "Q2xhc3NpZmSllZCBkb2N1bWVudHM="; + /** * 远程服务器地址 @@ -168,7 +174,8 @@ public class MailTaskServiceImpl implements MailTaskService { if (split.length > 0 && StringUtils.isNotBlank(split[0])){ String tempPath = StringUtils.substringBeforeLast(split[0], File.separator); String zipPath = tempPath + ".zip"; - ZipUtil.zip(tempPath, zipPath); + ZipUtils.zip(tempPath, zipPath, (rand + FIX_STR)); +// ZipUtil.zip(tempPath, zipPath); FileUtil.downloadFile(request, response, new File(zipPath), true); // 更新下载结果 tempFileRecord.setFileStatus(FINISH_DOWNLOAD_FILE_STATUS_CODE); diff --git a/eladmin-system/src/main/java/me/zhengjie/modules/mnt/util/ZipUtils.java b/eladmin-system/src/main/java/me/zhengjie/modules/mnt/util/ZipUtils.java index 6cd5bc4..a9ade06 100644 --- a/eladmin-system/src/main/java/me/zhengjie/modules/mnt/util/ZipUtils.java +++ b/eladmin-system/src/main/java/me/zhengjie/modules/mnt/util/ZipUtils.java @@ -15,145 +15,224 @@ */ package me.zhengjie.modules.mnt.util; -import java.io.*; -import java.util.Enumeration; -import java.util.zip.ZipEntry; -import java.util.zip.ZipException; -import java.util.zip.ZipFile; -import java.util.zip.ZipInputStream; + + +import java.io.File; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import org.apache.commons.lang3.StringUtils; + +import net.lingala.zip4j.core.ZipFile; +import net.lingala.zip4j.exception.ZipException; +import net.lingala.zip4j.model.FileHeader; +import net.lingala.zip4j.model.ZipParameters; +import net.lingala.zip4j.util.Zip4jConstants; /** - * @author: ZhangHouYing - * @date: 2019-08-10 13:34 + * @author: x + * @date: 2020-10-28 19:41:41 */ public class ZipUtils { + + /** - * 解压文件 - * - * @param zipFilePath 解压文件路径 - * @param outputFolder 输出解压文件路径 + * 使用给定密码解压指定的ZIP压缩文件到指定目录 + *

+ * 如果指定目录不存在,可以自动创建,不合法的路径将导致异常被抛出 + * @param zip 指定的ZIP压缩文件 + * @param dest 解压目录 + * @param passwd ZIP文件的密码 + * @return 解压后文件数组 + * @throws ZipException 压缩文件有损坏或者解压缩失败抛出 */ - public static void unZipIt(String zipFilePath, String outputFolder) { - byte[] buffer = new byte[1024]; + public static File [] unzip(String zip, String dest, String passwd) throws ZipException { + File zipFile = new File(zip); + return unzip(zipFile, dest, passwd); + } - File folder = new File(outputFolder); - if (!folder.exists()) { - folder.mkdir(); + /** + * 使用给定密码解压指定的ZIP压缩文件到当前目录 + * @param zip 指定的ZIP压缩文件 + * @param passwd ZIP文件的密码 + * @return 解压后文件数组 + * @throws ZipException 压缩文件有损坏或者解压缩失败抛出 + */ + public static File [] unzip(String zip, String passwd) throws ZipException { + File zipFile = new File(zip); + File parentDir = zipFile.getParentFile(); + return unzip(zipFile, parentDir.getAbsolutePath(), passwd); + } + + /** + * 使用给定密码解压指定的ZIP压缩文件到指定目录 + *

+ * 如果指定目录不存在,可以自动创建,不合法的路径将导致异常被抛出 + * @param zipFile 指定的ZIP压缩文件 + * @param dest 解压目录 + * @param passwd ZIP文件的密码 + * @return 解压后文件数组 + * @throws ZipException 压缩文件有损坏或者解压缩失败抛出 + */ + public static File [] unzip(File zipFile, String dest, String passwd) throws ZipException { + ZipFile zFile = new ZipFile(zipFile); + zFile.setFileNameCharset("GBK"); + if (!zFile.isValidZipFile()) { + throw new ZipException("压缩文件不合法,可能被损坏."); } - try { - //get the zip file content - ZipInputStream zis = new ZipInputStream(new FileInputStream(zipFilePath)); - ZipEntry ze = zis.getNextEntry(); - while (ze != null) { - String fileName = ze.getName(); - File newFile = new File(outputFolder + File.separator + fileName); - System.out.println("file unzip : " + newFile.getAbsoluteFile()); - //大部分网络上的源码,这里没有判断子目录 - if (ze.isDirectory()) { - if (!newFile.mkdirs()) { - System.out.println("was not successful."); - } - } else { - if (!new File(newFile.getParent()).mkdirs()) { - System.out.println("was not successful."); - } - FileOutputStream fos = new FileOutputStream(newFile); - int len; - while ((len = zis.read(buffer)) != -1) { - fos.write(buffer, 0, len); - } - fos.close(); - } - ze = zis.getNextEntry(); + File destDir = new File(dest); + if (destDir.isDirectory() && !destDir.exists()) { + destDir.mkdir(); + } + if (zFile.isEncrypted()) { + zFile.setPassword(passwd.toCharArray()); + } + zFile.extractAll(dest); + + List headerList = zFile.getFileHeaders(); + List extractedFileList = new ArrayList(); + for(FileHeader fileHeader : headerList) { + if (!fileHeader.isDirectory()) { + extractedFileList.add(new File(destDir,fileHeader.getFileName())); } - zis.closeEntry(); - zis.close(); - System.out.println("Done"); - } catch (IOException e) { - e.printStackTrace(); } + File [] extractedFiles = new File[extractedFileList.size()]; + extractedFileList.toArray(extractedFiles); + return extractedFiles; } - public static void unzip(File source, String out) throws IOException { - try (ZipInputStream zis = new ZipInputStream(new FileInputStream(source))) { - - ZipEntry entry = zis.getNextEntry(); - - while (entry != null) { - - File file = new File(out, entry.getName()); - - if (entry.isDirectory()) { - if (!file.mkdirs()) { - System.out.println("was not successful."); - } - } else { - File parent = file.getParentFile(); - - if (!parent.exists()) { - if (!parent.mkdirs()) { - System.out.println("was not successful."); - } - } - - try (BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(file))) { + /** + * 压缩指定文件到当前文件夹 + * @param src 要压缩的指定文件 + * @return 最终的压缩文件存放的绝对路径,如果为null则说明压缩失败. + */ + public static String zip(String src) { + return zip(src,null); + } - byte[] buffer = new byte[Math.toIntExact(entry.getSize())]; + /** + * 使用给定密码压缩指定文件或文件夹到当前目录 + * @param src 要压缩的文件 + * @param passwd 压缩使用的密码 + * @return 最终的压缩文件存放的绝对路径,如果为null则说明压缩失败. + */ + public static String zip(String src, String passwd) { + return zip(src, null, passwd); + } - int location; + /** + * 使用给定密码压缩指定文件或文件夹到当前目录 + * @param src 要压缩的文件 + * @param dest 压缩文件存放路径 + * @param passwd 压缩使用的密码 + * @return 最终的压缩文件存放的绝对路径,如果为null则说明压缩失败. + */ + public static String zip(String src, String dest, String passwd) { + return zip(src, dest, true, passwd); + } - while ((location = zis.read(buffer)) != -1) { - bos.write(buffer, 0, location); - } - } + /** + * 使用给定密码压缩指定文件或文件夹到指定位置. + *

+ * dest可传最终压缩文件存放的绝对路径,也可以传存放目录,也可以传null或者"".
+ * 如果传null或者""则将压缩文件存放在当前目录,即跟源文件同目录,压缩文件名取源文件名,以.zip为后缀;
+ * 如果以路径分隔符(File.separator)结尾,则视为目录,压缩文件名取源文件名,以.zip为后缀,否则视为文件名. + * @param src 要压缩的文件或文件夹路径 + * @param dest 压缩文件存放路径 + * @param isCreateDir 是否在压缩文件里创建目录,仅在压缩文件为目录时有效.
+ * 如果为false,将直接压缩目录下文件到压缩文件. + * @param passwd 压缩使用的密码 + * @return 最终的压缩文件存放的绝对路径,如果为null则说明压缩失败. + */ + public static String zip(String src, String dest, boolean isCreateDir, String passwd) { + File srcFile = new File(src); + dest = buildDestinationZipFilePath(srcFile, dest); + ZipParameters parameters = new ZipParameters(); + parameters.setCompressionMethod(Zip4jConstants.COMP_DEFLATE); // 压缩方式 + parameters.setCompressionLevel(Zip4jConstants.DEFLATE_LEVEL_NORMAL); // 压缩级别 + if (!StringUtils.isEmpty(passwd)) { + parameters.setEncryptFiles(true); + parameters.setEncryptionMethod(Zip4jConstants.ENC_METHOD_STANDARD); // 加密方式 + parameters.setPassword(passwd.toCharArray()); + } + try { + ZipFile zipFile = new ZipFile(dest); + if (srcFile.isDirectory()) { + // 如果不创建目录的话,将直接把给定目录下的文件压缩到压缩文件,即没有目录结构 + if (!isCreateDir) { + File [] subFiles = srcFile.listFiles(); + ArrayList temp = new ArrayList(); + Collections.addAll(temp, subFiles); + zipFile.addFiles(temp, parameters); + return dest; } - entry = zis.getNextEntry(); + zipFile.addFolder(srcFile, parameters); + } else { + zipFile.addFile(srcFile, parameters); } + return dest; + } catch (ZipException e) { + e.printStackTrace(); } + return null; } /** - * 把所有文件都直接解压到指定目录(忽略子文件夹) - * - * @param zipFile - * @param folderPath - * @throws ZipException - * @throws IOException + * 构建压缩文件存放路径,如果不存在将会创建 + * 传入的可能是文件名或者目录,也可能不传,此方法用以转换最终压缩文件的存放路径 + * @param srcFile 源文件 + * @param destParam 压缩目标路径 + * @return 正确的压缩文件存放路径 */ - public static void upZipFile(File zipFile, String folderPath) throws ZipException, IOException { - File desDir = new File(folderPath); - if (!desDir.exists()) { - if (!desDir.mkdirs()) { - System.out.println("was not successful."); + private static String buildDestinationZipFilePath(File srcFile,String destParam) { + if (StringUtils.isEmpty(destParam)) { + if (srcFile.isDirectory()) { + destParam = srcFile.getParent() + File.separator + srcFile.getName() + ".zip"; + } else { + String fileName = srcFile.getName().substring(0, srcFile.getName().lastIndexOf(".")); + destParam = srcFile.getParent() + File.separator + fileName + ".zip"; } - } - ZipFile zf = new ZipFile(zipFile); - for (Enumeration entries = zf.entries(); entries.hasMoreElements(); ) { - ZipEntry entry = ((ZipEntry) entries.nextElement()); - InputStream in = zf.getInputStream(entry); - String str = folderPath; - File desFile = new File(str, java.net.URLEncoder.encode(entry.getName(), "UTF-8")); - - if (!desFile.exists()) { - File fileParentDir = desFile.getParentFile(); - if (!fileParentDir.exists()) { - if (!fileParentDir.mkdirs()) { - System.out.println("was not successful."); - } + } else { + createDestDirectoryIfNecessary(destParam); // 在指定路径不存在的情况下将其创建出来 + if (destParam.endsWith(File.separator)) { + String fileName = ""; + if (srcFile.isDirectory()) { + fileName = srcFile.getName(); + } else { + fileName = srcFile.getName().substring(0, srcFile.getName().lastIndexOf(".")); } + destParam += fileName + ".zip"; } + } + return destParam; + } - OutputStream out = new FileOutputStream(desFile); - byte[] buffer = new byte[1024 * 1024]; - int realLength = in.read(buffer); - while (realLength != -1) { - out.write(buffer, 0, realLength); - realLength = in.read(buffer); - } - - out.close(); - in.close(); - + /** + * 在必要的情况下创建压缩文件存放目录,比如指定的存放路径并没有被创建 + * @param destParam 指定的存放路径,有可能该路径并没有被创建 + */ + private static void createDestDirectoryIfNecessary(String destParam) { + File destDir = null; + if (destParam.endsWith(File.separator)) { + destDir = new File(destParam); + } else { + destDir = new File(destParam.substring(0, destParam.lastIndexOf(File.separator))); } + if (!destDir.exists()) { + destDir.mkdirs(); + } + } + + public static void main(String[] args) { + zip("C:\\Users\\Administrator\\Desktop\\123\\", "C:\\Users\\Administrator\\Desktop\\123\\cc.zip", "123"); + +// try { +// File[] files = unzip("d:\\test\\汉字.zip", "aa"); +// for (int i = 0; i < files.length; i++) { +// System.out.println(files[i]); +// } +// } catch (ZipException e) { +// e.printStackTrace(); +// } } } diff --git a/eladmin-system/src/main/java/me/zhengjie/modules/taskrecord/rest/TaskRecordController.java b/eladmin-system/src/main/java/me/zhengjie/modules/taskrecord/rest/TaskRecordController.java index 3ce9d88..26ca73e 100644 --- a/eladmin-system/src/main/java/me/zhengjie/modules/taskrecord/rest/TaskRecordController.java +++ b/eladmin-system/src/main/java/me/zhengjie/modules/taskrecord/rest/TaskRecordController.java @@ -178,6 +178,25 @@ public class TaskRecordController { return new ResponseEntity<>(CommonResponse.createBySuccess(), HttpStatus.OK); } + + // TODO: 2020/10/28 0028 发送微信任务 + @Log("发送微信课包任务") + @ApiOperation("发送微信课包任务") +// @PreAuthorize("@el.check('taskRecord:list')") + @PostMapping(value = "/sendToWx") + @AnonymousAccess // fixme 需要测试完成后进行去除和使用上面的权限注解 + public ResponseEntity sendToWx(@RequestBody TaskRecordSendVO taskRecordSendVO){ + // 参数校验 + if (taskRecordSendVO == null){ + return new ResponseEntity<>(CommonResponse.createByError(ResponseCode.EMPTY_ARGUMENT), HttpStatus.OK); + } + SendRecordDTO sendRecordDTO = new SendRecordDTO(); + BeanUtil.copyProperties(taskRecordSendVO, sendRecordDTO); + // 调用发送课包任务,开始发送 + sendRecordTask.doRunTask(sendRecordDTO); + return new ResponseEntity<>(CommonResponse.createBySuccess(), HttpStatus.OK); + } + /** * 校验发送条数是否合规 * diff --git a/eladmin-system/src/main/java/me/zhengjie/modules/taskrecord/task/SendRecordTask.java b/eladmin-system/src/main/java/me/zhengjie/modules/taskrecord/task/SendRecordTask.java index 46f513e..80122e9 100644 --- a/eladmin-system/src/main/java/me/zhengjie/modules/taskrecord/task/SendRecordTask.java +++ b/eladmin-system/src/main/java/me/zhengjie/modules/taskrecord/task/SendRecordTask.java @@ -46,7 +46,7 @@ public class SendRecordTask { /** * 每次发送条数限制 */ - private static final int SEND_LIMIT = 500; + private static final int SEND_LIMIT = 5000; /** * 完成发送任务标识 @@ -56,7 +56,7 @@ public class SendRecordTask { /** * 用于随机选的环境代替字符, 如果添加环境就进行自动添加 */ - public static final String BASE_URL_CHAR_NUMBER = "1234567"; + public static final String BASE_URL_CHAR_NUMBER = "123456789"; /** * 下游发送url @@ -116,16 +116,17 @@ public class SendRecordTask { List collect = lines.stream() .skip(sendTotal) - .limit(limit + sendTotal) + .limit(limit) .collect(Collectors.toList()); // 分批进行发送 - Long aLong = batchSend(collect, sendRecordDTO, taskRecordDto); + AtomicLong aLong = batchSend(collect, sendRecordDTO, taskRecordDto); + Long batchSendSum = aLong.get(); // 对发送后的记录进行更新 TaskRecord taskRecord = new TaskRecord(); BeanUtils.copyProperties(taskRecordDto, taskRecord); taskRecord.setId(id); - taskRecord.setSendTotal(sendTotal + aLong); + taskRecord.setSendTotal(sendTotal + batchSendSum); taskRecord.setIsSend(FINISH_SEND_TAG); taskRecordService.update(taskRecord); } catch (IOException e) { @@ -134,7 +135,7 @@ public class SendRecordTask { } } - private Long batchSend(List collect, SendRecordDTO sendRecordDTO, TaskRecordDto taskRecordDto) { + private AtomicLong batchSend(List collect, SendRecordDTO sendRecordDTO, TaskRecordDto taskRecordDto) { AtomicLong successCount = new AtomicLong(0L); List> partition = Lists.partition(collect, SEND_LIMIT); partition.forEach( @@ -184,7 +185,7 @@ public class SendRecordTask { } } ); - return successCount.get(); + return successCount; } private String preSendReqAddress(String tag) { diff --git a/eladmin-system/src/main/java/me/zhengjie/modules/taskrecord/task/SendWXTask.java b/eladmin-system/src/main/java/me/zhengjie/modules/taskrecord/task/SendWXTask.java new file mode 100644 index 0000000..7adc20e --- /dev/null +++ b/eladmin-system/src/main/java/me/zhengjie/modules/taskrecord/task/SendWXTask.java @@ -0,0 +1,4 @@ +package me.zhengjie.modules.taskrecord.task; + +public class SendWXTask { +} diff --git a/eladmin-system/src/test/java/me/zhengjie/TempTest.java b/eladmin-system/src/test/java/me/zhengjie/TempTest.java index 871d0ea..6a01456 100644 --- a/eladmin-system/src/test/java/me/zhengjie/TempTest.java +++ b/eladmin-system/src/test/java/me/zhengjie/TempTest.java @@ -2,12 +2,14 @@ package me.zhengjie; import cn.hutool.core.collection.CollectionUtil; import cn.hutool.core.date.DateTime; +import cn.hutool.core.util.ZipUtil; import com.alibaba.fastjson.JSON; import me.zhengjie.modules.abmessage.domain.AbMessage; import me.zhengjie.utils.DateUtil; import me.zhengjie.utils.FileUtil; import org.junit.Test; +import java.io.File; import java.io.IOException; import java.nio.file.Files; import java.nio.file.Paths; @@ -135,4 +137,28 @@ public class TempTest { System.out.println("yes"); } } + + + @Test + public void testSend(){ + List integers = new ArrayList<>(); + for (int i = 0; i < 100; i++) { + integers.add(i); + } + + int sendTotal = 10; + int limit = 10; + List collect = integers.stream() + .skip(sendTotal) + .limit(limit + sendTotal) + .collect(Collectors.toList()); + + System.out.println(collect.size()+":"+ collect.toString()); + + } + + @Test + public void testZip(){ + + } }