Browse Source

生成码数据

luyanwen 3 years ago
parent
commit
a83ea39b60

+ 7 - 0
abi-cloud-qr-platform-server/pom.xml

@@ -130,6 +130,13 @@
             <artifactId>spring-boot-starter-amqp</artifactId>
         </dependency>
 
+        <!--生成加密压缩包依赖-->
+        <dependency>
+            <groupId>net.lingala.zip4j</groupId>
+            <artifactId>zip4j</artifactId>
+            <version>1.3.1</version>
+        </dependency>
+
         <!-- redisson -->
         <dependency>
             <groupId>org.redisson</groupId>

+ 175 - 55
abi-cloud-qr-platform-server/src/main/java/com/abi/qms/platform/infrastructure/mq/GenerateCodeConsumer.java

@@ -1,25 +1,32 @@
 package com.abi.qms.platform.infrastructure.mq;
 
+import cn.hutool.core.io.FileUtil;
 import cn.hutool.core.io.file.FileWriter;
 import cn.hutool.core.util.ZipUtil;
-import com.abi.qms.platform.dao.entity.QrData;
-import com.abi.qms.platform.dao.entity.QrInnerData;
-import com.abi.qms.platform.dao.entity.QrPackage;
-import com.abi.qms.platform.dao.entity.QrRepertorySerialNumber;
+import com.abi.qms.platform.dao.entity.*;
 import com.abi.qms.platform.dao.enums.QrFormatUrlEnum;
 import com.abi.qms.platform.dao.enums.QrPackageGenerateStatusEnum;
 import com.abi.qms.platform.dao.enums.QrRepertoryTypeEnum;
+import com.abi.qms.platform.dao.mapper.QrPackageBatchMapper;
 import com.abi.qms.platform.dao.mapper.QrPackageMapper;
 import com.abi.qms.platform.dao.mapper.QrRepertoryMapper;
 import com.abi.qms.platform.dao.mapper.QrRepertorySerialNumberMapper;
+import com.abi.qms.platform.dao.tablestore.entity.QrCode;
 import com.abi.qms.platform.dao.vo.result.QrPackageVO;
 import com.abi.qms.platform.dao.vo.result.QrRepertoryColumnVO;
 import com.abi.qms.platform.dao.vo.result.QrRepertoryVO;
 import com.abi.qms.platform.infrastructure.qr.build.parent.SerialBuildCode;
 import com.abi.qms.platform.infrastructure.util.BuildCodeUtil;
-import com.abi.qms.platform.service.QrDataService;
 import com.abi.qms.platform.service.QrPackageService;
+import com.abi.task.common.tablestore.TableStorePlusUtils;
+import com.abi.task.common.tablestore.common.TableStoreEntity;
+import com.abi.task.common.tablestore.entity.DemoEntity;
+import com.abi.task.common.utils.TableStoreUtils;
+import com.alibaba.fastjson.JSON;
+import com.alibaba.fastjson.JSONObject;
+import com.alicloud.openservices.tablestore.model.search.query.BoolQuery;
 import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.baomidou.mybatisplus.core.toolkit.IdWorker;
 import com.rabbitmq.client.Channel;
 import lombok.SneakyThrows;
 import lombok.extern.slf4j.Slf4j;
@@ -33,9 +40,15 @@ import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.beans.factory.annotation.Value;
 import org.springframework.messaging.Message;
 import org.springframework.stereotype.Component;
+import net.lingala.zip4j.core.ZipFile;
+import net.lingala.zip4j.exception.ZipException;
+import net.lingala.zip4j.model.ZipParameters;
+import net.lingala.zip4j.util.Zip4jConstants;
 
 import java.io.File;
+import java.io.IOException;
 import java.time.LocalDateTime;
+import java.time.format.DateTimeFormatter;
 import java.util.*;
 import java.util.stream.Collectors;
 
