您的位置:首页 > 文旅 > 旅游 > wordpress官网模板_电商网站设计_公关公司提供的服务有哪些_seo经典案例分析

wordpress官网模板_电商网站设计_公关公司提供的服务有哪些_seo经典案例分析

2025/4/15 21:35:50 来源:https://blog.csdn.net/Mirs_Zhu/article/details/146071635  浏览:    关键词:wordpress官网模板_电商网站设计_公关公司提供的服务有哪些_seo经典案例分析
wordpress官网模板_电商网站设计_公关公司提供的服务有哪些_seo经典案例分析

一、第三方包下载

使用npm下载以下插件:

npm install jszip-utils docxtemplater pizzip file-saver docxtemplater-image-module-free

二、总页面组件代码

<template>

  <summaryDetails

    :securityId="securityId"

    :symbol="symbol"

    id="summaryDetails"

  />

</template>

<script setup lang="ts">

import summaryDetails from './summaryDetails.vue'

const props = defineProps({

  symbol: {

    // 证券代码

    type: String,

    default: '000001'

  },

  securityId: {

    // 证券id

    type: [String, Number],

    required: true

  }

})

</script>

<style scoped lang="less"></style>

三、summaryDetails组件代码

<template>

  <ItemCard title="综述" v-loading="loading">

    <template #rightPart>

      <el-date-picker

        v-model="dateRange"

        value-format="YYYY"

        type="yearrange"

        range-separator="至"

        start-placeholder="开始年份"

        end-placeholder="结束年份"

        :editable="false"

        :disabled-date="disabledDate"

        @change="changeDate"

        @clear="changeDate1"

        class="date-select"

        ref="datePicker"

      />

      <div class="upload-box" @click="exportDataList">

        <span class="icon iconfont icon-baogaodaochu"></span>

        <span class="upload-text">报告导出</span>

      </div>

    </template>

    <template #otherContent>

      <div class="item">

        <div class="title">简述</div>

        <div class="table-box">

          <AISketch :sketch-list="sketchList"></AISketch>

        </div>

      </div>

      <div class="item">

        <div class="title">综述详情</div>

        <div class="table-box">

          <div

            class="item-detail"

            v-for="(item, index) in summaryDetailsList"

            :key="index"

          >

            <div class="detail-title">

              {{ item.title }}

              <div class="line"></div>

            </div>

            <div class="all-detail" v-html="item.overview"></div>

            <div

              class="children-item"

              v-for="(item1, index1) in item.items"

              :key="index1"

            >

              <div class="children-title">

                <div class="dot"></div>

                {{ item1.title }}

              </div>

              <div class="children-detail" v-html="item1.desc"></div>

            </div>

          </div>

        </div>

      </div>

    </template>

  </ItemCard>

</template>

<script setup lang="ts">

import JSZipUtils from 'jszip-utils'

import docxtemplater from 'docxtemplater'

import PizZip from 'pizzip'

import saveAs from 'file-saver'

import ImageModule from 'docxtemplater-image-module-free'

import { ElMessage } from 'element-plus'

import ItemCard from './../RiskWarn/ItemCard.vue'

import AISketch from '@/pages/monitor/views/stockMonitor/components/AISummary/AISketch.vue'

import { queryAISummaryData } from '@/pages/monitor/monitorApi/stockMonitor'

const props = defineProps({

  symbol: {

    // 证券代码

    type: String,

    default: ''

  },

  securityId: {

    // 证券id

    type: [String, Number],

    required: true

  },

  sketchList: {

    type: Array as any,

    default: () => {}

  }

})

interface ImageOptions {

  centered: boolean

  getImage: (chartId: string) => ArrayBuffer | false

  getSize: () => [number, number]

}

const loading = ref(false) // 加载状态

const dateRange = ref<any>([]) // 年份范围

const securityId1 = ref(props.securityId) // 证券id

const symbol1 = ref(props.symbol) // 证券代码

const sketchList = ref<any>(props.sketchList) // 简述数据

const summaryDetailsList = ref<any>([]) // 综述详情数据

const cleanedData = ref<any>([]) // 综述详情数据

const datePicker = ref() // 时间筛选框ref

// 监听参数重新赋值

watch(

  () => [props.securityId, props.symbol, props.sketchList],

  (newValue: any, oldValue: any) => {

    if (newValue[0] != oldValue[0]) {

      securityId1.value = newValue[0]

      getAISummaryData() //查询接口

    }

    if (newValue[1] != oldValue[1]) {

      symbol1.value = newValue[1]

    }

    if (newValue[2] != oldValue[2]) {

      sketchList.value = newValue[2]

    }

    dateRange.value = []

  },

  { deep: true }

)

// 控制当前时间之后不能选

const disabledDate = (time: any) => {

  const year = time.getFullYear()

  return year < 2019 || year > new Date().getFullYear()

}

// 改变时间

const changeDate = (value: any) => {

  if (value) {

    dateRange.value = toRaw(value)

    getAISummaryData()

    datePicker.value.blur()

  }

}

