|
@@ -192,9 +192,17 @@
|
|
|
<el-table-column prop="createTime" label="绑定时间" align="center" />
|
|
|
<el-table-column label="操作" align="center" width="320">
|
|
|
<template #default="scope">
|
|
|
- <el-button type="primary" @click="previewTemplate(scope.row)">预览</el-button>
|
|
|
- <el-button type="primary" @click="replaceTemplate(scope.row)">替换</el-button>
|
|
|
- <el-dropdown style="margin-left: 10px;" trigger="click" @command="(command) => handleExport(command, scope.row)">
|
|
|
+ <el-button type="primary" @click="previewTemplate(scope.row)"
|
|
|
+ >预览</el-button
|
|
|
+ >
|
|
|
+ <el-button type="primary" @click="replaceTemplate(scope.row)"
|
|
|
+ >替换</el-button
|
|
|
+ >
|
|
|
+ <el-dropdown
|
|
|
+ style="margin-left: 10px"
|
|
|
+ trigger="click"
|
|
|
+ @command="(command) => handleExport(command, scope.row)"
|
|
|
+ >
|
|
|
<el-button type="success">
|
|
|
导出文档<i class="el-icon-arrow-down el-icon--right"></i>
|
|
|
</el-button>
|
|
@@ -202,6 +210,9 @@
|
|
|
<el-dropdown-menu>
|
|
|
<el-dropdown-item command="word">Word格式</el-dropdown-item>
|
|
|
<el-dropdown-item command="pdf">PDF格式</el-dropdown-item>
|
|
|
+ <!-- <el-dropdown-item command="pdf-to-word"
|
|
|
+ >PDF转Word</el-dropdown-item
|
|
|
+ > -->
|
|
|
</el-dropdown-menu>
|
|
|
</template>
|
|
|
</el-dropdown>
|
|
@@ -259,7 +270,12 @@ import {
|
|
|
calculate,
|
|
|
getphases,
|
|
|
} from "@/api/project";
|
|
|
-import { searchList, updateDocument, exportDocument,exportToPDF } from "@/api/document";
|
|
|
+import {
|
|
|
+ searchList,
|
|
|
+ updateDocument,
|
|
|
+ exportDocument,
|
|
|
+ exportToPDF,
|
|
|
+} from "@/api/document";
|
|
|
import { searchCustomer } from "@/api/customer";
|
|
|
import { searchProduct } from "@/api/product";
|
|
|
/* import {searchTemplate} from "@/api/template" */
|
|
@@ -343,6 +359,57 @@ export default {
|
|
|
this.init();
|
|
|
},
|
|
|
methods: {
|
|
|
+ // 添加 PDF 转 Word 的方法
|
|
|
+ async convertPDFToWord(pdfPath) {
|
|
|
+ try {
|
|
|
+ // 创建FormData对象
|
|
|
+ const formData = new FormData();
|
|
|
+ formData.append("oss_url", pdfPath);
|
|
|
+
|
|
|
+ // 调用后端转换接口
|
|
|
+ const res = await axios.post(
|
|
|
+ `${process.env.VUE_APP_BASE_API}/convert/pdftoword`,
|
|
|
+ formData,
|
|
|
+ {
|
|
|
+ headers: {
|
|
|
+ "Content-Type": "multipart/form-data", // 设置请求头为form-data
|
|
|
+ },
|
|
|
+ }
|
|
|
+ );
|
|
|
+
|
|
|
+ if (res.status === 200) {
|
|
|
+ // 将base64转换为Blob
|
|
|
+ const byteCharacters = atob(res.data.data.file_content);
|
|
|
+ const byteNumbers = new Array(byteCharacters.length);
|
|
|
+ for (let i = 0; i < byteCharacters.length; i++) {
|
|
|
+ byteNumbers[i] = byteCharacters.charCodeAt(i);
|
|
|
+ }
|
|
|
+ const byteArray = new Uint8Array(byteNumbers);
|
|
|
+ const blob = new Blob([byteArray], {
|
|
|
+ type: "application/vnd.openxmlformats-officedocument.wordprocessingml.document",
|
|
|
+ });
|
|
|
+
|
|
|
+ // 创建下载链接
|
|
|
+ const link = document.createElement("a");
|
|
|
+ link.href = URL.createObjectURL(blob);
|
|
|
+ link.download = "converted.docx"; // 或使用服务器返回的文件名
|
|
|
+ document.body.appendChild(link);
|
|
|
+ link.click();
|
|
|
+ document.body.removeChild(link);
|
|
|
+
|
|
|
+ // 清理URL对象
|
|
|
+ URL.revokeObjectURL(link.href);
|
|
|
+
|
|
|
+ this.$message.success("转换成功");
|
|
|
+ } else {
|
|
|
+ throw new Error(res.data.message || "转换失败");
|
|
|
+ }
|
|
|
+ } catch (error) {
|
|
|
+ console.error("PDF转Word失败:", error);
|
|
|
+ this.$message.error("PDF转Word失败,请稍后重试");
|
|
|
+ }
|
|
|
+ },
|
|
|
+
|
|
|
// 修改后的导出文档方法
|
|
|
async exportDocument(template) {
|
|
|
try {
|
|
@@ -357,64 +424,168 @@ export default {
|
|
|
templateData.forEach((item) => {
|
|
|
const templateSection = document.createElement("div");
|
|
|
templateSection.className = "template-textarea";
|
|
|
- templateSection.innerHTML = item.content;
|
|
|
- contentContainer.appendChild(templateSection);
|
|
|
- });
|
|
|
|
|
|
- // 处理所有输入框
|
|
|
- contentContainer
|
|
|
- .querySelectorAll('input[type="text"]')
|
|
|
- .forEach((input) => {
|
|
|
- const span = document.createElement("span");
|
|
|
- span.textContent = input.value;
|
|
|
- input.parentNode.replaceChild(span, input);
|
|
|
+ // 创建临时div来解析HTML
|
|
|
+ const tempDiv = document.createElement("div");
|
|
|
+ tempDiv.innerHTML = item.content;
|
|
|
+
|
|
|
+ // 处理标题格式
|
|
|
+ tempDiv
|
|
|
+ .querySelectorAll("h1, h2, h3, h4, h5, h6")
|
|
|
+ .forEach((heading) => {
|
|
|
+ heading.style.fontWeight = "bold";
|
|
|
+ heading.style.margin = "1em 0";
|
|
|
+
|
|
|
+ switch (heading.tagName.toLowerCase()) {
|
|
|
+ case "h1":
|
|
|
+ heading.style.fontSize = "24pt";
|
|
|
+ break;
|
|
|
+ case "h2":
|
|
|
+ heading.style.fontSize = "18pt";
|
|
|
+ break;
|
|
|
+ case "h3":
|
|
|
+ heading.style.fontSize = "14pt";
|
|
|
+ break;
|
|
|
+ case "h4":
|
|
|
+ case "h5":
|
|
|
+ case "h6":
|
|
|
+ heading.style.fontSize = "12pt";
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ });
|
|
|
+
|
|
|
+ // 处理表格
|
|
|
+ tempDiv.querySelectorAll("table").forEach((table) => {
|
|
|
+ // 设置表格属性
|
|
|
+ table.setAttribute("border", "1");
|
|
|
+ table.setAttribute("cellspacing", "0");
|
|
|
+ table.setAttribute("cellpadding", "5");
|
|
|
+ table.style.borderCollapse = "collapse";
|
|
|
+ table.style.width = "100%";
|
|
|
+ table.style.border = "1px solid black";
|
|
|
+
|
|
|
+ // 处理所有单元格
|
|
|
+ const cells = table.querySelectorAll("td, th");
|
|
|
+ cells.forEach((cell) => {
|
|
|
+ cell.style.border = "1px solid black";
|
|
|
+ cell.style.padding = "5px";
|
|
|
+ if (cell.tagName === "TH") {
|
|
|
+ cell.style.backgroundColor = "#f0f0f0";
|
|
|
+ cell.style.fontWeight = "bold";
|
|
|
+ }
|
|
|
+ });
|
|
|
});
|
|
|
|
|
|
+ templateSection.innerHTML = tempDiv.innerHTML;
|
|
|
+ contentContainer.appendChild(templateSection);
|
|
|
+ });
|
|
|
+
|
|
|
// 构建HTML内容
|
|
|
- let contentData = `<!DOCTYPE html>
|
|
|
- <html>
|
|
|
- <head>
|
|
|
- <meta charset="UTF-8">
|
|
|
- <style>
|
|
|
- @page {
|
|
|
- size: A4;
|
|
|
- margin: 2cm;
|
|
|
- }
|
|
|
- body {
|
|
|
- font-family: Arial, sans-serif;
|
|
|
- font-size: 12pt;
|
|
|
- line-height: 1.5;
|
|
|
- }
|
|
|
- table {
|
|
|
- width: 100%;
|
|
|
- border-collapse: collapse;
|
|
|
- }
|
|
|
- td, th {
|
|
|
- border: 1px solid black;
|
|
|
- padding: 5px;
|
|
|
- }
|
|
|
- .template-textarea {
|
|
|
- page-break-after: always;
|
|
|
- }
|
|
|
- .TOC {
|
|
|
- display: none !important;
|
|
|
- }
|
|
|
- </style>
|
|
|
- </head>
|
|
|
- <body>
|
|
|
- ${contentContainer.innerHTML}
|
|
|
- </body>
|
|
|
+ let contentData = `
|
|
|
+ <!DOCTYPE html>
|
|
|
+ <html xmlns:o='urn:schemas-microsoft-com:office:office'
|
|
|
+ xmlns:w='urn:schemas-microsoft-com:office:word'
|
|
|
+ xmlns='http://www.w3.org/TR/REC-html40'>
|
|
|
+ <head>
|
|
|
+ <meta charset="UTF-8">
|
|
|
+ <title>${template.title}</title>
|
|
|
+ <xml>
|
|
|
+ <w:WordDocument>
|
|
|
+ <w:View>Print</w:View>
|
|
|
+ <w:Zoom>100</w:Zoom>
|
|
|
+ <w:DoNotOptimizeForBrowser/>
|
|
|
+ </w:WordDocument>
|
|
|
+ </xml>
|
|
|
+ <style>
|
|
|
+ /* 重置样式 */
|
|
|
+ * {
|
|
|
+ margin: 0;
|
|
|
+ padding: 0;
|
|
|
+ box-sizing: border-box;
|
|
|
+ }
|
|
|
+
|
|
|
+ /* 页面设置 */
|
|
|
+ @page {
|
|
|
+ size: A4;
|
|
|
+ margin: 2cm;
|
|
|
+ }
|
|
|
+
|
|
|
+ /* 基本样式 */
|
|
|
+ body {
|
|
|
+ font-family: "Times New Roman", SimSun, serif;
|
|
|
+ font-size: 12pt;
|
|
|
+ line-height: 1.5;
|
|
|
+ }
|
|
|
+
|
|
|
+ /* 标题样式 */
|
|
|
+ h1 { font-size: 24pt; margin: 1em 0; }
|
|
|
+ h2 { font-size: 18pt; margin: 1em 0; }
|
|
|
+ h3 { font-size: 14pt; margin: 1em 0; }
|
|
|
+ h4, h5, h6 { font-size: 12pt; margin: 1em 0; }
|
|
|
+
|
|
|
+ /* 表格样式 */
|
|
|
+ table {
|
|
|
+ width: 100%;
|
|
|
+ border-collapse: collapse;
|
|
|
+ border: 1px solid black;
|
|
|
+ margin: 1em 0;
|
|
|
+ mso-table-lspace: 0pt;
|
|
|
+ mso-table-rspace: 0pt;
|
|
|
+ mso-border-alt: solid windowtext .5pt;
|
|
|
+ }
|
|
|
+
|
|
|
+ td, th {
|
|
|
+ border: 1px solid black;
|
|
|
+ padding: 5px;
|
|
|
+ mso-border-alt: solid windowtext .5pt;
|
|
|
+ }
|
|
|
+
|
|
|
+ th {
|
|
|
+ background-color: #f0f0f0;
|
|
|
+ font-weight: bold;
|
|
|
+ }
|
|
|
+
|
|
|
+ /* Word特定样式 */
|
|
|
+ .MsoNormal {
|
|
|
+ margin-bottom: .0001pt;
|
|
|
+ text-align: justify;
|
|
|
+ text-justify: inter-ideograph;
|
|
|
+ }
|
|
|
+
|
|
|
+ /* 分页控制 */
|
|
|
+ .template-textarea {
|
|
|
+ page-break-after: always;
|
|
|
+ }
|
|
|
+
|
|
|
+ /* 隐藏目录 */
|
|
|
+ .TOC {
|
|
|
+ display: none !important;
|
|
|
+ }
|
|
|
+ </style>
|
|
|
+ <!--[if gte mso 9]>
|
|
|
+ <xml>
|
|
|
+ <w:WordDocument>
|
|
|
+ <w:View>Print</w:View>
|
|
|
+ <w:Zoom>100</w:Zoom>
|
|
|
+ <w:DoNotOptimizeForBrowser/>
|
|
|
+ </w:WordDocument>
|
|
|
+ </xml>
|
|
|
+ <![endif]-->
|
|
|
+ </head>
|
|
|
+ <body>
|
|
|
+ ${contentContainer.innerHTML}
|
|
|
+ </body>
|
|
|
</html>`;
|
|
|
|
|
|
- /* // 处理表格样式
|
|
|
- contentData = contentData
|
|
|
- .replaceAll("<table ", `<table style="border-collapse: collapse;" `)
|
|
|
- .replaceAll("<td>", `<td style="border: 1px solid black;">`); */
|
|
|
-
|
|
|
// 调用导出接口
|
|
|
const res = await exportDocument({
|
|
|
content: contentData,
|
|
|
title: template.title,
|
|
|
+ options: {
|
|
|
+ format: "docx",
|
|
|
+ encoding: "utf-8",
|
|
|
+ preserveStyles: true,
|
|
|
+ },
|
|
|
});
|
|
|
|
|
|
if (res.status !== 200) {
|
|
@@ -425,7 +596,7 @@ export default {
|
|
|
// 处理文件下载
|
|
|
const link = document.createElement("a");
|
|
|
link.href = res.data.file_path;
|
|
|
- link.download = res.data.file_name;
|
|
|
+ link.download = `${template.title}.docx`;
|
|
|
document.body.appendChild(link);
|
|
|
link.click();
|
|
|
document.body.removeChild(link);
|
|
@@ -1025,7 +1196,8 @@ export default {
|
|
|
selTemplate(row) {
|
|
|
this.currentData = row;
|
|
|
this.selectedTemplates = []; // 重置选择
|
|
|
- this.templateQueryForm.page = 1; // 重置页码
|
|
|
+ this.selectedTemplateIds = new Set(row.documentIds || []); // 初始化已绑定的模版ID
|
|
|
+ this.templateQueryForm.page = 1; // 重置���码
|
|
|
this.loadTemplateList();
|
|
|
},
|
|
|
// 处理模版分页变化
|
|
@@ -1058,10 +1230,12 @@ export default {
|
|
|
const currentPageSelected = this.selectedPageIds.get(currentPage);
|
|
|
|
|
|
this.templateList.forEach((row) => {
|
|
|
- const shouldSelect =
|
|
|
- this.isAllSelected ||
|
|
|
+ const shouldSelect =
|
|
|
+ this.isAllSelected ||
|
|
|
(currentPageSelected && currentPageSelected.has(row.id)) ||
|
|
|
- this.selectedTemplateIds.has(row.id);
|
|
|
+ this.selectedTemplateIds.has(row.id) ||
|
|
|
+ (this.currentData.documentIds &&
|
|
|
+ this.currentData.documentIds.includes(row.id));
|
|
|
|
|
|
if (shouldSelect) {
|
|
|
this.$refs.templateTable.toggleRowSelection(row, true);
|
|
@@ -1089,8 +1263,8 @@ export default {
|
|
|
// 如果之前是全选状态,现在取消了某些选择
|
|
|
if (this.isAllSelected && selection.length < this.templateList.length) {
|
|
|
this.isAllSelected = false;
|
|
|
- // 保留其他页面的选择,仅更新当前页
|
|
|
- const allSelectedIds = new Set();
|
|
|
+ // 保留其他页面的选择和已绑定的模版
|
|
|
+ const allSelectedIds = new Set(this.currentData.documentIds || []);
|
|
|
this.selectedPageIds.forEach((pageIds, page) => {
|
|
|
if (page !== currentPage) {
|
|
|
pageIds.forEach((id) => allSelectedIds.add(id));
|
|
@@ -1100,11 +1274,13 @@ export default {
|
|
|
currentPageIds.forEach((id) => allSelectedIds.add(id));
|
|
|
this.selectedTemplateIds = allSelectedIds;
|
|
|
} else {
|
|
|
- // 正常选择模式,直接更新选中状态
|
|
|
+ // 正常选择模式,保留已绑定的模版
|
|
|
+ const existingIds = new Set(this.currentData.documentIds || []);
|
|
|
this.templateList.forEach((item) => {
|
|
|
if (currentPageIds.includes(item.id)) {
|
|
|
this.selectedTemplateIds.add(item.id);
|
|
|
- } else {
|
|
|
+ } else if (!existingIds.has(item.id)) {
|
|
|
+ // 只删除非已绑定的模版
|
|
|
this.selectedTemplateIds.delete(item.id);
|
|
|
}
|
|
|
});
|
|
@@ -1116,22 +1292,24 @@ export default {
|
|
|
const currentPage = this.templateQueryForm.page;
|
|
|
|
|
|
if (selection.length > 0) {
|
|
|
- this.$confirm('是否选择所有页的模版?', '提示', {
|
|
|
- confirmButtonText: '全部选择',
|
|
|
- cancelButtonText: '仅选择当前页',
|
|
|
- type: 'info'
|
|
|
- }).then(() => {
|
|
|
- // 选择所有页
|
|
|
- this.selectAllPages();
|
|
|
- }).catch(() => {
|
|
|
- // 仅选择当前页
|
|
|
- this.selectCurrentPage(selection);
|
|
|
- // 更新当前页的选择记录
|
|
|
- this.selectedPageIds.set(
|
|
|
- currentPage,
|
|
|
- new Set(selection.map((item) => item.id))
|
|
|
- );
|
|
|
- });
|
|
|
+ this.$confirm("是否选择所有页的模版?", "提示", {
|
|
|
+ confirmButtonText: "全部选择",
|
|
|
+ cancelButtonText: "仅选择当前页",
|
|
|
+ type: "info",
|
|
|
+ })
|
|
|
+ .then(() => {
|
|
|
+ // 选择所有页
|
|
|
+ this.selectAllPages();
|
|
|
+ })
|
|
|
+ .catch(() => {
|
|
|
+ // 仅选择当前页
|
|
|
+ this.selectCurrentPage(selection);
|
|
|
+ // 更新当前页的选择记录
|
|
|
+ this.selectedPageIds.set(
|
|
|
+ currentPage,
|
|
|
+ new Set(selection.map((item) => item.id))
|
|
|
+ );
|
|
|
+ });
|
|
|
} else {
|
|
|
// 取消全选
|
|
|
this.isAllSelected = false;
|
|
@@ -1160,8 +1338,8 @@ export default {
|
|
|
|
|
|
this.$message.success(`已选择全部 ${this.templateTotal} 条数据`);
|
|
|
} catch (error) {
|
|
|
- console.error('获取所有模版失败:', error);
|
|
|
- this.$message.error('获取所有模版失败');
|
|
|
+ console.error("获取所有模版失败:", error);
|
|
|
+ this.$message.error("获取所有模版失败");
|
|
|
}
|
|
|
},
|
|
|
|
|
@@ -1182,7 +1360,7 @@ export default {
|
|
|
const params = {
|
|
|
...this.templateQueryForm,
|
|
|
page: 1,
|
|
|
- pageSize
|
|
|
+ pageSize,
|
|
|
};
|
|
|
|
|
|
try {
|
|
@@ -1192,7 +1370,7 @@ export default {
|
|
|
}
|
|
|
return [];
|
|
|
} catch (error) {
|
|
|
- console.error('获取所有模版失败:', error);
|
|
|
+ console.error("获取所有模版失败:", error);
|
|
|
return [];
|
|
|
}
|
|
|
},
|
|
@@ -1200,16 +1378,20 @@ export default {
|
|
|
// 确认选择
|
|
|
confirmTemplateSelection() {
|
|
|
if (this.selectedTemplateIds.size === 0) {
|
|
|
- this.$message.warning('请至少选择一个模版');
|
|
|
+ this.$message.warning("请至少选择一个模版");
|
|
|
return;
|
|
|
}
|
|
|
-
|
|
|
+ // 合并已有的文档ID和新选择的ID
|
|
|
+ const allDocIds = new Set([
|
|
|
+ ...(this.currentData.documentIds || []),
|
|
|
+ ...this.selectedTemplateIds,
|
|
|
+ ]);
|
|
|
relate({
|
|
|
project_id: this.currentData.id,
|
|
|
- doc_ids: JSON.stringify([...this.selectedTemplateIds])
|
|
|
+ doc_ids: JSON.stringify([...allDocIds]),
|
|
|
}).then((res) => {
|
|
|
if (res.status !== 200) return;
|
|
|
- this.$message.success('模版关联成功');
|
|
|
+ this.$message.success("模版关联成功");
|
|
|
this.closeTemplateDialog();
|
|
|
this.search();
|
|
|
});
|
|
@@ -1441,7 +1623,7 @@ export default {
|
|
|
this.pageTotal = res.data.totalPage;
|
|
|
} catch (err) {
|
|
|
console.error("搜索失败:", err);
|
|
|
- this.$message.error("获取项目列表失��");
|
|
|
+ this.$message.error("获取项目列表失");
|
|
|
}
|
|
|
},
|
|
|
//修改分页
|
|
@@ -1473,17 +1655,108 @@ export default {
|
|
|
});
|
|
|
},
|
|
|
// 新增:处理导出命令
|
|
|
- handleExport(command, row) {
|
|
|
+ async handleExport(command, row) {
|
|
|
switch (command) {
|
|
|
- case 'word':
|
|
|
- this.exportDocument(row);
|
|
|
+ case "word":
|
|
|
+ await this.exportDocument(row);
|
|
|
break;
|
|
|
- case 'pdf':
|
|
|
- this.exportToPDF(row);
|
|
|
+ case "pdf":
|
|
|
+ await this.exportToPDF(row);
|
|
|
+ break;
|
|
|
+ case "pdf-to-word": // 添加新的命令类型
|
|
|
+ const pdfResult = await this.exportToPDF_url(row);
|
|
|
+ if (pdfResult && pdfResult.file_path) {
|
|
|
+ await this.convertPDFToWord(pdfResult.file_path);
|
|
|
+ }
|
|
|
break;
|
|
|
}
|
|
|
},
|
|
|
+ /* 过去pdf链接 */
|
|
|
+ async exportToPDF_url(template) {
|
|
|
+ try {
|
|
|
+ // 解析模版内容
|
|
|
+ const templateData = JSON.parse(template.data || "[]");
|
|
|
+
|
|
|
+ // 创建一个临时的容器来存放内容
|
|
|
+ const contentContainer = document.createElement("div");
|
|
|
+ contentContainer.className = "content";
|
|
|
+
|
|
|
+ // 处理每个模版段落
|
|
|
+ templateData.forEach((item) => {
|
|
|
+ const templateSection = document.createElement("div");
|
|
|
+ templateSection.className = "template-textarea";
|
|
|
+ templateSection.innerHTML = item.content;
|
|
|
+ contentContainer.appendChild(templateSection);
|
|
|
+ });
|
|
|
+
|
|
|
+ // 处理所有输入框
|
|
|
+ contentContainer
|
|
|
+ .querySelectorAll('input[type="text"]')
|
|
|
+ .forEach((input) => {
|
|
|
+ const span = document.createElement("span");
|
|
|
+ span.textContent = input.value;
|
|
|
+ input.parentNode.replaceChild(span, input);
|
|
|
+ });
|
|
|
+
|
|
|
+ // 构建HTML内容
|
|
|
+ let contentData = `<!DOCTYPE html>
|
|
|
+ <html>
|
|
|
+ <head>
|
|
|
+ <meta charset="UTF-8">
|
|
|
+ <style>
|
|
|
+ @page {
|
|
|
+ size: A4;
|
|
|
+ margin: 2cm;
|
|
|
+ }
|
|
|
+ body {
|
|
|
+ font-family: Arial, sans-serif;
|
|
|
+ font-size: 12pt;
|
|
|
+ line-height: 1.5;
|
|
|
+ }
|
|
|
+ table {
|
|
|
+ width: 100%;
|
|
|
+ border-collapse: collapse;
|
|
|
+ }
|
|
|
+ td, th {
|
|
|
+ border: 1px solid black;
|
|
|
+ padding: 5px;
|
|
|
+ }
|
|
|
+ .template-textarea {
|
|
|
+ page-break-after: always;
|
|
|
+ }
|
|
|
+ .TOC {
|
|
|
+ display: none !important;
|
|
|
+ }
|
|
|
+ </style>
|
|
|
+ </head>
|
|
|
+ <body>
|
|
|
+ ${contentContainer.innerHTML}
|
|
|
+ </body>
|
|
|
+ </html>`;
|
|
|
+
|
|
|
+ /* // 处理表格样式
|
|
|
+ contentData = contentData
|
|
|
+ .replaceAll("<table ", `<table style="border-collapse: collapse;" `)
|
|
|
+ .replaceAll("<td>", `<td style="border: 1px solid black;">`); */
|
|
|
|
|
|
+ // 调用导出接口,指定导出类型为 PDF
|
|
|
+ const res = await exportToPDF({
|
|
|
+ content: contentData,
|
|
|
+ title: template.title,
|
|
|
+ });
|
|
|
+
|
|
|
+ if (res.status !== 200) {
|
|
|
+ this.$alert(res.errMsg);
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ // 处理文件下载
|
|
|
+ return res.data; // 返回结果,包含 file_path
|
|
|
+ } catch (error) {
|
|
|
+ console.error("导出PDF失败:", error);
|
|
|
+ this.$alert("导出PDF时发生错误,请稍后重试。");
|
|
|
+ }
|
|
|
+ },
|
|
|
// 添加新的 exportToPDF 方法
|
|
|
async exportToPDF(template) {
|
|
|
try {
|
|
@@ -1503,11 +1776,13 @@ export default {
|
|
|
});
|
|
|
|
|
|
// 处理所有输入框
|
|
|
- contentContainer.querySelectorAll('input[type="text"]').forEach((input) => {
|
|
|
- const span = document.createElement("span");
|
|
|
- span.textContent = input.value;
|
|
|
- input.parentNode.replaceChild(span, input);
|
|
|
- });
|
|
|
+ contentContainer
|
|
|
+ .querySelectorAll('input[type="text"]')
|
|
|
+ .forEach((input) => {
|
|
|
+ const span = document.createElement("span");
|
|
|
+ span.textContent = input.value;
|
|
|
+ input.parentNode.replaceChild(span, input);
|
|
|
+ });
|
|
|
|
|
|
// 构建HTML内容
|
|
|
let contentData = `<!DOCTYPE html>
|
|
@@ -1545,7 +1820,7 @@ export default {
|
|
|
</body>
|
|
|
</html>`;
|
|
|
|
|
|
- /* // 处理表格样式
|
|
|
+ /* // 处理表格样式
|
|
|
contentData = contentData
|
|
|
.replaceAll("<table ", `<table style="border-collapse: collapse;" `)
|
|
|
.replaceAll("<td>", `<td style="border: 1px solid black;">`); */
|
|
@@ -1570,6 +1845,7 @@ export default {
|
|
|
document.body.removeChild(link);
|
|
|
|
|
|
this.$message.success("导出成功");
|
|
|
+ return res.data; // 返回结果,包含 file_path
|
|
|
} catch (error) {
|
|
|
console.error("导出PDF失败:", error);
|
|
|
this.$alert("导出PDF时发生错误,请稍后重试。");
|
|
@@ -1621,15 +1897,16 @@ export default {
|
|
|
// 添加PDF导出相关样式
|
|
|
.content {
|
|
|
background: white;
|
|
|
-
|
|
|
+
|
|
|
.template-textarea {
|
|
|
page-break-after: always;
|
|
|
-
|
|
|
+
|
|
|
table {
|
|
|
width: 100%;
|
|
|
border-collapse: collapse;
|
|
|
-
|
|
|
- td, th {
|
|
|
+
|
|
|
+ td,
|
|
|
+ th {
|
|
|
border: 1px solid black;
|
|
|
padding: 5px;
|
|
|
}
|