|
@@ -0,0 +1,255 @@
|
|
|
+package com.abi.qms.platform.service.impl;
|
|
|
+
|
|
|
+import cn.hutool.core.io.FileUtil;
|
|
|
+import cn.hutool.core.io.IoUtil;
|
|
|
+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.enums.QrPackageGenerateStatusEnum;
|
|
|
+import com.abi.qms.platform.dao.mapper.QrPackageMapper;
|
|
|
+import com.abi.qms.platform.dao.mapper.QrRepertoryMapper;
|
|
|
+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.dto.req.ImportQrDataReq;
|
|
|
+import com.abi.qms.platform.infrastructure.mq.GenerateCodeConsumer;
|
|
|
+import com.abi.qms.platform.service.QrDataService;
|
|
|
+import com.abi.qms.platform.service.QrPackageService;
|
|
|
+import com.abi.task.common.api.exception.BusinessException;
|
|
|
+import lombok.extern.slf4j.Slf4j;
|
|
|
+import org.apache.commons.lang3.StringUtils;
|
|
|
+import org.springframework.beans.factory.annotation.Autowired;
|
|
|
+import org.springframework.data.mongodb.core.MongoTemplate;
|
|
|
+import org.springframework.data.mongodb.core.query.Criteria;
|
|
|
+import org.springframework.data.mongodb.core.query.Query;
|
|
|
+import org.springframework.stereotype.Service;
|
|
|
+import org.springframework.web.multipart.MultipartFile;
|
|
|
+
|
|
|
+import java.io.BufferedReader;
|
|
|
+import java.io.File;
|
|
|
+import java.io.IOException;
|
|
|
+import java.io.InputStreamReader;
|
|
|
+import java.time.LocalDateTime;
|
|
|
+import java.util.ArrayList;
|
|
|
+import java.util.LinkedList;
|
|
|
+import java.util.List;
|
|
|
+
|
|
|
+/**
|
|
|
+ * 码数据 Service业务层处理
|
|
|
+ *
|
|
|
+ * @author WeiganCai
|
|
|
+ * @date: 2021-05-11
|
|
|
+ */
|
|
|
+@Service
|
|
|
+@Slf4j
|
|
|
+public class QrDataServiceImpl implements QrDataService {
|
|
|
+
|
|
|
+ @Autowired
|
|
|
+ private MongoTemplate mongoTemplate;
|
|
|
+
|
|
|
+ @Autowired
|
|
|
+ private QrPackageMapper qrPackageMapper;
|
|
|
+
|
|
|
+ @Autowired
|
|
|
+ private QrRepertoryMapper qrRepertoryMapper;
|
|
|
+
|
|
|
+ @Autowired
|
|
|
+ private QrPackageService qrPackageService;
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 根据批次号查询码数量
|
|
|
+ */
|
|
|
+ public long selectCountByBatchNumber(String batchNumber) {
|
|
|
+ Query query = new Query();
|
|
|
+ query.addCriteria(Criteria.where("batchNumber").is(batchNumber));
|
|
|
+ return mongoTemplate.count(query, QrData.class);
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 根据批次号删除码
|
|
|
+ */
|
|
|
+ public void deleteCodeByBatchNumber(String batchNumber) {
|
|
|
+ Query query = new Query();
|
|
|
+ query.addCriteria(Criteria.where("batchNumber").is(batchNumber));
|
|
|
+ mongoTemplate.remove(query, QrData.class);
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 根据批次号查询码
|
|
|
+ */
|
|
|
+ public List<QrData> selectCodeByBatch(String batchNumber) {
|
|
|
+ Query query = new Query();
|
|
|
+ query.addCriteria(Criteria.where("batchNumber").is(batchNumber));
|
|
|
+ return mongoTemplate.find(query, QrData.class);
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 批量插入
|
|
|
+ */
|
|
|
+ @Override
|
|
|
+ public void batchInsert(List<QrData> qrDataList) {
|
|
|
+ mongoTemplate.insert(qrDataList, QrData.class);
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 导入码数据
|
|
|
+ */
|
|
|
+ @Override
|
|
|
+ public void importQrData(ImportQrDataReq req) {
|
|
|
+ // 校验txt文件
|
|
|
+ MultipartFile file = req.getFile();
|
|
|
+ checkTxtFile(file);
|
|
|
+
|
|
|
+ // 查询码包
|
|
|
+ Long qrPackageId = req.getQrPackageId();
|
|
|
+ QrPackageVO qrPackageVo = qrPackageMapper.selectQrPackageDetailById(qrPackageId);
|
|
|
+ List<QrData> qrDataList = new LinkedList<>();
|
|
|
+
|
|
|
+ // 从txt中提取码数据
|
|
|
+ txtToQrData(file, qrPackageVo, qrDataList);
|
|
|
+
|
|
|
+ try {
|
|
|
+ // 插入文本中的数据
|
|
|
+ insertImportData(qrPackageVo, qrDataList);
|
|
|
+
|
|
|
+ // 压缩文件
|
|
|
+ zipFile(file, qrPackageVo);
|
|
|
+
|
|
|
+ // 更改生成状态为已生成
|
|
|
+ QrPackage update = new QrPackage().setId(qrPackageVo.getId()).setGenerateStatus(QrPackageGenerateStatusEnum.GENERATE_SUCCESS.getCode());
|
|
|
+ qrPackageMapper.updateById(update);
|
|
|
+
|
|
|
+ } catch (Exception e) {
|
|
|
+ log.error("导入码失败", e);
|
|
|
+ qrPackageService.failedRollback(new QrPackage().setId(qrPackageVo.getId()).setBatchNumber(qrPackageVo.getBatchNumber()));
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 压缩文件
|
|
|
+ */
|
|
|
+ private void zipFile(MultipartFile file, QrPackageVO qrPackageVo) {
|
|
|
+ try {
|
|
|
+ File txtFile = File.createTempFile(qrPackageVo.getBatchNumber(), "txt");
|
|
|
+ file.transferTo(txtFile);
|
|
|
+ // 按照批次号.txt的方式重命名
|
|
|
+ txtFile = FileUtil.rename(txtFile, qrPackageVo.getBatchNumber() + ".txt", true, true);
|
|
|
+
|
|
|
+ // 压缩文件
|
|
|
+ File zipFile = ZipUtil.zip(txtFile);
|
|
|
+
|
|
|
+ // 删除生成的临时文件,上传阿里云,并更新码包的下载路径
|
|
|
+ qrPackageService.delFileAndUpdatePath(txtFile, zipFile, qrPackageVo.getId());
|
|
|
+ } catch (IOException e) {
|
|
|
+ log.error("IOException", e);
|
|
|
+ throw new BusinessException("压缩文件错误");
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 从txt中提取码数据
|
|
|
+ * @param file txt文件
|
|
|
+ * @param qrPackageVo 码包
|
|
|
+ * @param qrDataList 码数据
|
|
|
+ */
|
|
|
+ private void txtToQrData(MultipartFile file, QrPackageVO qrPackageVo, List<QrData> qrDataList) {
|
|
|
+ // 码库 & 码库的列
|
|
|
+ QrRepertoryVO qrRepertory = qrRepertoryMapper.selectQrRepertoryDetailById(qrPackageVo.getQrRepertoryId());
|
|
|
+ List<QrRepertoryColumnVO> qrRepertoryColumnList = qrRepertory.getQrRepertoryColumnList();
|
|
|
+
|
|
|
+ BufferedReader br = null;
|
|
|
+ try {
|
|
|
+ br = new BufferedReader(new InputStreamReader(file.getInputStream()));
|
|
|
+ String line = null;
|
|
|
+ while ((line = br.readLine()) != null) {
|
|
|
+ if (StringUtils.isBlank(line)) {
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+
|
|
|
+ line = line.replace(",", ",");
|
|
|
+ // 跳过特殊字符
|
|
|
+ if (!line.matches("[0-9a-zA-Z\\.\\,\\:\\-/]*")) {
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+
|
|
|
+ String[] codeArr = line.split(",");
|
|
|
+ // 验证导入的码列数是否与定义的码库列数一致
|
|
|
+ if (codeArr.length != qrRepertoryColumnList.size()) {
|
|
|
+ throw new BusinessException("导入文件的码列数与码库定义的码列数不一致,导入失败");
|
|
|
+ }
|
|
|
+
|
|
|
+ QrData qrData = new QrData();
|
|
|
+ List<QrInnerData> qrInnerDataList = new LinkedList<>();
|
|
|
+ LocalDateTime localDateTime = LocalDateTime.now();
|
|
|
+
|
|
|
+ for (int i = 0; i < codeArr.length; i++) {
|
|
|
+ String urlCode = codeArr[i];
|
|
|
+ // 分离url与code
|
|
|
+ int urlIndex = urlCode.lastIndexOf("/") + 1;
|
|
|
+ QrInnerData qrInnerData = new QrInnerData();
|
|
|
+ qrInnerData.setUrl(urlCode.substring(0, urlIndex));
|
|
|
+ qrInnerData.setCode(urlCode.substring(urlIndex));
|
|
|
+ qrInnerData.setQrRepertoryColumnId(qrRepertoryColumnList.get(i).getId());
|
|
|
+ qrInnerData.setSortNumber(i);
|
|
|
+
|
|
|
+ qrInnerDataList.add(qrInnerData);
|
|
|
+ }
|
|
|
+
|
|
|
+ qrData.setQrRepertoryId(qrRepertory.getId());
|
|
|
+ qrData.setBatchNumber(qrPackageVo.getBatchNumber());
|
|
|
+ qrData.setQrRepertoryType(qrRepertory.getType());
|
|
|
+ qrData.setInnerDataList(qrInnerDataList);
|
|
|
+ qrData.setCreateTime(localDateTime);
|
|
|
+
|
|
|
+ qrDataList.add(qrData);
|
|
|
+ }
|
|
|
+ } catch (IOException e) {
|
|
|
+ log.error("读取码文件出错", e);
|
|
|
+ throw new BusinessException("读取码文件出错");
|
|
|
+ } finally {
|
|
|
+ IoUtil.close(br);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 校验txt文件
|
|
|
+ * @param file
|
|
|
+ */
|
|
|
+ private void checkTxtFile(MultipartFile file) {
|
|
|
+ if (file != null && file.getSize() > 0) {
|
|
|
+ String fileName = file.getOriginalFilename();
|
|
|
+ String suffix = fileName.substring(fileName.lastIndexOf(".") + 1);
|
|
|
+ if (!"txt".equals(suffix)) {
|
|
|
+ throw new BusinessException("上传文件格式不正确");
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ throw new BusinessException("上传文件为空");
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 插入文本中的数据
|
|
|
+ * @param qrPackageVo 码包
|
|
|
+ * @param qrDataList 码数据List
|
|
|
+ */
|
|
|
+ private void insertImportData(QrPackageVO qrPackageVo, List<QrData> qrDataList) {
|
|
|
+ try {
|
|
|
+ List<QrData> batchInsertList = new ArrayList<>();
|
|
|
+ for (int i = 0; i < qrDataList.size(); i++) {
|
|
|
+ batchInsertList.add(qrDataList.get(i));
|
|
|
+ // 每5000个插入一次
|
|
|
+ if (i > 0 && i % GenerateCodeConsumer.ONCE_GENERATE_NUMBER == 0) {
|
|
|
+ batchInsert(batchInsertList);
|
|
|
+ batchInsertList.clear();
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if (!batchInsertList.isEmpty()) {
|
|
|
+ batchInsert(batchInsertList);
|
|
|
+ }
|
|
|
+ } catch (Exception e) {
|
|
|
+ log.error("导入的码插入mongodb失败", e);
|
|
|
+ throw new BusinessException("导入的码重复或与系统中的码重复,导入失败");
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|