Procházet zdrojové kódy

功能新增,PDF下载功能

lihao16 před 1 rokem
rodič
revize
7961fcf335

+ 7 - 1
inspur-party/pom.xml

@@ -59,6 +59,12 @@
             <artifactId>inspur-ai</artifactId>
             <version>3.8.2</version>
         </dependency>
+        <dependency>
+            <groupId>com.itextpdf</groupId>
+            <artifactId>itext7-core</artifactId>
+            <version>7.1.9</version>
+            <type>pom</type>
+        </dependency>
     </dependencies>
 
-</project>
+</project>

+ 75 - 3
inspur-party/src/main/java/com/inspur/service/partywork/impl/PartyMeetingAudioServiceImpl.java

@@ -23,6 +23,11 @@ import com.inspur.mapper.PartyMeetingAudioMapper;
 import com.inspur.mapper.PartyMeetingInfoMapper;
 import com.inspur.moonshot.domain.*;
 import com.inspur.service.partywork.IPartyMeetingAudioService;
+import org.apache.pdfbox.pdmodel.PDDocument;
+import org.apache.pdfbox.pdmodel.PDPage;
+import org.apache.pdfbox.pdmodel.PDPageContentStream;
+import org.apache.pdfbox.pdmodel.common.PDRectangle;
+import org.apache.pdfbox.pdmodel.font.PDType0Font;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.springframework.beans.factory.annotation.Autowired;
@@ -232,7 +237,7 @@ public class PartyMeetingAudioServiceImpl implements IPartyMeetingAudioService
                 }
             }
         }
-        String content = contentSb.toString() + ";总结以上文字内容,并形成会议纪要。";
+        String content = contentSb.toString() + ";对以上文字进行提炼总结内容,只允许返回中文,不能出现特殊符号。字数控制在1000字以内。";
         log.info("summaryGenerate content.length : " + content.length());
         String baseDir = InspurConfig.getUploadPath();
         String filePath = baseDir + "/meeting_summary" + "/" + meetingId + "/";
@@ -252,10 +257,11 @@ public class PartyMeetingAudioServiceImpl implements IPartyMeetingAudioService
         summary.setCreateTime(DateUtils.getNowDate());
         partyMeetingAudioMapper.insertPartyMeetingAudio(summary);
         // 异步线程池
-        moonshotGenerate(content, filePath + fileName, summary,partyMeetingAudioMapper);
+        moonshotGenerate(content, filePath + fileName, summary,partyMeetingAudioMapper,meetingInfo);
         return AjaxResult.success("一键生成任务创建成功,请刷新列表");
     }