@@ -61,8 +74,8 @@ public class GenerateCodeConsumer {
 	@Autowired
 	private QrRepertorySerialNumberMapper qrRepertorySerialNumberMapper;
 
-	@Autowired
-	private QrDataService qrDataService;
+//	@Autowired
+//	private QrDataService qrDataService;
 
 	@Autowired
 	private QrPackageService qrPackageService;
@@ -70,6 +83,21 @@ public class GenerateCodeConsumer {
 	@Autowired
 	private RedissonClient redissonClient;
 
+	@Autowired
+	private TableStorePlusUtils tableStorePlusUtils;
+
+	@Autowired
+    private QrPackageBatchMapper qrPackageBatchMapper;
+
+	//生成码数据
+	final List<QrData> qrDataList = new LinkedList<>();
+
+	//生成码包路径
+	private File file = new File(this.getClass().getResource("/").getPath()+"/code");
+
+	//批量添加文件
+	private ArrayList<File> files = new ArrayList<>();
+
 	/** 允许单个码生成重复的次数 */
 	private static final int REPEAT_BUILD_CODE_TIMES = 10;
 
@@ -82,7 +110,8 @@ public class GenerateCodeConsumer {
 
 	@SneakyThrows
 	@RabbitHandler
-	public void onMessage(QrPackage qrPackage, Message message, Channel channel) {
+	public void onMessage(String objeQrPackage, Message message, Channel channel) {
+		QrPackage qrPackage = JSONObject.parseObject(objeQrPackage,QrPackage.class);
 		try {
 			// 生成码
 			loopGenerateCode(qrPackage);
@@ -126,48 +155,99 @@ public class GenerateCodeConsumer {
 		// child_index用于标记同一列的第几个码格式变量
 		Map<String, QrRepertorySerialNumber> qrRepertorySerialNumberMap = new LinkedHashMap<>();
 
-		// 处理url和流水号
+		// 处理url和流水号--后续生成码要用到
 		getUrlAndSerialNumber(qrRepertoryColumnList, qrRepertoryId, deptUrl, urlMap, qrRepertorySerialNumberMap);
 
-		// 申请数量、批次号、创建时间、重复次数
-		Long qrNumber = qrPackageVo.getQrNumber();
-//		String batchNumber = qrPackageVo.getBatchNumber();
-		LocalDateTime localDateTime = LocalDateTime.now();
-		int repeatTimes = 0;
-
-		// 循环生成码
-//		loopGenerateCode(qrRepertoryColumnList, qrRepertoryId, urlMap, qrRepertorySerialNumberMap, qrNumber, batchNumber, localDateTime, repeatTimes);
-
-		// 更新码库流水号
-		if (!qrRepertorySerialNumberMap.isEmpty()) {
-			for (Map.Entry<String, QrRepertorySerialNumber> entry : qrRepertorySerialNumberMap.entrySet()) {
-				QrRepertorySerialNumber qrRepertorySerialNumber = entry.getValue();
-				QrRepertorySerialNumber updateSerialNumber = new QrRepertorySerialNumber()
-						.setId(qrRepertorySerialNumber.getId())
-						.setSerialNumber(qrRepertorySerialNumber.getSerialNumber());
-				qrRepertorySerialNumberMapper.updateById(updateSerialNumber);
-			}
-		}
-
-		// 创建码文件
-		createCodeFile(qrPackage, qrRepertory);
+		//码包id
+        //根据码包id查询,获取批次号
+		QueryWrapper<QrPackageBatch> param = new QueryWrapper<>();
+		param.eq("package_id", qrPackageVo.getId());
+		List<QrPackageBatch> qrPackageBatches = qrPackageBatchMapper.selectList(param);
+
+		for (QrPackageBatch qrPackageBatch:qrPackageBatches) {
+			// 这批下的申请数量
+			Long qrNumber = qrPackageBatch.getBatchQrNumber();
+			//批次号
+			String batchNumber = qrPackageBatch.getBatchNumber();
+			//重复次数
+			int repeatTimes = 0;
+
+			/**
+			 * qrRepertoryColumnList  码库的列
+			 * qrRepertoryId 码库id
+			 * urlMap 存放每列的url
+			 * qrRepertorySerialNumberMap 用于标记同一列的第几个码格式变量
+			 * qrNumber 码数量
+			 * batchNumber 批次号
+			 * localDateTime 创建时间
+			 */
+			// 循环生成码
+			List<QrData> codeList = loopGenerateCode(qrRepertoryColumnList, qrRepertoryId, urlMap, qrRepertorySerialNumberMap, qrNumber, batchNumber, repeatTimes);
+
+			// table数据库  批量插入
+			saveTableStore(qrPackageBatch, codeList);
+
+			// 创建码文件
+			createCodeFile(qrRepertory,batchNumber);
 
+		}
 		// 更改生成状态为已生成
 		qrPackageUpdate = new QrPackage().setId(qrPackageVo.getId()).setGenerateStatus(QrPackageGenerateStatusEnum.GENERATE_SUCCESS.getCode());
 		qrPackageMapper.updateById(qrPackageUpdate);
+		//压缩后得名字
+		String zipName = DateTimeFormatter.ofPattern("yyyyMMddHHmmss").format(LocalDateTime.now())+".zip";
+//		压缩密码
+		String pas = String.valueOf((int) (Math.random()*9+1)*100000);
+		log.info("生成密码:"+pas);
+		//压缩加密文件
+		zipEncryption(file,files,pas,zipName);
+		// TODO:上传阿里云,并更新码包的下载路径 保存zip密码
+
+		//删除生成文件
+		FileUtil.del(file);
 	}
 
 	/**
-	 * 循环生成码
+	 * 批量新增tableStore,码表
 	 */
-	private void loopGenerateCode(List<QrRepertoryColumnVO> qrRepertoryColumnList, Long qrRepertoryId, Map<Long, String> urlMap, Map<String, QrRepertorySerialNumber> qrRepertorySerialNumberMap, Long qrNumber, String batchNumber, LocalDateTime localDateTime, int repeatTimes) {
-		// 生成码
-		while (true) {
-			// 查询已生成的数量
-			long alreadyGenerateNumber = qrDataService.selectCountByBatchNumber(batchNumber);
+	private void saveTableStore(QrPackageBatch qrPackageBatch, List<QrData> codeList) {
+		List<TableStoreEntity> codeSave = new ArrayList<>();
+		for (QrData qrData:codeList) {
+			List<QrInnerData> innerDataList = qrData.getInnerDataList();
+			for (QrInnerData qrInnerData:innerDataList) {
+				QrCode qrCode = new QrCode();
+				qrCode.setId(String.valueOf(IdWorker.getId()));
+				//码
+				qrCode.setCode(qrInnerData.getCode());
+				//批次id
+				qrCode.setBatchNumberId(qrPackageBatch.getId());
+				//码包id
+				qrCode.setPackageId(qrPackageBatch.getPackageId());
+				//要拼接的url
+				qrCode.setUrl(qrInnerData.getUrl());
+				//创建时间
+				qrCode.setCreateTime(LocalDateTime.now());
+				codeSave.add(qrCode);
+			}
+		}
+		tableStorePlusUtils.putRow(codeSave);
+	}
 
+	/**
+     * qrRepertoryColumnList  码库的列
+     * qrRepertoryId 码库id
+     * urlMap 存放每列的url
+     * qrRepertorySerialNumberMap 用于标记同一列的第几个码格式变量
+     * qrNumber 码数量
+     * batchNumber 批次号
+     * localDateTime 创建时间
+     * repeatTimes 失败次数
+     */
+	private List<QrData> loopGenerateCode(List<QrRepertoryColumnVO> qrRepertoryColumnList, Long qrRepertoryId, Map<Long, String> urlMap, Map<String, QrRepertorySerialNumber> qrRepertorySerialNumberMap, Long qrNumber, String batchNumber, int repeatTimes) {
+        LocalDateTime localDateTime = LocalDateTime.now();
+		while (true) {
 			// 计算还需生成的数量
-			long needGenerateNumber = qrNumber - alreadyGenerateNumber;
+			long needGenerateNumber = qrNumber --;
 
 			if (needGenerateNumber <= 0) {
 				log.info("批次号:{},码生成完毕", batchNumber);
@@ -177,7 +257,6 @@ public class GenerateCodeConsumer {
 			// 计算本次最多生成多少码
 			long currentMaxGenerateNumber = needGenerateNumber <= ONCE_GENERATE_NUMBER ? needGenerateNumber : ONCE_GENERATE_NUMBER;
 
-			List<QrData> qrDataList = new LinkedList<>();
 			// 用Set存放不重复的码
 			HashSet<String> uniqueSet = new HashSet<>();
 			// 生成码要用的参数
@@ -222,19 +301,18 @@ public class GenerateCodeConsumer {
 
 				qrData.setInnerDataList(qrInnerDataList);
 				qrDataList.add(qrData);
-
 			}
 
 			try {
-				qrDataService.batchInsert(qrDataList);
+				return qrDataList;
 			} catch (Exception e) {
-				// mongoDB唯一索引冲突导致插入失败,继续生成码
-				log.error("mongo insert error", e);
+				log.error("封装码失败", e);
 				if (++repeatTimes >= REPEAT_BUILD_CODE_TIMES) {
 					throw new RuntimeException("生成码失败,重复生成码次数超过" + REPEAT_BUILD_CODE_TIMES + "次");
 				}
 			}
 		}
+		return null;
 	}
 
 	/**
@@ -299,15 +377,12 @@ public class GenerateCodeConsumer {
 	/**
 	 * 创建码文件
 	 */
-	private void createCodeFile(QrPackage qrPackage, QrRepertoryVO qrRepertory) {
-		String batchNumber = qrPackage.getBatchNumber();
-		List<QrData> qrDataList = qrDataService.selectCodeByBatch(batchNumber);
+	private void createCodeFile( QrRepertoryVO qrRepertory,String batchNumber) {
 		List<QrRepertoryColumnVO> qrRepertoryColumnList = qrRepertory.getQrRepertoryColumnList();
 		StringBuilder content = new StringBuilder();
 		// 第一行为每列的名称,用“,”分隔
 		String dataComposition = qrRepertoryColumnList.stream().map(col -> col.getAlias()).collect(Collectors.joining(","));
 		content.append(dataComposition).append("\r\n");
-
 		// 拼接码
 		List<QrInnerData> innerDataList;
 		String innerData;
@@ -316,16 +391,19 @@ public class GenerateCodeConsumer {
 			innerData = innerDataList.stream().map(qrInnerData -> qrInnerData.getUrl() + qrInnerData.getCode()).collect(Collectors.joining(","));
 			content.append(innerData).append("\r\n");
 		}
+		//如果文件不存在,创建一个文件
+		try{
+			if (!file.exists()) {
+				file.mkdir();
+			}
+		}catch (Exception e){
+			log.error("创建文件异常",e);
+		}
 
-		// 生成txt和zip文件
-		FileWriter fileWriter = new FileWriter(batchNumber + ".txt");
+		// 生成txt
+		FileWriter fileWriter = new FileWriter(file.getPath()+"/"+ batchNumber + ".txt");
 		fileWriter.write(content.toString());
-		File txtFile = fileWriter.getFile();
-		File zipFile = ZipUtil.zip(txtFile);
-
-		// 删除生成的临时文件,上传阿里云,并更新码包的下载路径
-		qrPackageService.delFileAndUpdatePath(txtFile, zipFile, qrPackage.getId());
-
+		files.add(new File(file.getPath()+"/"+ batchNumber + ".txt"));
 	}
 
 	/**
@@ -376,4 +454,46 @@ public class GenerateCodeConsumer {
 		}
 	}
 
+	/**
+	 * zip加密
+	 * @param file
+	 * @param files txt文件
+	 * @param pas 密码
+	 * @param zipName 压缩后的名字
+	 */
+	private void zipEncryption(File file  ,ArrayList<File> files,String pas,String zipName){
+		try {
+			//创建压缩文件
+			ZipFile zipFile = new ZipFile(file.getPath()+"/"+zipName);
+			//设置压缩文件参数
+			ZipParameters parameters = new ZipParameters();
+			//设置压缩方法
+			parameters.setCompressionMethod(Zip4jConstants.COMP_DEFLATE);
+
+			//设置压缩级别
+			//DEFLATE_LEVEL_FASTEST     - Lowest compression level but higher speed of compression
+			//DEFLATE_LEVEL_FAST        - Low compression level but higher speed of compression
+			//DEFLATE_LEVEL_NORMAL  - Optimal balance between compression level/speed
+			//DEFLATE_LEVEL_MAXIMUM     - High compression level with a compromise of speed
+			//DEFLATE_LEVEL_ULTRA       - Highest compression level but low speed
+			parameters.setCompressionLevel(Zip4jConstants.DEFLATE_LEVEL_NORMAL);
+
+			//设置压缩文件加密
+			parameters.setEncryptFiles(true);
+
+			//设置加密方法
+			parameters.setEncryptionMethod(Zip4jConstants.ENC_METHOD_AES);
+
+			//设置aes加密强度
+			parameters.setAesKeyStrength(Zip4jConstants.AES_STRENGTH_256);
+
+			//设置密码
+			parameters.setPassword(pas);
+
+			//添加文件到压缩文件
+			zipFile.addFiles(files, parameters);
+		} catch (ZipException e) {
+			e.printStackTrace();
+		}
+	}
 }

+ 4 - 4
abi-cloud-qr-platform-server/src/main/resources/dao/mapper/QrRepertoryMapper.xml

@@ -35,8 +35,8 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
 
     <!-- 码包 -->
     <resultMap id="QrPackageResult" type="com.abi.qms.platform.dao.vo.result.QrPackageVO">
-        <result property="batchNumber" column="batch_number"/>
-        <result property="name" column="qr_package_name"/>
+<!--        <result property="batchNumber" column="batch_number"/>-->
+<!--        <result property="name" column="qr_package_name"/>-->
         <result property="qrNumber" column="qr_number"/>
         <result property="createTime" column="qr_package_create_time"/>
         <result property="createByName" column="qr_package_create_by_name"/>
@@ -140,8 +140,8 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
             qrc.remark,
             qf.code_variable_build_class,
             bd.dept_url,
-            qp.batch_number,
-            qp.name AS qr_package_name,
+<!--            qp.batch_number,-->
+<!--            qp.name AS qr_package_name,-->
             qp.qr_number,
             qp.create_time AS qr_package_create_time,
             ui.user_name AS qr_package_create_by_name