|
|
@@ -0,0 +1,262 @@
|
|
|
+package com.wx.blink.backend.manager;
|
|
|
+
|
|
|
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
|
|
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
|
|
+import com.itextpdf.text.PageSize;
|
|
|
+import com.itextpdf.text.pdf.PdfDocument;
|
|
|
+import com.wx.blink.backend.domain.dataobject.BlinkCustomerVisitItineraryDDO;
|
|
|
+import com.wx.blink.backend.domain.dataobject.BlinkCustomerVisitItineraryDO;
|
|
|
+import com.wx.blink.backend.domain.dto.BlinkCustomerVisitItineraryDVO;
|
|
|
+import com.wx.blink.backend.domain.dto.BlinkCustomerVisitItineraryVO;
|
|
|
+import com.wx.blink.backend.domain.qry.BlinkCustomerVisitItineraryQry;
|
|
|
+import com.wx.blink.backend.objectmapper.BlinkCustomerVisitItineraryMapper;
|
|
|
+import com.wx.blink.backend.repository.BlinkCustomerVisitItineraryDRepository;
|
|
|
+import com.wx.blink.backend.repository.BlinkCustomerVisitItineraryRepository;
|
|
|
+import com.wx.blink.backend.service.IBlinkCustomerVisitItineraryDService;
|
|
|
+import com.wx.blink.backend.service.IBlinkCustomerVisitItineraryService;
|
|
|
+import com.wx.blink.base.common.domain.PageResult;
|
|
|
+import com.wx.blink.base.common.domain.RequestUser;
|
|
|
+import com.wx.blink.base.common.domain.ResponseDTO;
|
|
|
+import com.wx.blink.base.common.util.BlinkEntityUtil;
|
|
|
+import com.wx.blink.base.common.util.BlinkPageUtil;
|
|
|
+import com.wx.blink.base.common.util.BlinkRequestUtil;
|
|
|
+import com.wx.blink.base.module.support.file.domain.vo.FileUploadVO;
|
|
|
+import com.wx.blink.base.module.support.file.service.FileService;
|
|
|
+import com.wx.blink.base.module.support.pdf.PDFCommonGenerator;
|
|
|
+import org.apache.commons.fileupload.FileItem;
|
|
|
+import org.apache.commons.fileupload.disk.DiskFileItem;
|
|
|
+import org.springframework.stereotype.Service;
|
|
|
+
|
|
|
+import javax.annotation.Resource;
|
|
|
+import java.io.*;
|
|
|
+import java.text.MessageFormat;
|
|
|
+import java.util.HashMap;
|
|
|
+import java.util.List;
|
|
|
+import java.util.Map;
|
|
|
+
|
|
|
+import com.itextpdf.text.*;
|
|
|
+import com.itextpdf.text.pdf.PdfWriter;
|
|
|
+import org.springframework.web.multipart.MultipartFile;
|
|
|
+import org.springframework.web.multipart.commons.CommonsMultipartFile;
|
|
|
+import org.xhtmlrenderer.pdf.ITextRenderer;
|
|
|
+
|
|
|
+
|
|
|
+@Service
|
|
|
+public class BlinkCustomerVisitItineraryImpl extends ServiceImpl<BlinkCustomerVisitItineraryRepository, BlinkCustomerVisitItineraryDO> implements IBlinkCustomerVisitItineraryService {
|
|
|
+
|
|
|
+ @Resource
|
|
|
+ private BlinkCustomerVisitItineraryRepository visitItineraryRepository;
|
|
|
+ @Resource
|
|
|
+ private BlinkCustomerVisitItineraryMapper visitItineraryMapper;
|
|
|
+ @Resource
|
|
|
+ private BlinkCustomerVisitItineraryDRepository visitItineraryDRepository;
|
|
|
+ @Resource
|
|
|
+ private IBlinkCustomerVisitItineraryDService visitItineraryDService;
|
|
|
+ @Resource
|
|
|
+ private FileService fileService;
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public void addOrUpdate(BlinkCustomerVisitItineraryVO vo) {
|
|
|
+ BlinkCustomerVisitItineraryDO visitItineraryDO = visitItineraryMapper.customerVisitItineraryVOtoDomain(vo);
|
|
|
+ if (visitItineraryDO != null) {
|
|
|
+ String itineraryName = "";
|
|
|
+ String arrivalCitys = "";
|
|
|
+ Double durations = 0.0;
|
|
|
+ String attachments = "";
|
|
|
+ if (vo.getVisitItineraryDVOList() != null && !vo.getVisitItineraryDVOList().isEmpty()) {
|
|
|
+ itineraryName = vo.getVisitItineraryDVOList().get(0).getArrivalDate().toString() + "~"
|
|
|
+ + vo.getVisitItineraryDVOList().get(vo.getVisitItineraryDVOList().size() - 1).getArrivalDate().toString();
|
|
|
+ attachments = createPdfAttachment(itineraryName,vo.getVisitItineraryDVOList());
|
|
|
+ int rowNum = 0;
|
|
|
+ for (BlinkCustomerVisitItineraryDVO visitItineraryDVO : vo.getVisitItineraryDVOList()) {
|
|
|
+ rowNum++;
|
|
|
+ arrivalCitys += visitItineraryDVO.getArrivalCity();
|
|
|
+ if (rowNum < vo.getVisitItineraryDVOList().size()) {
|
|
|
+ arrivalCitys += "、";
|
|
|
+ }
|
|
|
+ durations += visitItineraryDVO.getDuration();
|
|
|
+ }
|
|
|
+ visitItineraryDO.setItineraryName(itineraryName);
|
|
|
+ visitItineraryDO.setArrivalCitys(arrivalCitys);
|
|
|
+ visitItineraryDO.setDurations(durations);
|
|
|
+ visitItineraryDO.setAttachments(attachments);
|
|
|
+ }
|
|
|
+ //生成PDF
|
|
|
+
|
|
|
+ //有id更新,没有则新增
|
|
|
+ if (visitItineraryDO.getId() == null || visitItineraryDO.getId() == "") {
|
|
|
+ //创建人赋值
|
|
|
+ BlinkEntityUtil.setCreateInfo(visitItineraryDO);
|
|
|
+ this.save(visitItineraryDO);
|
|
|
+ //保存明细
|
|
|
+ if (vo.getVisitItineraryDVOList() != null && !vo.getVisitItineraryDVOList().isEmpty()) {
|
|
|
+ for (BlinkCustomerVisitItineraryDVO visitItineraryDVO : vo.getVisitItineraryDVOList()) {
|
|
|
+ BlinkCustomerVisitItineraryDDO visitItineraryDDO = visitItineraryMapper.customerVisitItineraryDVOtoDomain(visitItineraryDVO);
|
|
|
+ visitItineraryDDO.setPid(visitItineraryDO.getId());
|
|
|
+ visitItineraryDService.save(visitItineraryDDO);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ //更新人赋值
|
|
|
+ BlinkEntityUtil.setUpdatedInfo(visitItineraryDO);
|
|
|
+ this.updateById(visitItineraryDO);
|
|
|
+ //处理明细
|
|
|
+ Map<String, Object> delParam = new HashMap<>();
|
|
|
+ delParam.put("pid", visitItineraryDO.getId());
|
|
|
+ visitItineraryDService.removeByMap(delParam);
|
|
|
+ if (vo.getVisitItineraryDVOList() != null && !vo.getVisitItineraryDVOList().isEmpty()) {
|
|
|
+ for (BlinkCustomerVisitItineraryDVO visitItineraryDVO : vo.getVisitItineraryDVOList()) {
|
|
|
+ BlinkCustomerVisitItineraryDDO visitItineraryDDO = visitItineraryMapper.customerVisitItineraryDVOtoDomain(visitItineraryDVO);
|
|
|
+ visitItineraryDDO.setPid(visitItineraryDO.getId());
|
|
|
+ visitItineraryDService.save(visitItineraryDDO);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public PageResult<BlinkCustomerVisitItineraryVO> visitItineraryQueryPage(BlinkCustomerVisitItineraryQry qry) {
|
|
|
+ Page<?> page = BlinkPageUtil.convert2PageQuery(qry);
|
|
|
+ List<BlinkCustomerVisitItineraryVO> list = visitItineraryRepository.visitItineraryQueryPage(page);
|
|
|
+ PageResult<BlinkCustomerVisitItineraryVO> pageResult = BlinkPageUtil.convert2PageResult(page, list);
|
|
|
+ return pageResult;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 生成pdf
|
|
|
+ */
|
|
|
+ public String createPdfAttachment(String itineraryName, List<BlinkCustomerVisitItineraryDVO> vos) {
|
|
|
+ try {
|
|
|
+ MultipartFile file = new CommonsMultipartFile(createBlankPdfFileItem("attachments", itineraryName + ".pdf",vos));
|
|
|
+ RequestUser requestUser = BlinkRequestUtil.getRequestUser();
|
|
|
+ ResponseDTO<FileUploadVO> uploadedfile = fileService.fileUpload(file, 1, requestUser);
|
|
|
+ return uploadedfile.getData().getFileKey();
|
|
|
+ } catch (Exception e) {
|
|
|
+ throw new RuntimeException(e);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 创建一个空的PDF字节数组
|
|
|
+ *
|
|
|
+ * @return 包含空PDF的字节数组
|
|
|
+ */
|
|
|
+ public byte[] createEmptyPdfBytes() {
|
|
|
+ ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
|
|
|
+
|
|
|
+ // 创建PDF文档
|
|
|
+ Document document = new Document();
|
|
|
+ try {
|
|
|
+ PdfWriter.getInstance(document, outputStream);
|
|
|
+ document.open();
|
|
|
+ // 不添加任何内容,创建空白PDF
|
|
|
+ document.close();
|
|
|
+ } catch (Exception e) {
|
|
|
+ e.printStackTrace();
|
|
|
+ }
|
|
|
+
|
|
|
+ return outputStream.toByteArray();
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 生成PDF文件流
|
|
|
+ *
|
|
|
+ * @param vos PDF内容文本
|
|
|
+ * @param fileName 自定义文件名(不含.pdf扩展名)
|
|
|
+ * @return 包含PDF字节数组和文件名的结果对象
|
|
|
+ * @throws IOException
|
|
|
+ */
|
|
|
+ public byte[] generatePdf(List<BlinkCustomerVisitItineraryDVO> vos, String fileName) throws IOException {
|
|
|
+ // 1. 创建HTML内容(简单包装)
|
|
|
+ String htmlContent = wrapContentInHtml(vos);
|
|
|
+
|
|
|
+ // 2. 生成PDF
|
|
|
+ ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
|
|
|
+ ITextRenderer renderer = new ITextRenderer();
|
|
|
+
|
|
|
+ try {
|
|
|
+ renderer.setDocumentFromString(htmlContent);
|
|
|
+ renderer.layout();
|
|
|
+ renderer.createPDF(outputStream);
|
|
|
+ return outputStream.toByteArray();
|
|
|
+ } catch (Exception e) {
|
|
|
+ e.printStackTrace();
|
|
|
+ } finally {
|
|
|
+ outputStream.close();
|
|
|
+ }
|
|
|
+ return null;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 将纯文本包装为简单HTML
|
|
|
+ */
|
|
|
+ private String wrapContentInHtml(List<BlinkCustomerVisitItineraryDVO> vos) {
|
|
|
+ String result = "<!DOCTYPE html>" +
|
|
|
+ "<html>" +
|
|
|
+ "<head>" +
|
|
|
+ "<meta charset=\"UTF-8\">" +
|
|
|
+ "<style>" +
|
|
|
+ "body { font-family: SimSun; font-size: 14px; }" +
|
|
|
+ "h1 { color: #333; text-align: center; }" +
|
|
|
+ "</style>" +
|
|
|
+ "</head>" +
|
|
|
+ "<body>" +
|
|
|
+ "<h1>文档内容</h1>";
|
|
|
+ String content = "<div> 到达城市:{0} 到达日期:{1} 停留周期:{2}天 </div>";
|
|
|
+
|
|
|
+ for (BlinkCustomerVisitItineraryDVO vo : vos) {
|
|
|
+ result += MessageFormat.format(content, vo.getArrivalCity(), vo.getArrivalDate().toString(), vo.getDuration().toString());
|
|
|
+ }
|
|
|
+ result += "</body>" + "</html>";
|
|
|
+ return result;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 创建空白PDF的FileItem
|
|
|
+ *
|
|
|
+ * @param fieldName 表单字段名
|
|
|
+ * @param fileName PDF文件名(如"blank.pdf")
|
|
|
+ * @return FileItem对象
|
|
|
+ */
|
|
|
+ public FileItem createBlankPdfFileItem(String fieldName, String fileName, List<BlinkCustomerVisitItineraryDVO> vos) {
|
|
|
+ // 1. 创建空白PDF字节数组
|
|
|
+ try {
|
|
|
+ byte[] pdfBytes = generatePdf(vos, fileName);
|
|
|
+ // 2. 创建DiskFileItem
|
|
|
+ DiskFileItem fileItem = new DiskFileItem(
|
|
|
+ fieldName, // 表单字段名
|
|
|
+ "application/pdf", // 内容类型
|
|
|
+ false, // 是否表单字段
|
|
|
+ fileName, // 文件名
|
|
|
+ 1024, // 缓冲区大小
|
|
|
+ new File(System.getProperty("java.io.tmpdir")) // 临时目录
|
|
|
+ {
|
|
|
+ }
|
|
|
+ );
|
|
|
+ // 3. 将PDF字节写入FileItem
|
|
|
+ try (OutputStream os = fileItem.getOutputStream()) {
|
|
|
+ os.write(pdfBytes);
|
|
|
+ } catch (Exception e) {
|
|
|
+ e.printStackTrace();
|
|
|
+ }
|
|
|
+ return fileItem;
|
|
|
+
|
|
|
+ } catch (Exception e) {
|
|
|
+ e.printStackTrace();
|
|
|
+ }
|
|
|
+ return null;
|
|
|
+ }
|
|
|
+
|
|
|
+ public File getAbsoluteFile(String uploadDir, String fileName) throws IOException {
|
|
|
+ File desc = new File(uploadDir + File.separator + fileName);
|
|
|
+
|
|
|
+ if (!desc.exists()) {
|
|
|
+ if (!desc.getParentFile().exists()) {
|
|
|
+ desc.getParentFile().mkdirs();
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return desc;
|
|
|
+ }
|
|
|
+
|
|
|
+}
|