// 清空时间

const changeDate1 = () => {

  dateRange.value = []

  getAISummaryData()

}

const base64DataURLToArrayBuffer = (dataURL: string) => {

  const base64Regex = /^data:image\/(png|jpg|svg|svg\+xml);base64,/

  if (!base64Regex.test(dataURL)) {

    return false

  }

  const stringBase64 = dataURL.replace(base64Regex, '')

  let binaryString

  if (typeof window !== 'undefined') {

    binaryString = window.atob(stringBase64)

  } else {

    binaryString = new Buffer(stringBase64, 'base64').toString('binary')

  }

  const len = binaryString.length

  const bytes = new Uint8Array(len)

  for (let i = 0; i < len; i++) {

    const ascii = binaryString.charCodeAt(i)

    bytes[i] = ascii

  }

  return bytes.buffer

}

const downLoadDoc = (demoUrl: string, docxData: any, fileName: string) => {

  // 读取并获得模板文件的二进制内容

  JSZipUtils.getBinaryContent(demoUrl, function (error: any, content: any) {

    // 抛出异常

    if (error) {

      throw error

    }

    let opts: ImageOptions = {

      centered: false,

      getImage: (chartId: string) => {

        return base64DataURLToArrayBuffer(chartId) || false

      },

      getSize: () => {

        return [230, 120]

      }

    }

    // 创建一个PizZip实例,内容为模板的内容

    let zip = new PizZip(content)

    // 创建并加载docxtemplater实例对象

    let doc = new docxtemplater()

      .loadZip(zip)

      .attachModule(new ImageModule(opts))

    // 去除未定义值所显示的undefined

    doc.setOptions({

      nullGetter: function () {

        return ''

      }

    })

    // 设置模板变量的值,对象的键需要和模板上的变量名一致,值就是你要放在模板上的值

    doc.setData({

      ...docxData

    })

    // eslint-disable-next-line no-useless-catch

    try {

      // 用模板变量的值替换所有模板变量

      doc.render()

    } catch (error) {

      // 抛出异常

      throw error

    }

    // 生成一个代表docxtemplater对象的zip文件(不是一个真实的文件,而是在内存中的表示)

    let out = doc.getZip().generate({

      type: 'blob',

      mimeType:

        'application/vnd.openxmlformats-officedocument.wordprocessingml.document'

    })

    // 将目标文件对象保存为目标类型的文件,并命名

    saveAs(out, fileName)

  })

}

// 导出

const exportDataList = async () => {

  loading.value = true

  let fileName = `${

    dateRange.value && dateRange.value.length > 0

      ? `${dateRange.value[0]}-${dateRange.value[1]}综述`

      : '今年以来综述'

  }`

  // 去掉 <span style="color: #ff0000"></span> 标签

  const cleanedItems = sketchList.value.map((item: any) => ({

    ...item,

    desc: item.desc.replace(/<span style="color: #ff0000">(.*?)<\/span>/g, '$1')

  }))

  // 去掉 <br/> 标签

  cleanedData.value = summaryDetailsList.value.map((item: any) => {

    // 解决更改对象导致原数组换行标签消失问题(重新复制一份对象进行删除标签)

    const newItem = JSON.parse(JSON.stringify(item))

    return removeBrTags(newItem)

  })

  // 下载word文档

  downLoadDoc(

    'public/ai-report.docx',

    { items: cleanedItems, infos: cleanedData.value },

    fileName

  )

  loading.value = false

}

// 去掉<br/>标签方法

const removeBrTags = (obj: any) => {

  if (typeof obj === 'string') {

    return obj.replace(/<br\/>/g, '') // 去掉 <br/> 标签

  } else if (typeof obj === 'object' && obj !== null) {

    for (const key in obj) {

      if (Object.prototype.hasOwnProperty.call(obj, key)) {

        obj[key] = removeBrTags(obj[key]) // 递归处理

      }

    }

  }

  return obj

}

// 查询数据

const getAISummaryData = () => {

  loading.value = true

  sketchList.value = []

  summaryDetailsList.value = []

  queryAISummaryData(

    dateRange.value[1],

    securityId1.value,

    dateRange.value[0],

    symbol1.value

  ).then((res: any) => {

    if (res.code === 200) {

      sketchList.value = res.data.items

      summaryDetailsList.value = res.data.data

    } else {

      ElMessage({

        type: 'error',

        message: res.message

      })

    }

    loading.value = false

  })

}

onMounted(() => {

  getAISummaryData()

})

</script>

<style scoped lang="less">

.upload-box {

  margin-left: 20px;

  display: flex;

  align-items: center;

  cursor: pointer;

  font-weight: normal;

  .icon-baogaodaochu {

    font-size: 14px;

    color: #3a5bb7;

  }

  .upload-text {

    font-size: 12px;

    color: #3a5bb7;

    margin-left: 3px;

  }

}

