feat(property-marketing): 新增PDF导出功能并优化投放指南页面交互
This commit is contained in:
@ -10,7 +10,7 @@
|
||||
>
|
||||
<a-tab-pane key="placement_guide" title="投放指南"></a-tab-pane>
|
||||
<a-tab-pane key="guide_history">
|
||||
<template #title>历史投放指南</template>
|
||||
<template #title>历史指南列表</template>
|
||||
</a-tab-pane>
|
||||
</a-tabs>
|
||||
</div>
|
||||
@ -30,7 +30,7 @@
|
||||
@updateQuery="handleUpdateQuery"
|
||||
/>
|
||||
|
||||
<div v-if="listData.total > 0" class="pagination-box flex justify-end">
|
||||
<div v-if="listData.total > 0" class="pagination-box flex justify-end ignore-export">
|
||||
<a-pagination
|
||||
:total="listData.total"
|
||||
size="mini"
|
||||
@ -60,7 +60,7 @@
|
||||
</a-spin>
|
||||
<div v-if="tabData == 'placement_guide'" class="ignore-export">
|
||||
<a-space class="down-btn">
|
||||
<a-button type="outline" @click="downPage">
|
||||
<a-button type="outline" :loading="exportLoading" @click="downPage">
|
||||
<template #icon>
|
||||
<icon-download />
|
||||
</template>
|
||||
@ -84,7 +84,6 @@ import listSearchForm from './components/table-data/listSearchForm.vue';
|
||||
import GuideListHistory from './components/table-data/guideListHistory.vue';
|
||||
import MonthData from './components/month-data/index.vue';
|
||||
import PlacementSuggestions from './components/placement-suggestions/index.vue';
|
||||
import ActionGuideDistribution from './components/action-guide-distribution';
|
||||
import {
|
||||
getAiResult,
|
||||
getPlacementGuide,
|
||||
@ -92,11 +91,8 @@ import {
|
||||
savePlacementGuide,
|
||||
} from '@/api/all/propertyMarketing';
|
||||
import { Message } from '@arco-design/web-vue';
|
||||
import html2canvas from 'html2canvas';
|
||||
import { jsPDF } from 'jspdf';
|
||||
import { AiResultStatus } from '@/views/property-marketing/put-account/investment-guidelines/constants';
|
||||
import { fetchUploadFile } from '@/api/all';
|
||||
import axios from 'axios';
|
||||
import { uploadPdf } from '@/views/property-marketing/put-account/investment-guidelines/constants';
|
||||
|
||||
const tabData = ref('placement_guide');
|
||||
|
||||
@ -133,7 +129,7 @@ const handleUpdateQuery = (payload) => {
|
||||
};
|
||||
|
||||
const loading = ref(false);
|
||||
|
||||
const exportLoading = ref(false);
|
||||
const listData = reactive({
|
||||
total: 0,
|
||||
list: [],
|
||||
@ -166,15 +162,27 @@ const aiResult = reactive({
|
||||
|
||||
// 下载当前页面
|
||||
const downPage = async () => {
|
||||
await nextTick();
|
||||
const fileUrl = await uploadPdf();
|
||||
const link = document.createElement('a');
|
||||
link.href = fileUrl;
|
||||
link.download = '投放指南.pdf';
|
||||
document.body.appendChild(link);
|
||||
link.click();
|
||||
document.body.removeChild(link);
|
||||
try {
|
||||
let fileUrl = saveForm.file_url;
|
||||
exportLoading.value = true;
|
||||
if (saveForm.file_url === '') {
|
||||
fileUrl = await uploadPdf('投放指南.pdf', '.guidelines-data-wrap');
|
||||
saveForm.file_url = fileUrl;
|
||||
}
|
||||
console.log(fileUrl, 'fileUrl');
|
||||
const link = document.createElement('a');
|
||||
link.href = fileUrl;
|
||||
link.download = '投放指南.pdf';
|
||||
document.body.appendChild(link);
|
||||
link.click();
|
||||
document.body.removeChild(link);
|
||||
exportLoading.value = false;
|
||||
} catch (error) {
|
||||
Message.error(error.message);
|
||||
exportLoading.value = false;
|
||||
}
|
||||
};
|
||||
|
||||
const saveForm = reactive({
|
||||
account: [],
|
||||
plan: [],
|
||||
@ -258,51 +266,6 @@ const handleSave = async () => {
|
||||
}
|
||||
};
|
||||
|
||||
// 上传pdf文件
|
||||
const uploadPdf = async () => {
|
||||
if (saveForm.file_url !== '') {
|
||||
return saveForm.file_url;
|
||||
}
|
||||
const response = await fetchUploadFile({ suffix: 'pdf' });
|
||||
const preSignedUrl = response?.data?.upload_url;
|
||||
const fileUrl = response?.data?.file_url;
|
||||
if (!preSignedUrl) {
|
||||
throw new Error('未能获取有效的预签名上传地址');
|
||||
}
|
||||
saveForm.file_url = fileUrl;
|
||||
const pdfBlob = await generatePDF(); // 生成 PDF Blob
|
||||
console.log('pdfBlob', pdfBlob);
|
||||
await axios.put(preSignedUrl, pdfBlob, {
|
||||
headers: {
|
||||
'Content-Type': pdfBlob.type,
|
||||
},
|
||||
});
|
||||
return fileUrl;
|
||||
};
|
||||
|
||||
const generatePDF = async (): Promise<Blob> => {
|
||||
await nextTick();
|
||||
const sections = document.querySelectorAll('.guidelines-data-wrap');
|
||||
const pdf = new jsPDF('p', 'mm', 'a4');
|
||||
let position = 0;
|
||||
for (const section of sections) {
|
||||
if (section.children.length === 0) continue; // 跳过空内容区域
|
||||
const canvas = await html2canvas(section as HTMLElement, {
|
||||
ignoreElements: (element) => {
|
||||
return element.classList.contains('ignore-export'); // 例如:忽略 class 为 ignore-export 的元素
|
||||
},
|
||||
});
|
||||
const imgData = canvas.toDataURL('image/png');
|
||||
const imgProps = pdf.getImageProperties(imgData);
|
||||
const pdfWidth = pdf.internal.pageSize.getWidth();
|
||||
const pdfHeight = (imgProps.height * pdfWidth) / imgProps.width;
|
||||
pdf.addImage(imgData, 'PNG', 0, position, pdfWidth, pdfHeight);
|
||||
position += pdfHeight + 10;
|
||||
}
|
||||
|
||||
return pdf.output('blob');
|
||||
};
|
||||
|
||||
onMounted(() => {
|
||||
onSearch();
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user