Bläddra i källkod

Merge branch 'master' of http://git.fmode.cn:3000/bin/edu-textbook

warrior 2 månader sedan
förälder
incheckning
96b38c1a3a

+ 20 - 6
server/cloud/tbook/func-tbook-export.js

@@ -213,9 +213,14 @@ export async function exportProcessReportDocs(processId,bookList) {
         let now = new Date();
         let fileList = docsList?.map(item=>item?.pdfPath);
         let zipName = `申报书导出-${now.getFullYear()}${now.getMonth()+1}${now.getDate()}-${now.getHours()}${now.getMinutes()}${now.getSeconds()}.zip`
-        zipPath = await createZip(fileList,zipName)
+        zipPath = await createZip(fileList,zipName,{tempDir:null})
         if(zipPath){
             zipUrl = (await uploadFileToOSS(zipPath))?.url || null
+            fs.rmSync(zipPath)
+            fileList.forEach(tempFile=>{
+                console.log("rm",tempFile)
+                fs.rmSync(path.dirname(tempFile),{recursive:true,force:true});
+            })
         }
         docsList = docsList.map(item=>{return {code:item.code,title:item.title,url:item?.url,urlPdf:item?.urlPdf}})
     }
@@ -505,8 +510,13 @@ function renderReportDocsByTextbook(textbook){
         })
     }
 
+ 
+    let bookTempDir = path.join(tempDir,bookid)
+    if(!fs.existsSync(bookTempDir)) fs.mkdirSync(bookTempDir)
+
+
     let codePngBuffer = await toBarCode(json?.code);
-    let codePngPath = path.join(tempDir,bookid+"code.png")
+    let codePngPath = path.join(bookTempDir,bookid+"code.png")
     fs.writeFileSync(codePngPath,codePngBuffer)
     // let codeBarImg = 
     // console.log(codeBarImg)