.item {

  border: 1px solid #ebeef8;

  border-top: none;

  .title {

    display: flex;

    align-items: center;

    padding-left: 26px;

    height: 38px;

    background: #f4f7fc;

    border: 1px solid #ebeef8;

    border-left: none;

    border-right: none;

    font-weight: bold;

    font-size: 14px;

    color: #333333;

    position: relative;

    &::before {

      content: '';

      position: absolute;

      left: 15px;

      top: 50%;

      margin-top: -5px;

      width: 4px;

      height: 10px;

      background: #3a5bb7;

      border-radius: 0px 2px 2px 0px;

    }

  }

  .table-box {

    padding: 15px;

    .item-detail {

      margin-bottom: 20px;

      &:last-child {

        margin-bottom: 0;

      }

      .detail-title {

        width: 80px;

        height: 30px;

        background: rgba(58, 91, 183, 0.06);

        border-radius: 6px;

        font-size: 13px;

        color: #3a5bb7;

        display: flex;

        align-items: center;

        justify-content: center;

        margin-right: 12px;

      }

      .all-detail {

        margin: 10px 0;

      }

      .children-item {

        margin-bottom: 10px;

        font-size: 14px;

        color: #333333;

        &:last-child {

          margin-bottom: 0;

        }

        .children-title {

          margin: 5px 0;

          display: flex;

          align-items: center;

          .dot {

            width: 4px;

            height: 4px;

            background: #333333;

            margin-right: 10px;

          }

        }

      }

    }

  }

}

</style>

四、ItemCard组件代码

<template>

  <div class="item-box">

    <div class="pub-item-title">

      {{ title }}

      <div class="right-part">

        <slot name="rightPart"></slot>

      </div>

    </div>

    <div class="content-box" id="content-to-export">

      <div

        class="overview-box"

        v-if="

          title !== '综述'

        "

      >

        <div class="title">{{ title }}</div>

        <div class="content" v-html="aiText"></div>

      </div>

      <slot name="otherContent"></slot>

    </div>

  </div>

</template>

<script setup lang="ts">

const props = defineProps({

  title: {

    type: String,

    default: ''

  },

  aiText: {

    type: String,

    default: ''

  },

  sketchList: {

    type: Array as any,

    default: () => {}

  }

})

</script>

<style scoped lang="less">

.item-box {

  width: 1410px;

  margin: 0 auto;

  padding: 0 20px 20px;

  background: #ffffff;

  border-radius: 6px;

  .pub-item-title {

    :deep(.right-part) {

      display: flex;

      align-items: center;

      margin-left: auto;

      .date-select {

        width: 300px;

        height: 28px;

        --el-text-color-regular: #333333;

      }

      .drop-select {

        margin-left: 14px;

        width: 100px;

        height: 28px;

        font-weight: normal;

        --el-text-color-regular: #333333;

        .el-input__wrapper {

          padding: 0 11px;

          .el-input__inner {

            line-height: 28px;

            height: 28px;

          }

        }

        .el-select__wrapper {

          min-height: 28px;

        }

      }

    }

  }

  .content-box {

    margin-top: 14px;

    // border: 1px solid #ebeef8;

    .overview-box {

      padding: 17px 15px;

      border: 1px solid #ebeef8;

      border-bottom: none;

      .title {

        padding-left: 10px;

        line-height: 14px;

        font-size: 14px;

        color: #3a5bb7;

        position: relative;

        &::before {

          content: '';

          position: absolute;

          left: 0;

          top: 50%;

          margin-top: -2px;

          width: 4px;

          height: 4px;

          background: #3a5bb7;

        }

      }

      .content {

        margin-top: 10px;

        text-align: justify;

        color: #333333;

      }

    }

  }

}

</style>

五、AISketch组件代码

<template>

  <div class="AISketch">

    <div class="item-sketch" v-for="(item, index) in sketchList" :key="index">

      <div class="tags">{{ item.title }}</div>

      <div class="tags-info" v-html="item.desc"></div>

    </div>

  </div>

</template>

<script setup lang="ts">

const props = defineProps({

  // 简述列表

  sketchList: {

    type: Array as any,

    default: () => {}

  }

})

</script>

<style lang="less" scoped>

.AISketch {

  .item-sketch {

    display: flex;

    align-items: center;

    margin-bottom: 10px;

    &:last-child {

      margin-bottom: 0;

    }

    .tags {

      width: 80px;

      height: 30px;

      background: rgba(58, 91, 183, 0.06);

      border-radius: 6px;

      font-size: 13px;

      color: #3a5bb7;

      display: flex;

      align-items: center;

      justify-content: center;

      margin-right: 12px;

    }

    .tags-info {

      font-size: 13px;

      color: #666666;

    }

  }

}

</style>

六、在public文件夹中创建word文件(ai-report.docx)

如下编写模板(样式自调):

综述

|简述

{#items}

{title}

{desc}

{/items}

|综述详情

{#infos}

{title}

 {overview}

{#items}

·{title}

{desc}

{/items}

{/infos}

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com