Browse Source

feat: 招商门户页面开发

周玉环 1 day ago
parent
commit
cb8392b01e

+ 3 - 7
xinkeaboard-promotion-portal/src/components/keyword/search.vue

@@ -2,8 +2,8 @@
   <div class="keyword-search">
     <div class="keyword-search-title">{{ year }}年{{ month }}月核心关键词搜索量</div>
     <div class="keyword-search-value">
-      <span v-if="loading">数据加载中...</span>
-      <span v-else>{{ searchVolume }}</span>
+      <span v-show="loading">数据加载中...</span>
+      <span v-show="!loading">{{ searchVolume }}</span>
     </div>
     <div class="keyword-search-line"></div>
     <div class="keyword-search-tip">
@@ -62,11 +62,7 @@ const searchVolume = computed(() => {
     width: 546px;
     height: 1px;
     margin: 36px 0;
-    background: linear-gradient(
-      90deg,
-      var(--promotion--color-primary) 0%,
-      rgba(3, 110, 184, 0) 100%
-    );
+    background: #036eb8;
   }
 
   &-tip {

+ 4 - 4
xinkeaboard-promotion-portal/src/utils/http.ts

@@ -33,10 +33,10 @@ http.interceptors.response.use(
     const res = response.data;
     // 你可以根据后端约定的 code 来处理
     if (res.state !== 200) {
-      showMessage({
-        type: 'error',
-        message: response.msg || '请求失败'
-      });
+      // showMessage({
+      //   type: 'error',
+      //   message: response.msg || '请求失败'
+      // });
     }
     return response.data; // 正常返回数据
   },

+ 28 - 15
xinkeaboard-promotion-portal/src/utils/pdf.ts

@@ -1,25 +1,39 @@
-import { ref, nextTick, computed } from 'vue';
+import { nextTick, computed } from 'vue';
 import { useMainStore } from '@/store';
 import html2canvas from 'html2canvas';
 import jsPDF from 'jspdf';
+import { showMessage } from './common';
 
 const mainStore = useMainStore();
 
 const expanded = computed(() => mainStore.getExpanded);
 
-export const downloadPDF = async (pdfContent: HTMLElement) => {
-//   if (!expanded.value) {
-//     expanded.value = true;
-//     await nextTick();
-//   }
-//   showWatermark.value = true;
+export const downloadPDF = async (pdfContent: HTMLElement, callback: () => void) => {
+  if (!expanded.value) {
+    mainStore.setExpanded(true);
+    await nextTick();
+  }
   await nextTick();
-  const canvas = await html2canvas(pdfContent, {
-    scale: 1,
-    useCORS: true,
-    backgroundColor: '#fff' // 防止透明背景
-  });
+  let canvas = null;
+  try {
+    canvas = await html2canvas(pdfContent, {
+      scale: 2,
+      useCORS: true,
+      backgroundColor: '#fff' // 防止透明背景
+    });
+  } catch (error) {
+    callback && callback();
+    mainStore.setExpanded(false);
+    showMessage({
+      type: 'error',
+      message: '下载失败,请稍后再试'
+    });
+    console.error('html2canvas error:', error);
+    return;
+  }
+
   const imgData = canvas.toDataURL('image/png', 0.7);
+
   const pdf = new jsPDF('p', 'mm', 'a4');
   // const pdf = new jsPDF("landscape", "mm", "a4"); // 横向 A4
   // pdf.setFontSize(100); // 设置当前字体大小为 12(单位:pt)
@@ -31,8 +45,7 @@ export const downloadPDF = async (pdfContent: HTMLElement) => {
   const x = (pageWidth - imgWidth) / 2;
   const y = (pageHeight - imgHeight) / 2;
   pdf.addImage(imgData, 'JPEG', x, y, imgWidth, imgHeight);
-//   showWatermark.value = false;
-//   expanded.value = false;
-
+  mainStore.setExpanded(false);
   pdf.save('charts-and-table.pdf');
+  callback && callback();
 };

+ 1 - 1
xinkeaboard-promotion-portal/src/views/Home.vue

@@ -43,7 +43,7 @@ onUnmounted(() => {});
 
 <style lang="scss" scoped>
 .promotion-portal {
-  width: 1920px;
+  max-width: 1920px;
   height: 100%;
   overflow: auto;
 

+ 14 - 8
xinkeaboard-promotion-portal/src/views/Record.vue

@@ -11,9 +11,7 @@
         </div>
         <div class="overview-left">概述</div>
         <div class="overview-right">
-          <el-button v-loading.fullscreen.lock="fullscreenLoading" @click="download"
-            >下载报告</el-button
-          >
+          <el-button v-show="!expanded" @click="download">下载报告</el-button>
         </div>
         <div class="record-wrap-content__keyword">
           <img :src="keywordPng" />
@@ -49,6 +47,8 @@
 
 <script lang="ts" setup>
 import { ref, computed } from 'vue';
+import { ElLoading } from 'element-plus';
+
 import { useMainStore } from '../store';
 import KeywordSearch from '../components/keyword/search.vue';
 import KeywordTable from '../components/keyword/table.vue';
@@ -58,28 +58,34 @@ import keywordPng from '../assets/images/keyword.png';
 import CompetitorPng from '../assets/images/competitor.png';
 import AiAnalysisPng from '../assets/images/ai-analysis.png';
 import { downloadPDF } from '@/utils/pdf';
+import { showMessage } from '@/utils/common';
 
 const mainStore = useMainStore();
 mainStore.initData();
 
-const fullscreenLoading = ref<boolean>(false);
 const pdfContent = ref<HTMLElement | null>(null);
 const keywordData = computed(() => mainStore.getKeywordInfo);
 const loading = computed(() => keywordData.value.loading);
 const keywordEn = computed(() => keywordData.value.data?.keywordEn);
 const keywords = computed(() => keywordData.value?.data?.keywords?.join(','));
+const expanded = computed(() => mainStore.getExpanded);
 
 const download = () => {
-  fullscreenLoading.value = true;
-  downloadPDF(pdfContent.value!);
-  fullscreenLoading.value = false;
+  const loading = ElLoading.service({
+    lock: true,
+    text: '下载中...',
+    background: 'rgba(0, 0, 0, 0.7)'
+  });
+  downloadPDF(pdfContent.value!, () => {
+    loading.close();
+  });
 };
 </script>
 
 <style lang="scss" scoped>
 .record {
   position: relative;
-  width: 1920px;
+  max-width: 1920px;
   height: 100%;
   // overflow: auto;
   background-color: #fff;