-    private void moonshotGenerate(String reqContent,String filePath, PartyMeetingAudio summary, PartyMeetingAudioMapper partyMeetingAudioMapper) {
+
+    private void moonshotGenerate(String reqContent, String filePath, PartyMeetingAudio summary, PartyMeetingAudioMapper partyMeetingAudioMapper, PartyMeetingInfo meetingInfo) {
         Thread thread = new Thread(() -> {
             log.info("moonshotGenerate thread start ... ");
             StringBuffer rspSb = new StringBuffer();
@@ -290,10 +296,14 @@ public class PartyMeetingAudioServiceImpl implements IPartyMeetingAudioService
                     summary.setIsTranslate(3);
                 }
                 cn.hutool.core.io.FileUtil.writeString(txtRsp, filePath, "UTF-8");
+                // 生成pdf文件
+                generatePdf(txtRsp,summary,meetingInfo);
+                summary.setTxtUrl(serverConfig.getNewUrl() + filePath.replace("/home/inspur/party-admin/uploadPath", "/profile"));
                 summary.setIsTranslate(4);
             }catch (Exception e) {
                 summary.setIsTranslate(3);
                 log.info("moonshotGenerate error ...,{}",e.getMessage());
+                e.printStackTrace();
             }finally {
                 // 更新状态
                 summary.setUpdateTime(DateUtils.getNowDate());
@@ -304,6 +314,68 @@ public class PartyMeetingAudioServiceImpl implements IPartyMeetingAudioService
         thread.start();
     }
 
+    private void generatePdf(String txtRsp, PartyMeetingAudio summary, PartyMeetingInfo meetingInfo) throws IOException {
+        // 根据实际路径调整
+        // String fontPath = "D:\\home\\inspur\\font\\simhei.ttf";
+        String fontPath = "/home/inspur/font/simhei.ttf";
+        // try () {
+        PDDocument document = new PDDocument();
+        PDPage page = new PDPage(PDRectangle.A4);
+        document.addPage(page);
+        PDType0Font font = PDType0Font.load(document, new File(fontPath));
+        try (PDPageContentStream contents = new PDPageContentStream(document, page)) {
+            contents.beginText();
+            // 文本开始的x坐标
+            float startX = 50;
+            // 文本开始的y坐标(A4纸顶部向下约50单位)
+            float startY = 730;
+            contents.newLineAtOffset(startX, startY);
+            writeTextWithWrapAndSpacing(contents, font, 18,  meetingInfo.getTitle(), page.getMediaBox().getWidth() - 2 * startX, 30);
+            writeTextWithWrapAndSpacing(contents, font, 14, "会议地点: " + meetingInfo.getAddress(), page.getMediaBox().getWidth() - 2 * startX, 25);
+            writeTextWithWrapAndSpacing(contents, font, 14, "会议主持: " + meetingInfo.getHost(), page.getMediaBox().getWidth() - 2 * startX, 25);
+            writeTextWithWrapAndSpacing(contents, font, 14, "发起组织: " + meetingInfo.getFromOrg(), page.getMediaBox().getWidth() - 2 * startX, 25);
+            String beginTime = DateUtils.parseDateToStr("yyyy-MM-dd HH:mm:ss", meetingInfo.getBeginTime());
+            String endTime = DateUtils.parseDateToStr("yyyy-MM-dd HH:mm:ss", meetingInfo.getEndTime());
+            writeTextWithWrapAndSpacing(contents, font, 14, "会议时间: " + beginTime + " - " + endTime, page.getMediaBox().getWidth() - 2 * startX, 25);
+            writeTextWithWrapAndSpacing(contents, font, 14, "会议内容:", page.getMediaBox().getWidth() - 2 * startX, 20);
+            String formatText = formatText(txtRsp);
+            writeTextWithWrapAndSpacing(contents, font, 12, formatText, page.getMediaBox().getWidth() - 2 * startX, 15);
+            contents.endText();
+            contents.close();
+        }
+        document.save(summary.getTxtPath() + ".pdf");
+        System.out.println("end");
+        /*} catch (IOException e) {
+            e.printStackTrace();
+        }*/
+    }
+
+    public static String formatText(String text) {
+        // 使用replaceAll去除所有可能的换行符和空格
+        return text.replaceAll("[\\n\\r\\s*]+", "");
+    }
+
+    private static void writeTextWithWrapAndSpacing(PDPageContentStream contentStream, PDType0Font font, float fontSize, String text, float maxWidth, float spacing) throws IOException {
+        float currentWidth = 0;
+        float spaceWidth = font.getStringWidth(" ") / 1000 * fontSize; // 计算空格宽度
+        float initialOffset = -fontSize * 1.5f; // 初始换行偏移
+        contentStream.setFont(font, fontSize);
+        for (int i = 0; i < text.length(); i++) {
+            String c = text.substring(i, i + 1);
+            float charWidth = font.getStringWidth(c) / 1000 * fontSize;
+            if (currentWidth + charWidth > maxWidth) {
+                // 换行
+                contentStream.newLineAtOffset(0, initialOffset);
+                currentWidth = 0;
+                initialOffset = -fontSize * 1.5f; // 重置换行偏移,确保后续行使用相同的行间距
+            }
+            contentStream.showText(c);
+            currentWidth += charWidth;
+        }
+        // 每个段落后添加额外的间隔
+        contentStream.newLineAtOffset(0, -spacing);
+    }
+
     @Override
     public AjaxResult updateAudioTxt(PartyMeetingAudio partyMeetingAudio) throws IOException {
         // 查询audio数据库信息

+ 15 - 0
inspur-ui/src/views/party_work/meeting/info.vue

@@ -361,6 +361,7 @@
             <div style="margin-top: 35px;display: flex;justify-content: center;align-items: center;">
               <el-button type="primary" @click="audioTxtEdit">文本编辑</el-button>
               <el-button type="primary" @click="audioTxtSave">文本保存</el-button>
+              <el-button type="primary" v-if="this.havePdf" @click="downloadPdf">纪要下载</el-button>
             </div>
 
           </div>
@@ -724,6 +725,8 @@
           value: '100',
           label: '100%'
         }],
+        havePdf: false,
+        pdfUrl : "",
         firstPhoto: null,
         firstPhotoList: [],
         selectedFileIndex: -1,
@@ -1038,8 +1041,20 @@
         this.audioId = id;
         getAudio(id).then(response => {
           this.audioTxt = response.data.audioTxt;
+          if (response.data.isTranslate === 4) {
+            this.havePdf = true;
+            this.pdfUrl = response.data.txtUrl + ".pdf";
+          }else {
+            this.havePdf = false;
+          }
         });
       },
+      downloadPdf() {
+        if (this.pdfUrl != null || this.pdfUrl != '') {
+          // 下载文件
+          window.open(this.pdfUrl);
+        }
+      },
       audioTxtSave() {
         this.audioReadOnly = true;
         let id = this.audioId;