@@ -594,8 +604,11 @@ function renderReportDocsByTextbook(textbook){
     lastPageList.push(json?.authorSignPDF?.url||docx7);
     lastPageList.push(json?.unitMaterial?.url||docx8);
     lastPageList.push(docx9);
-    let lastPageFileName = path.join(tempDir,`${bookid}_${bookData.title}_申报书及附件_789.pdf`)
-    let lastPagePdf = await docxToPdf(null,lastPageFileName,{mergeFiles:lastPageList}) // 成功用pdf,失败继续用docx
+    let lastPageFileName = path.join(bookTempDir,`${bookid}_${bookData.title}_申报书及附件_789.pdf`)
+    let lastPagePdf = await docxToPdf(null,lastPageFileName,{mergeFiles:lastPageList,tempDir:bookTempDir}) // 成功用pdf,失败继续用docx
+    docx7&&fs.rmSync(docx7)
+    docx8&&fs.rmSync(docx8)
+    docx9&&fs.rmSync(docx9)
     // mergeFiles = [...lastPageList,...mergeFiles]
     mergeFiles = [lastPagePdf,...mergeFiles]
 
@@ -610,14 +623,15 @@ function renderReportDocsByTextbook(textbook){
         }
         try{
             // DOCX模板合成 速度2-3秒
-            filePath = renderDocx(TemplateDocxPath,tempFileName,bookData)
+            filePath = renderDocx(TemplateDocxPath,tempFileName,bookData,{tempDir:bookTempDir})
             urlDocx = (await uploadFileToOSS(filePath))?.url || null
             console.log("DOCX CREATED:",filePath)
 
             // PDF文档拼接 速度10-30s 需要API支持
             pdfPath = filePath.replaceAll(".docx",".pdf")
             let options = {
-                mergeFiles:mergeFiles
+                mergeFiles:mergeFiles,
+                tempDir:bookTempDir
             }
             pdfPath = await docxToPdf(filePath,pdfPath,options) || filePath // 成功用pdf,失败继续用docx
             console.log("PDF CREATED:",filePath)

+ 2 - 2
server/cloud/tbook/test/test-export.js

@@ -32,9 +32,9 @@ async function main(){
         // console.log(await exportProcessReportDocs(null,["MU5YpUizfW"]))
         // console.log(await exportProcessReportDocs(null,["UUGgHPHsIC"]))
         // console.log(await exportProcessReportDocs(null,["KxhErArSbB"]))
-        console.log(await exportProcessReportDocs(null,["3wJSkW9HNV"]))
+        console.log(await exportProcessReportDocs(null,["7cf69rSawD"]))
         
-
+        // console.log(await exportProcessReportDocs(null,["3wJSkW9HNV"]))
         // console.log(await exportProcessReportDocs(null,["tHhfIDBkhf"]))
         // console.log(await exportProcessReportDocs(null,["cgTEtIvkK4"]))
         // console.log(await exportProcessReportDocs(null,["KvvN9lWhri"]))

+ 43 - 20
server/lib/docs/index.js

@@ -77,11 +77,11 @@ module.exports.uploadFileToOSS = uploadFileToOSS
  * @param {Array<string>} filePathList - 要打包的文件路径数组
  * @param {string} outputZipName - 输出的zip文件名称
  */
- export function createZip(filePathList, outputZipName) {
+ export function createZip(filePathList, outputZipName,options) {
     let zipStream = new compressing.zip.Stream();
     return new Promise((resolve)=>{
         try {
-            let outputPath = path.join(tempDir,outputZipName)
+            let outputPath = path.join(options?.tempDir||tempDir,outputZipName)
             // 遍历文件路径列表,将每个文件添加到zip流中
             for (const filePath of filePathList) {
                 // 检查文件是否存在
@@ -125,13 +125,13 @@ module.exports.createZip = createZip
 
 
 const download = require('download')
-async function downloadUrl(url) {
+async function downloadUrl(url,options) {
     // console.log(url)
     if(url?.startsWith("/")) {return url};
     let md5 = crypto.createHash('md5');
     let extname = path.extname(url)?.toLocaleLowerCase();
     let filename = md5.update(url).digest('hex') + extname;
-    let filepath = path.join(tempDir,filename)
+    let filepath = path.join(options?.tempDir||tempDir,filename)
     // console.log(filename,filepath)
     try{
         // if(fs.existsSync(filepath)){fs.rmSync(filepath)} // 存在则删除
@@ -161,7 +161,7 @@ async function downloadUrl(url) {
             let filePath
             plist.push((async ()=>{
                 try{
-                    filePath = await downloadUrl(mergeFiles[index]);
+                    filePath = await downloadUrl(mergeFiles[index],options);
                 }catch(err){}
                 if(filePath){
                     mergeFileMap[index] = filePath // 按原有顺序整理
@@ -236,13 +236,24 @@ async function downloadUrl(url) {
         //     pdfBuffer = await LibreOffice.convert(convertOpts);
         // }
 
+        let mainPdfPath = docxPath
+        if(docxPath){
+            convertOpts.files = [files[0]];
+            console.log(convertOpts)
+            let mainPdfBuffer = await LibreOffice.convert(convertOpts);
+            mainPdfPath = path.dirname(docxPath)+"/109_"+path.basename(docxPath)+".pdf"
+            fs.writeFileSync(mainPdfPath,mainPdfBuffer)
+        }
+
         // 方式2:先合并pdf,后合并docx
         if(files?.length>4){
-            let pdfList = files.slice(1);
+            let pdfList = [mainPdfPath,...files.slice(1)];
+            pdfList = pdfList.filter(item=>item)
             let mergedFileList = await mergePdfListReduce(pdfList,convertOpts) 
-            convertOpts.files = [files[0],...mergedFileList]
+            pdfBuffer = mergedFileList[0]?.data;
+        // convertOpts.files = [files[0],...mergedFileList]
             // console.log(convertOpts)
-            pdfBuffer = await LibreOffice.convert(convertOpts);
+            // pdfBuffer = await LibreOffice.convert(convertOpts);
         }else{
             pdfBuffer = await LibreOffice.convert(convertOpts);
         }
@@ -272,6 +283,17 @@ const sizeOf = require("image-size");
  */
 export async function mergePdfListReduce(pdfList,convertOpts){
     console.log("pdfList",pdfList)
+    // 所有非PDF转PDF
+    for (let index = 0; index < pdfList.length; index++) {
+        let file = pdfList[index];
+        if(file?.toLocaleLowerCase()?.indexOf("pdf")==-1){
+            convertOpts.files = [file];
+            let pdfBuffer = await LibreOffice.convert(convertOpts);
+            fs.writeFileSync(file+".pdf",pdfBuffer)
+            pdfList[index] = file+".pdf"
+        }
+    }
+
     let mergeList = []
     let plist = []
     let length = pdfList.length
@@ -280,10 +302,11 @@ export async function mergePdfListReduce(pdfList,convertOpts){
         // console.log(file,index,length)
         if(!file) break;
         let files = [file,pdfList.shift(),pdfList.shift(),pdfList.shift()
-            ,pdfList.shift()
-            ,pdfList.shift()
-            ,pdfList.shift(),pdfList.shift(),pdfList.shift()
-            ,pdfList.shift(),pdfList.shift(),pdfList.shift()
+            ,pdfList.shift(),pdfList.shift(),pdfList.shift(),pdfList.shift()
+            ,pdfList.shift(),pdfList.shift(),pdfList.shift(),pdfList.shift()
+            ,pdfList.shift(),pdfList.shift(),pdfList.shift(),pdfList.shift()
+            // ,pdfList.shift(),pdfList.shift(),pdfList.shift()
+            // ,pdfList.shift(),pdfList.shift(),pdfList.shift()
             // ,pdfList.shift(),pdfList.shift(),pdfList.shift(),pdfList.shift()
         ]; // 每次合并四个
         files=files?.filter(item=>item);
@@ -318,7 +341,7 @@ export async function mergePdfListReduce(pdfList,convertOpts){
     }
 }
 
-export function renderDocx(inputDocxPath, outputDocxName, options){
+export function renderDocx(inputDocxPath, outputDocxName, data,options){
     let imageOptions = {
         getImage(tagValue,tagName) {
             if(!fs.existsSync(tagValue)){
@@ -333,7 +356,7 @@ export function renderDocx(inputDocxPath, outputDocxName, options){
         },
     };
     
-    let outputDocxPath = path.join(tempDir,outputDocxName)
+    let outputDocxPath = path.join(options?.tempDir||tempDir,outputDocxName)
     // Load the docx file as binary content
     let content = fs.readFileSync(
         inputDocxPath,
@@ -349,12 +372,12 @@ export function renderDocx(inputDocxPath, outputDocxName, options){
     });
 
     // Render the document (Replace {first_name} by John, {last_name} by Doe, ...)
-    Object.keys(options).forEach(key=>{ // 除去空值
-        if(options[key]==undefined){
-            options[key] = ""
+    Object.keys(data).forEach(key=>{ // 除去空值
+        if(data[key]==undefined){
+            data[key] = ""
         }
     })
-    doc.render(options);
+    doc.render(data);
 
     // Get the zip document and generate it as a nodebuffer
     let buf = doc.getZip().generate({
@@ -389,13 +412,13 @@ export function replaceDocx(inputDocxPath, outputDocxPath, options,eventMap) {
     // 解压出来的临时目录
     let md5 = crypto.createHash('md5');
     let outmd5 = md5.update(outputDocxPath).digest('hex')
-    let tempDocxPath =  path.join(tempDir , outmd5)
+    let tempDocxPath =  path.join(options?.tempDir||tempDir , outmd5)
     // 要替换的xml文件位置
     let tempDocxXMLName = path.join(tempDocxPath,`word/document.xml`)
 
     // 压缩文件夹为文件
     let dir_to_docx = (inputFilePath, outputFilePath) => {
-        outputFilePath = path.join(tempDir,outputFilePath)
+        outputFilePath = path.join(options?.tempDir||tempDir,outputFilePath)
         // 创建压缩流
         let zipStream = new compressing.zip.Stream()
         // 写出流