package com.ruoyi.requier.service.impl;
|
|
import cn.hutool.core.util.StrUtil;
|
import com.alibaba.fastjson.JSONArray;
|
import com.aspose.words.Document;
|
import com.aspose.words.License;
|
import com.aspose.words.SaveFormat;
|
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
|
import com.baomidou.mybatisplus.core.metadata.IPage;
|
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
|
import com.baomidou.mybatisplus.core.toolkit.ObjectUtils;
|
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
|
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
import com.deepoove.poi.XWPFTemplate;
|
import com.deepoove.poi.data.FilePictureRenderData;
|
import com.itextpdf.text.BadElementException;
|
import com.itextpdf.text.DocumentException;
|
import com.itextpdf.text.pdf.PdfContentByte;
|
import com.itextpdf.text.pdf.PdfReader;
|
import com.itextpdf.text.pdf.PdfStamper;
|
import com.ruoyi.common.core.domain.entity.User;
|
import com.ruoyi.common.utils.QueryWrappers;
|
import com.ruoyi.common.utils.SecurityUtils;
|
import com.ruoyi.framework.exception.ErrorException;
|
import com.ruoyi.inspect.dto.ReportPageDto;
|
import com.ruoyi.inspect.mapper.InsOrderMapper;
|
import com.ruoyi.inspect.mapper.InsOrderStateMapper;
|
import com.ruoyi.inspect.mapper.InsReportApproveConfigMapper;
|
import com.ruoyi.inspect.mapper.InsReportMapper;
|
import com.ruoyi.inspect.pojo.InsOrder;
|
import com.ruoyi.inspect.pojo.InsOrderState;
|
import com.ruoyi.inspect.pojo.InsReport;
|
import com.ruoyi.process.mapper.ProcessReportMapper;
|
import com.ruoyi.process.pojo.ProcessReport;
|
import com.ruoyi.requier.service.InsReportService;
|
import com.ruoyi.system.mapper.UserMapper;
|
import lombok.extern.slf4j.Slf4j;
|
import org.apache.commons.lang3.StringUtils;
|
import org.apache.logging.log4j.util.Strings;
|
import org.springframework.beans.factory.annotation.Value;
|
import org.springframework.data.redis.core.RedisTemplate;
|
import org.springframework.data.redis.serializer.StringRedisSerializer;
|
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
|
import org.springframework.stereotype.Service;
|
import org.springframework.transaction.annotation.Transactional;
|
import org.springframework.web.context.request.RequestContextHolder;
|
import org.springframework.web.multipart.MultipartFile;
|
|
import javax.annotation.Resource;
|
import javax.imageio.ImageIO;
|
import javax.servlet.ServletOutputStream;
|
import javax.servlet.http.HttpServletResponse;
|
import java.awt.image.BufferedImage;
|
import java.io.*;
|
import java.math.BigDecimal;
|
import java.net.URLEncoder;
|
import java.nio.file.Files;
|
import java.nio.file.Path;
|
import java.nio.file.Paths;
|
import java.nio.file.StandardCopyOption;
|
import java.time.LocalDateTime;
|
import java.time.format.DateTimeFormatter;
|
import java.util.*;
|
import java.util.concurrent.CompletableFuture;
|
import java.util.concurrent.atomic.AtomicLong;
|
import java.util.stream.Collectors;
|
import java.util.zip.ZipEntry;
|
import java.util.zip.ZipFile;
|
import java.util.zip.ZipOutputStream;
|
|
/**
|
* @author Administrator
|
* @description 针对表【ins_report(检验报告)】的数据库操作Service实现
|
* @createDate 2024-03-17 22:10:02
|
*/
|
@Service
|
@Slf4j
|
public class InsReportServiceImpl extends ServiceImpl<InsReportMapper, InsReport>
|
implements InsReportService {
|
|
@Resource
|
private UserMapper userMapper;
|
|
@Resource
|
private InsReportMapper insReportMapper;
|
|
@Resource
|
ProcessReportMapper processReportMapper;
|
|
@Value("${wordUrl}")
|
private String wordUrl;
|
|
@Value("${file.licenseUrl}")
|
private String licenseUrl;
|
|
@Value("${file.path}")
|
private String imgUrl;
|
|
@Resource
|
private InsOrderMapper insOrderMapper;
|
|
@Resource
|
private RedisTemplate<String, Object> redisTemplate;
|
|
@Resource
|
private ThreadPoolTaskExecutor threadPoolTaskExecutor;
|
|
@Resource
|
private InsOrderStateMapper insOrderStateMapper;
|
|
private static final String SYNC_REPORT_KEY_PREFIX = "syncApprovalReport_lock_";
|
|
@Resource
|
private InsReportApproveConfigMapper insReportApproveConfigMapper;
|
|
@Override
|
public IPage<ReportPageDto> pageInsReport(Page page, ReportPageDto reportPageDto) {
|
Map<String, Object> map = new HashMap<>();
|
User user = userMapper.selectById(SecurityUtils.getUserId());//当前登录的人
|
//获取当前人所属实验室id
|
String departLimsId = user.getDepartLimsId();
|
String laboratory = null;
|
if (ObjectUtils.isNotEmpty(departLimsId) && !departLimsId.isEmpty()) {
|
String[] split = departLimsId.split(",");
|
//查询对应架构名称(通信实验室,电力实验室,检测办)
|
String departLims = insOrderMapper.seldepLimsId(Integer.parseInt(split[split.length - 1]));
|
if (departLims.contains("实验室")) {
|
laboratory = departLims;
|
}
|
}
|
QueryWrapper<ReportPageDto> wrapper = QueryWrappers.queryWrappers(reportPageDto);
|
if(Objects.nonNull(reportPageDto.getCreateTimeRange())){
|
wrapper.gt(reportPageDto.getCreateTimeRange().size()>1,"create_time",reportPageDto.getCreateTimeRange().get(0))
|
.lt(reportPageDto.getCreateTimeRange().size()>1,"create_time",reportPageDto.getCreateTimeRange().get(1));
|
}
|
return insReportMapper.pageInsReport(page, wrapper ,laboratory);
|
}
|
|
@Override
|
public int inReport(String url, Integer id) {
|
InsReport insReport = new InsReport();
|
insReport.setId(id);
|
insReport.setUrlS(url);
|
return insReportMapper.updateById(insReport);
|
}
|
|
// 还原
|
@Override
|
public int upReportUrl(Integer id) {
|
InsReport insReport = insReportMapper.selectById(id);
|
String fileName = insReport.getUrlS().replace("/word/", "");
|
if(Strings.isNotEmpty(fileName)) {
|
String path = wordUrl + File.separator + fileName;
|
File file = new File(path);
|
if (file.exists()) {
|
file.delete();
|
}
|
}
|
return insReportMapper.update(null, Wrappers.<InsReport>lambdaUpdate().eq(InsReport::getId, id).set(InsReport::getUrlS, null));
|
}
|
|
@Override
|
public void downReport(Integer id,Integer type, HttpServletResponse response) {
|
InsReport insReport = insReportMapper.selectById(id);
|
String url = "";
|
// 0 下载docx 1 下载pdf
|
if(type == 0) {
|
url = Strings.isNotEmpty(insReport.getUrlS()) ? insReport.getUrlS() : insReport.getUrl();
|
}else {
|
url = insReport.getTempUrlPdf();
|
}
|
if(Strings.isEmpty(url)){
|
throw new ErrorException("报告地址为空");
|
}
|
File file = new File(wordUrl + File.separator + url.replace("/word/", ""));
|
try {
|
String fileName = file.getName();
|
if(fileName.indexOf("_") != -1) {
|
fileName = fileName.split("_")[1];
|
}
|
fileName = URLEncoder.encode(fileName, "UTF-8");
|
response.setContentType("application/octet-stream");
|
response.setHeader("Content-disposition","attachment;filename=" + fileName);
|
ServletOutputStream stream = response.getOutputStream();
|
FileInputStream fileInputStream = new FileInputStream(file);
|
byte[] bytes = new byte[1024];
|
int byteRead;
|
while((byteRead = fileInputStream.read(bytes)) != -1){
|
stream.write(bytes, 0, byteRead);
|
stream.flush();
|
}
|
fileInputStream.close();
|
stream.close();
|
}catch (Exception e){
|
throw new ErrorException("下载失败");
|
}
|
}
|
|
|
|
|
|
//提交
|
@Override
|
public int writeReport(Integer id) {
|
InsReport insReport = insReportMapper.selectById(id);
|
insReport.setId(id);
|
insReport.setState(1);
|
insReport.setWriteTime(LocalDateTime.now());//提交时间
|
insReport.setWriteUserId(SecurityUtils.getUserId().intValue());//提交人
|
//获取提交人的签名地址
|
String signatureUrl;
|
try {
|
signatureUrl = userMapper.selectById(SecurityUtils.getUserId().intValue()).getSignatureUrl();
|
} catch (Exception e) {
|
throw new ErrorException("找不到编制人的签名");
|
}
|
//系统生成报告地址
|
String url = insReport.getUrl();
|
//手动上传报告地址
|
String urlS = insReport.getUrlS();
|
wordInsertUrl(new HashMap<String, Object>() {{
|
put("writeUrl", new FilePictureRenderData(100,50,imgUrl + "/" + signatureUrl));
|
}}, (urlS == null ? url : urlS).replace("/word", wordUrl));
|
// 修改临时pdf
|
String tempUrlPdf = wordToPdfTemp((StrUtil.isBlank(urlS) ? url : urlS).replace("/word", wordUrl));
|
insReport.setTempUrlPdf("/word/" + tempUrlPdf);
|
return insReportMapper.updateById(insReport);
|
}
|
|
//审核
|
@Override
|
public int examineReport(Integer id, Integer isExamine, String examineTell) {
|
InsReport insReport = insReportMapper.selectById(id);
|
insReport.setIsExamine(isExamine);
|
if (ObjectUtils.isNotEmpty(examineTell)) {
|
insReport.setExamineTell(examineTell);
|
}
|
insReport.setExamineUserId(SecurityUtils.getUserId().intValue());//审核人
|
insReport.setExamineTime(LocalDateTime.now());//审核时间
|
if (isExamine == 0) {
|
//如果审核不通过
|
insReport.setState(0);//提交状态改为待提交
|
return insReportMapper.updateById(insReport);
|
}
|
//获取审核人的签名地址
|
String signatureUrl;
|
try {
|
signatureUrl = userMapper.selectById(insReport.getExamineUserId()).getSignatureUrl();
|
} catch (Exception e) {
|
throw new ErrorException("找不到审核人的签名");
|
}
|
//系统生成报告地址
|
String url = insReport.getUrl();
|
//手动上传报告地址
|
String urlS = insReport.getUrlS();
|
wordInsertUrl(new HashMap<String, Object>() {{
|
put("examineUrl", new FilePictureRenderData(100,50,imgUrl + "/" + signatureUrl));
|
}}, (urlS == null ? url : urlS).replace("/word", wordUrl));
|
// 修改临时pdf
|
String tempUrlPdf = wordToPdfTemp((StrUtil.isBlank(urlS) ? url : urlS).replace("/word", wordUrl));
|
insReport.setTempUrlPdf("/word/" + tempUrlPdf);
|
return insReportMapper.updateById(insReport);
|
}
|
|
//批准
|
@Override
|
@Transactional(rollbackFor = Exception.class)
|
public int ratifyReport(Integer id, Integer isRatify, String ratifyTell) {
|
InsReport insReport = insReportMapper.selectById(id);
|
insReport.setIsRatify(isRatify);
|
if (ObjectUtils.isNotEmpty(ratifyTell)) {
|
insReport.setRatifyTell(ratifyTell);
|
}
|
insReport.setRatifyUserId(SecurityUtils.getUserId().intValue());//批准人
|
insReport.setRatifyTime(LocalDateTime.now());//批准时间
|
if (isRatify == 0) {
|
//如果批准不通过
|
insReport.setState(0);//提交状态改为待提交
|
return insReportMapper.updateById(insReport);
|
}
|
//获取批准人的签名地址
|
String signatureUrl;
|
try {
|
signatureUrl = userMapper.selectById(insReport.getRatifyUserId()).getSignatureUrl();
|
} catch (Exception e) {
|
throw new ErrorException("找不到批准人的签名");
|
}
|
//获取场所的报告专用章
|
String sealUrl;
|
try {
|
String laboratory = insOrderMapper.selectById(insReport.getInsOrderId()).getLaboratory();
|
sealUrl = insReportMapper.getLaboratoryByName(laboratory);
|
} catch (Exception e) {
|
throw new ErrorException("找不到报告专用章");
|
}
|
if (sealUrl == null) throw new ErrorException("找不到报告专用章");
|
//系统生成报告地址
|
String url = insReport.getUrl();
|
//手动上传报告地址
|
String urlS = insReport.getUrlS();
|
String finalUrl = (urlS == null ? url : urlS).replace("/word", wordUrl);
|
wordInsertUrl(new HashMap<String, Object>() {{
|
put("ratifyUrl", new FilePictureRenderData(100,50,imgUrl + "/" + signatureUrl));
|
put("seal1", new FilePictureRenderData(600,600,imgUrl + "/" + sealUrl));
|
put("seal2", new FilePictureRenderData(600,600,imgUrl + "/" + sealUrl));
|
}}, finalUrl);
|
wordToPdf(finalUrl, sealUrl);
|
|
InsOrder insOrder = new InsOrder();
|
insOrder.setId(insReportMapper.selectById(id).getInsOrderId());
|
insOrder.setState(4);
|
insOrderMapper.updateById(insOrder);
|
// 修改临时pdf
|
String tempUrlPdf = wordToPdfTemp((StrUtil.isBlank(urlS) ? url : urlS).replace("/word", wordUrl));
|
insReport.setTempUrlPdf("/word/" + tempUrlPdf);
|
/*新增cnas7.8报告结果*/
|
ProcessReport processReport = new ProcessReport();
|
processReport.setInsReportCode(insReport.getCode());
|
processReportMapper.insert(processReport);
|
return insReportMapper.updateById(insReport);
|
}
|
|
@Override
|
public int wordInsertUrl(Map<String, Object> map, String url) {
|
XWPFTemplate template = XWPFTemplate.compile(url).render(map);
|
try {
|
template.writeAndClose(Files.newOutputStream(Paths.get(url)));
|
} catch (IOException e) {
|
throw new RuntimeException(e);
|
}
|
return 1;
|
}
|
|
//报告批量下载
|
@Override
|
@Transactional(rollbackFor = Exception.class)
|
public String downAll(String ids) {
|
List<Long> list = Arrays.stream(ids.split(",")).map(Long::parseLong).collect(Collectors.toList());
|
List<InsReport> insReports = insReportMapper.selectBatchIds(list);
|
String zipFilePath = null;
|
// 临时文件夹路径
|
try {
|
String tempFolderPath = wordUrl + "/tempFolder";
|
File tempFolder = new File(tempFolderPath);
|
if (tempFolder.exists()) {
|
deleteDirectory(tempFolder); // 删除旧的临时文件夹
|
}
|
tempFolder.mkdirs(); // 创建新的临时文件夹
|
for (InsReport insReport : insReports) {
|
File sourceFile = new File((ObjectUtils.isNotEmpty(insReport.getUrlS()) ? insReport.getUrlS() : insReport.getUrl()).replace("/word", wordUrl));
|
// 下载文件名称去除时间
|
String destinationFileName = sourceFile.getName();
|
if(destinationFileName.indexOf("_") != -1) {
|
destinationFileName = destinationFileName.split("_")[1];
|
}
|
File destinationFile = new File(tempFolder, destinationFileName);
|
Files.copy(sourceFile.toPath(), destinationFile.toPath(), StandardCopyOption.REPLACE_EXISTING);
|
}
|
// 压缩临时文件夹
|
zipFilePath = wordUrl + "/zip/output.zip";
|
zipDirectory(tempFolderPath, zipFilePath);
|
|
// 清理临时文件夹
|
deleteDirectory(tempFolder);
|
|
System.out.println("ZIP文件创建完成!");
|
} catch (IOException e) {
|
e.printStackTrace();
|
}
|
return "/word/zip/output.zip";
|
}
|
|
//批量上传
|
@Override
|
@Transactional(rollbackFor = Exception.class)
|
public int upAll(MultipartFile file) {
|
if (file != null) {
|
// 根据文件名查询id
|
String fileName = file.getOriginalFilename();
|
String code = fileName.replace(".docx", "").replace("JCZX", "JCZX/");
|
if(fileName.lastIndexOf("_") != -1) {
|
code = code.substring(file.getOriginalFilename().lastIndexOf("_") + 1);
|
}
|
//查询未审核的报告数据
|
InsReport insReport = insReportMapper.selectOne(Wrappers.<InsReport>lambdaQuery().eq(InsReport::getCode, code).eq(InsReport::getIsExamine,-9));
|
if (ObjectUtils.isEmpty(insReport)) {
|
throw new ErrorException("没有编号为" + code + "的报告或该报告已审核通过");
|
}
|
// 如果UrlS有值 先将该文件删除
|
if(Strings.isNotEmpty(insReport.getUrlS())) {
|
String url = wordUrl + File.separator + insReport.getUrlS().replace("/word/", "");
|
File file1 = new File(url);
|
if(file1.exists()) {
|
file1.delete();
|
}
|
}
|
String urlString;
|
String pathName;
|
String path = wordUrl;
|
File realpath = new File(path);
|
if (!realpath.exists()) {
|
realpath.mkdirs();
|
}
|
pathName = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyMMddHHmmss")) + "_" + insReport.getCode().replace("/", "") + ".docx";
|
urlString = realpath + "/" + pathName;
|
// 复制文件到指定路径
|
try {
|
Files.copy(file.getInputStream(), new File(urlString).toPath(), StandardCopyOption.REPLACE_EXISTING);
|
} catch (IOException e) {
|
throw new RuntimeException(e);
|
}
|
inReport("/word/" + pathName, insReport.getId());
|
}
|
// File tempFile = null;
|
// File unzipDir = null;
|
// try {
|
// tempFile = File.createTempFile(wordUrl, ".zip");
|
// file.transferTo(tempFile);
|
//
|
// unzipDir = new File("uploaded_files");
|
// if (!unzipDir.exists()) {
|
// unzipDir.mkdir();
|
// }
|
// unzip(tempFile, unzipDir);
|
// // 处理解压后的文件
|
// File[] files = unzipDir.listFiles();
|
// if (files != null) {
|
// for (File f : files) {
|
// // 根据文件名查询id
|
// String name = f.getName();
|
// String code = f.getName().replace(".docx", "").replace("JCZX", "JCZX/");
|
// if(f.getName().lastIndexOf("_") != -1) {
|
// code = code.substring(f.getName().lastIndexOf("_") + 1);
|
// }
|
// //InsReport insReport = insReportMapper.selectOne(Wrappers.<InsReport>lambdaQuery().eq(InsReport::getCode, f.getName().replace(".docx", "").replace("JCZX", "JCZX/")));
|
// InsReport insReport = insReportMapper.selectOne(Wrappers.<InsReport>lambdaQuery().eq(InsReport::getCode, code));
|
// if (ObjectUtils.isEmpty(insReport)) {
|
// throw new ErrorException("没有找到 " + f.getName() + " 这个文件对应的报告数据");
|
// }
|
// // 如果UrlS有值 先将该文件删除
|
// if(Strings.isNotEmpty(insReport.getUrlS())) {
|
// String url = wordUrl + File.separator + insReport.getUrlS().replace("/word/", "");
|
// File file1 = new File(url);
|
// if(file1.exists()) {
|
// file1.delete();
|
// }
|
// }
|
// String urlString;
|
// String pathName;
|
// try {
|
// String path = wordUrl;
|
// File realpath = new File(path);
|
// if (!realpath.exists()) {
|
// realpath.mkdirs();
|
// }
|
// pathName = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyMMddHHmmss")) + "_" + insReport.getCode().replace("/", "") + ".docx";
|
// urlString = realpath + "/" + pathName;
|
// // 复制文件到指定路径
|
// Files.copy(f.toPath(), new File(urlString).toPath(), StandardCopyOption.REPLACE_EXISTING);
|
// inReport("/word/" + pathName, insReport.getId());
|
// }
|
// catch (IOException e) {
|
// throw new ErrorException("文件上传失败");
|
// }
|
// }
|
// }
|
// } catch (IOException e) {
|
// throw new ErrorException("文件处理失败");
|
// } finally {
|
// if (tempFile != null && tempFile.exists()) {
|
// tempFile.delete();
|
// }
|
// // 递归删除解压目录及其中的文件
|
// if (unzipDir.exists()) {
|
// deleteDirectory(unzipDir); // 删除旧的临时文件夹
|
// }
|
// }
|
return 0;
|
}
|
|
@Override
|
@Transactional(rollbackFor = Exception.class)
|
public void withdraw(Map<String,Object> map) {
|
Integer id = Integer.parseInt(map.get("id").toString());
|
List<String> list = JSONArray.parseArray(map.get("laboratory").toString(), String.class);
|
Integer insOrderId = insReportMapper.selectById(id).getInsOrderId();
|
List<InsOrderState> insOrderStateS = insOrderStateMapper.selectList(new LambdaQueryWrapper<InsOrderState>()
|
.eq(InsOrderState::getInsOrderId, insOrderId)
|
.in(CollectionUtils.isNotEmpty(list),InsOrderState::getLaboratory, list));
|
if(CollectionUtils.isNotEmpty(insOrderStateS)) {
|
List<Integer> collect = insOrderStateS.stream().map(InsOrderState::getId).collect(Collectors.toList());
|
// 修改该单子试验室的状态为待复核,删除报告信息
|
insOrderStateMapper.update(null,new LambdaUpdateWrapper<InsOrderState>()
|
.set(InsOrderState::getInsState,3) // 待复核
|
.in(InsOrderState::getId,collect));
|
insReportMapper.delete(new LambdaQueryWrapper<InsReport>().eq(InsReport::getId,id));
|
}
|
}
|
|
@Override
|
public List<Map<String, Object>> getLaboratoryByReportId(Integer id) {
|
List<Map<String, Object>> list = new ArrayList<>();
|
Integer insOrderId = insReportMapper.selectById(id).getInsOrderId();
|
insOrderStateMapper.selectList(new LambdaQueryWrapper<InsOrderState>()
|
.eq(InsOrderState::getInsOrderId,insOrderId))
|
.forEach(insOrderState -> {
|
Map<String, Object> map = new HashMap<>();
|
map.put("label",insOrderState.getLaboratory());
|
map.put("value",insOrderState.getLaboratory());
|
list.add(map);
|
});
|
return list;
|
}
|
|
@Override
|
public Map<String, Object> getReportCountInfo(ReportPageDto reportPageDto) {
|
HashMap<String, Object> map = new HashMap<>();
|
User user = userMapper.selectById(SecurityUtils.getUserId());//当前登录的人
|
//获取当前人所属实验室id
|
String departLimsId = user.getDepartLimsId();
|
String laboratory = null;
|
if (ObjectUtils.isNotEmpty(departLimsId) && !departLimsId.isEmpty()) {
|
String[] split = departLimsId.split(",");
|
//查询对应架构名称(通信实验室,电力实验室,检测办)
|
String departLims = insOrderMapper.seldepLimsId(Integer.parseInt(split[split.length - 1]));
|
if (departLims.contains("实验室")) {
|
laboratory = departLims;
|
}
|
}
|
QueryWrapper<ReportPageDto> wrapper = QueryWrappers.queryWrappers(reportPageDto);
|
if(Objects.nonNull(reportPageDto.getCreateTimeRange())){
|
wrapper.gt(reportPageDto.getCreateTimeRange().size()>1,"create_time",reportPageDto.getCreateTimeRange().get(0))
|
.lt(reportPageDto.getCreateTimeRange().size()>1,"create_time",reportPageDto.getCreateTimeRange().get(1));
|
|
}
|
map.put("unSubmitCount",insReportMapper.findReportCountInfo(wrapper,laboratory,"ir.write_user_id").size());
|
map.put("unExamineCount",insReportMapper.findReportCountInfo(wrapper,laboratory,"ir.is_examine").size());
|
map.put("unRatifyCount",insReportMapper.findReportCountInfo(wrapper,laboratory,"ir.is_ratify").size());
|
return map;
|
}
|
|
@Override
|
@Transactional(rollbackFor = Exception.class)
|
public void batchApprovalReport(List<Integer> ids) {
|
redisTemplate.setKeySerializer(new StringRedisSerializer());
|
Integer userId = SecurityUtils.getUserId().intValue();
|
String key = SYNC_REPORT_KEY_PREFIX+userId;
|
//执行前删除之前的keys
|
deleteRedisKeys(key);
|
synchronized (key) {
|
redisTemplate.opsForValue().set(key,1);
|
RequestContextHolder.setRequestAttributes(RequestContextHolder.getRequestAttributes(),true);
|
//异步执行审批操作
|
CompletableFuture.runAsync(() -> {
|
try {
|
runBatchApproval(ids,key);
|
}catch (Exception e){
|
//删除key
|
deleteRedisKeys(key);
|
redisTemplate.opsForValue().set(key+"_exception",e.getMessage());
|
}
|
},threadPoolTaskExecutor);
|
}
|
}
|
|
/**
|
* 删除redis key
|
* @param key
|
*/
|
private void deleteRedisKeys(String key){
|
redisTemplate.delete(key);
|
redisTemplate.delete(key+"_num");
|
redisTemplate.delete(key+"_count");
|
redisTemplate.delete(key+"_surplus");
|
redisTemplate.delete(key+"_exception");
|
}
|
|
/**
|
* 执行审批操作
|
* @param ids 报告id列表
|
*/
|
private void runBatchApproval(List<Integer> ids,String keyPrefix) {
|
if(ids.isEmpty()){
|
return;
|
}
|
long start = System.currentTimeMillis();
|
String surplusKey = keyPrefix + "_surplus";//剩余条数
|
String numKey = keyPrefix + "_num";//总进度
|
String countKey = keyPrefix + "_count";//总条数
|
redisTemplate.opsForValue().set(countKey, ids.size());
|
redisTemplate.opsForValue().set(surplusKey, ids.size());
|
Object countObj = redisTemplate.opsForValue().get(countKey);
|
long parsed2 = Long.parseLong(String.valueOf(countObj));
|
AtomicLong count = new AtomicLong(parsed2);
|
for (Integer id : ids) {
|
//业务代码
|
InsReport insReport = insReportMapper.selectById(id);
|
String laboratory = insOrderMapper.selectById(insReport.getInsOrderId()).getLaboratory();
|
//获取签名和印章
|
String sealUrl;
|
String writeUrl;
|
String examineUrl;
|
String ratifyUrl;
|
int writeId;
|
int examineId;
|
int ratifyId;
|
try {
|
sealUrl = insReportMapper.getLaboratoryByName(laboratory);//印章
|
Map<String,Object> urlMap = insReportApproveConfigMapper.selectApprovalConfigByLaboratory(laboratory);//签名
|
writeUrl = imgUrl + "/" + (Objects.isNull(urlMap.get("writeUrl"))?"":urlMap.get("writeUrl").toString());//编制人签名url
|
examineUrl = imgUrl + "/" + (Objects.isNull(urlMap.get("examineUrl"))?"":urlMap.get("examineUrl").toString());//审核人签名url
|
ratifyUrl = imgUrl + "/" + (Objects.isNull(urlMap.get("ratifyUrl"))?"":urlMap.get("ratifyUrl").toString());//批准人签名url
|
writeId = Integer.parseInt(urlMap.get("writeId").toString());//编制人
|
examineId = Integer.parseInt(urlMap.get("examineId").toString());//审核人签
|
ratifyId =Integer.parseInt(urlMap.get("ratifyId").toString());//批准人
|
} catch (Exception e) {
|
throw new ErrorException("找不到签名和印章");
|
}
|
//设置报告信息
|
insReport.setIsExamine(1);
|
insReport.setIsRatify(1);
|
insReport.setState(1);
|
insReport.setWriteUserId(writeId);
|
insReport.setExamineUserId(examineId);
|
insReport.setRatifyUserId(ratifyId);
|
if(Objects.isNull(insReport.getWriteTime())){
|
insReport.setWriteTime(LocalDateTime.now());
|
}
|
if(Objects.isNull(insReport.getExamineTime())){
|
insReport.setExamineTime(LocalDateTime.now());
|
}
|
if(Objects.isNull(insReport.getRatifyTime())){
|
insReport.setRatifyTime(LocalDateTime.now());
|
}
|
//更新订单状态
|
InsOrder insOrder = new InsOrder();
|
insOrder.setId(insReport.getInsOrderId());
|
insOrder.setState(4);
|
insOrderMapper.updateById(insOrder);
|
//系统生成报告地址
|
String url = insReport.getUrl();
|
//手动上传报告地址
|
String urlS = insReport.getUrlS();
|
String finalUrl = (StringUtils.isBlank(urlS) ? url : urlS).replace("/word", wordUrl);
|
wordInsertUrl(new HashMap<String, Object>() {{
|
put("writeUrl", new FilePictureRenderData(100,50,writeUrl));
|
put("examineUrl", new FilePictureRenderData(100,50,examineUrl));
|
put("ratifyUrl", new FilePictureRenderData(100,50,ratifyUrl));
|
put("seal1", new FilePictureRenderData(600,600,imgUrl + "/" +sealUrl));
|
put("seal2", new FilePictureRenderData(600,600,imgUrl + "/" +sealUrl));
|
}}, finalUrl);
|
wordToPdf(finalUrl, sealUrl);
|
// 修改临时pdf
|
String tempUrlPdf = wordToPdfTemp((StrUtil.isBlank(urlS) ? url : urlS).replace("/word", wordUrl));
|
insReport.setTempUrlPdf("/word/" + tempUrlPdf);
|
//更新报告状态
|
insReportMapper.updateById(insReport);
|
//更新redis的key
|
Object o = redisTemplate.opsForValue().get(numKey);
|
if (Objects.isNull(o)) {
|
redisTemplate.opsForValue().set(numKey, 1);
|
} else {
|
long parsed = Long.parseLong(String.valueOf(o));
|
redisTemplate.opsForValue().set(numKey, parsed + 1);
|
}
|
redisTemplate.opsForValue().set(surplusKey, count.decrementAndGet());
|
}
|
long end = System.currentTimeMillis();
|
long useTime = (end-start)/1000;
|
log.info("线程{}报告审批结束,耗时:{}s",keyPrefix,useTime);
|
}
|
|
@Override
|
public Map<String, Object> getBatchApprovalProgress() {
|
Integer userId = SecurityUtils.getUserId().intValue();
|
String key = SYNC_REPORT_KEY_PREFIX + userId;
|
Map<String, Object> map = new HashMap<>();
|
map.put("hasProgress",false);
|
map.put("hasNum",0);
|
map.put("hasCount",0);
|
map.put("surplus",0);
|
Object o = redisTemplate.opsForValue().get(key);
|
if(Objects.nonNull(o)){
|
map.put("hasProgress",true);
|
}
|
Object o1 = redisTemplate.opsForValue().get(key+"_num");
|
Object o2 = redisTemplate.opsForValue().get(key+"_count");
|
Object surplus = redisTemplate.opsForValue().get(key+"_surplus");
|
Object exception = redisTemplate.opsForValue().get(key+"_exception");
|
if(Objects.nonNull(surplus)){
|
map.put("surplus",surplus);
|
}
|
if (Objects.nonNull(o1)&&Objects.nonNull(o2)){
|
//得到进度
|
BigDecimal multiply = new BigDecimal(String.valueOf(o1)).divide(new BigDecimal(String.valueOf(o2)), 2,BigDecimal.ROUND_DOWN).multiply(BigDecimal.valueOf(100));
|
map.put("hasNum",multiply);
|
map.put("hasCount",Long.parseLong(String.valueOf(o2)));
|
}
|
map.put("hasException",exception);
|
return map;
|
}
|
|
//解压文件夹
|
private void unzip(File zipFile, File destDir) throws IOException {
|
try (ZipFile zip = new ZipFile(zipFile)) {
|
Enumeration<? extends ZipEntry> entries = zip.entries();
|
while (entries.hasMoreElements()) {
|
ZipEntry entry = entries.nextElement();
|
File file = new File(destDir, entry.getName());
|
if (entry.isDirectory()) {
|
file.mkdirs();
|
} else {
|
file.getParentFile().mkdirs();
|
try (InputStream in = zip.getInputStream(entry);
|
OutputStream out = new FileOutputStream(file)) {
|
byte[] buffer = new byte[1024];
|
int len;
|
while ((len = in.read(buffer)) > 0) {
|
out.write(buffer, 0, len);
|
}
|
}
|
}
|
}
|
}
|
}
|
|
// 压缩文件夹
|
public static void zipDirectory(String sourceDirPath, String zipFilePath) throws IOException {
|
try (ZipOutputStream zipOut = new ZipOutputStream(new FileOutputStream(zipFilePath))) {
|
Path sourceDir = Paths.get(sourceDirPath);
|
Files.walk(sourceDir)
|
.filter(path -> !Files.isDirectory(path))
|
.forEach(path -> {
|
ZipEntry zipEntry = new ZipEntry(sourceDir.relativize(path).toString());
|
try {
|
zipOut.putNextEntry(zipEntry);
|
Files.copy(path, zipOut);
|
zipOut.closeEntry();
|
} catch (IOException e) {
|
e.printStackTrace();
|
}
|
});
|
}
|
}
|
|
// 删除文件夹及其内容
|
public static void deleteDirectory(File directory) throws IOException {
|
if (directory.isDirectory()) {
|
File[] files = directory.listFiles();
|
if (files != null) {
|
for (File file : files) {
|
deleteDirectory(file);
|
}
|
}
|
}
|
Files.delete(directory.toPath());
|
}
|
|
/**
|
* word转换pdf
|
* @param path
|
* @return
|
*/
|
public String wordToPdfTemp(String path) {
|
try {
|
return wordToPdf(path, path.replace(".docx", ".pdf"));
|
} catch (Exception e) {
|
throw new ErrorException("转换失败");
|
}
|
}
|
|
public String wordToPdf(String wordPath, String pdfPath) {
|
FileOutputStream os = null;
|
try {
|
//凭证 不然切换后有水印
|
InputStream is = Files.newInputStream(new File(licenseUrl).toPath());
|
License license = new License();
|
license.setLicense(is);
|
if (!license.getIsLicensed()) {
|
System.out.println("License验证不通过...");
|
return null;
|
}
|
//生成一个空的PDF文件
|
File file;
|
//判断是否是进厂报告
|
file = new File(pdfPath);
|
os = new FileOutputStream(file);
|
//要转换的word文件
|
Document doc = new Document(wordPath);
|
doc.save(os, SaveFormat.PDF);
|
String name = file.getName();
|
return file.getName();
|
} catch (Exception e) {
|
e.printStackTrace();
|
} finally {
|
if (os != null) {
|
try {
|
os.close();
|
} catch (IOException e) {
|
e.printStackTrace();
|
}
|
}
|
}
|
return null;
|
}
|
|
// @Override
|
// public void wordToPdf(String path, String sealUrl) {
|
// CompletableFuture.supplyAsync(() -> {
|
// try {
|
// wordToPdf(path, path.replace(".docx", ".pdf"), sealUrl);
|
// return null;
|
// } catch (Exception e) {
|
// throw new ErrorException("转换失败");
|
// }
|
// }).thenAccept(res -> {
|
// }).exceptionally(e -> {
|
// e.printStackTrace();
|
// return null;
|
// });
|
// }
|
|
|
|
// public String wordToPdf(String wordPath, String pdfPath, String sealUrl) {
|
// FileOutputStream os = null;
|
// try {
|
// //凭证 不然切换后有水印
|
//// InputStream inputStream = this.getClass().getResourceAsStream("/lib/license.xml");
|
// /*String url;
|
// try {
|
// InputStream inputStream = this.getClass().getResourceAsStream("/lib/license.xml");
|
// File file = File.createTempFile("temp", ".tmp");
|
// OutputStream outputStream = new FileOutputStream(file);
|
// IOUtils.copy(inputStream, outputStream);
|
// url = file.getAbsolutePath();
|
// } catch (FileNotFoundException e) {
|
// throw new ErrorException("找不到模板文件");
|
// } catch (IOException e) {
|
// throw new RuntimeException(e);
|
// }*/
|
// InputStream is = new ClassPathResource("/lib/license.xml").getInputStream();
|
// License license = new License();
|
// license.setLicense(is);
|
// if (!license.getIsLicensed()) {
|
// System.out.println("License验证不通过...");
|
// return null;
|
// }
|
// //生成一个空的PDF文件
|
// File file = new File(pdfPath.replace(".pdf", "-1.pdf"));
|
// os = new FileOutputStream(file);
|
// //要转换的word文件
|
// com.aspose.words.Document doc = new com.aspose.words.Document(wordPath);
|
// doc.save(os, SaveFormat.PDF);
|
//
|
// //添加骑缝章
|
// stamperCheckMarkPDF(pdfPath.replace(".pdf", "-1.pdf"), pdfPath, imgUrl + "/" + sealUrl);
|
//
|
//
|
// } catch (Exception e) {
|
// e.printStackTrace();
|
// } finally {
|
// if (os != null) {
|
// try {
|
// os.close();
|
// } catch (IOException e) {
|
// e.printStackTrace();
|
// }
|
// }
|
// }
|
// return null;
|
// }
|
|
/**
|
* 切割图片
|
*
|
* @param Path 图片路径
|
* @param n 切割份数
|
*/
|
public static com.itextpdf.text.Image[] slicingImages(String Path, int n) throws IOException, BadElementException {
|
com.itextpdf.text.Image[] nImage = new com.itextpdf.text.Image[n];
|
BufferedImage img = ImageIO.read(new File(Path));
|
|
int h = img.getHeight();
|
int w = img.getWidth();
|
|
int sw = w / n;
|
for (int i = 0; i < n; i++) {
|
BufferedImage subImg;
|
if (i == n - 1) {//最后剩余部分
|
subImg = img.getSubimage(i * sw, 0, w - i * sw, h);
|
} else {//前n-1块均匀切
|
subImg = img.getSubimage(i * sw, 0, sw, h);
|
}
|
ByteArrayOutputStream out = new ByteArrayOutputStream();
|
ImageIO.write(subImg, Path.substring(Path.lastIndexOf('.') + 1), out);
|
nImage[i] = com.itextpdf.text.Image.getInstance(out.toByteArray());
|
|
}
|
return nImage;
|
}
|
|
/**
|
* 盖骑缝章
|
*
|
* @param infilePath 原PDF路径
|
* @param outFilePath 输出PDF路径
|
*/
|
public static void stamperCheckMarkPDF(String infilePath, String outFilePath, String picPath) throws IOException, DocumentException {
|
PdfReader reader = new PdfReader(infilePath);//选择需要印章的pdf
|
PdfStamper stamp = new PdfStamper(reader, new FileOutputStream(outFilePath));//加完印章后的pdf
|
|
|
com.itextpdf.text.Rectangle pageSize = reader.getPageSize(1);//获得第一页
|
float height = pageSize.getHeight();
|
float width = pageSize.getWidth();
|
|
int nums = reader.getNumberOfPages();
|
com.itextpdf.text.Image[] nImage = slicingImages(picPath, nums);//生成骑缝章切割图片
|
|
for (int n = 1; n <= nums; n++) {
|
PdfContentByte over = stamp.getOverContent(n);//设置在第几页打印印章
|
com.itextpdf.text.Image img = nImage[n - 1];//选择图片
|
float newHeight = 100f;
|
float newWidth = img.getWidth() / (img.getHeight() / 100);
|
img.scaleAbsolute(newWidth, newHeight);//控制图片大小
|
img.setAbsolutePosition(width - newWidth, height / 2 - newHeight / 2);//控制图片位置
|
over.addImage(img);
|
}
|
stamp.close();
|
}
|
}
|