index.vue 2.6 KB
<!--
 * @Description: 文档在线预览页面(web-view 容器)
 * @Date: 2025-01-30
 * @Usage: 用于大文件(>= 10MB)的在线预览
-->
<template>
  <view class="document-preview-page">
    <!-- #ifdef WEAPP -->
    <web-view :src="previewUrl" @message="handleMessage" @load="handleLoad" @error="handleError" />
    <!-- #endif -->

    <!-- #ifdef H5 -->
    <iframe :src="previewUrl" frameborder="0" class="preview-iframe" />
    <!-- #endif -->
  </view>
</template>

<script setup>
import { computed, ref } from 'vue'
import { useLoad, useReady } from '@tarojs/taro'
import Taro from '@tarojs/taro'
import { getTencentPreviewUrl } from '@/components/DocumentPreview/utils'

// 响应式数据
const url = ref('')
const fileType = ref('')
const loading = ref(true)

// 计算属性
const previewUrl = computed(() => {
  if (!url.value) return ''

  const decodedUrl = decodeURIComponent(url.value)

  // 根据文件类型选择预览方式
  if (fileType.value === 'pdf') {
    // PDF 可以直接显示(需要支持跨域)
    return decodedUrl
  } else {
    // Office 文档使用腾讯文档预览
    return getTencentPreviewUrl(decodedUrl)
  }
})

// 页面加载
useLoad((options) => {
  console.log('文档预览页面参数:', options)

  if (options.url) {
    url.value = options.url
  }

  if (options.type) {
    fileType.value = decodeURIComponent(options.type)
  }

  // 设置导航栏标题
  const titleMap = {
    pdf: 'PDF 预览',
    doc: 'Word 预览',
    docx: 'Word 预览',
    xls: 'Excel 预览',
    xlsx: 'Excel 预览',
    ppt: 'PPT 预览',
    pptx: 'PPT 预览'
  }

  const title = titleMap[fileType.value] || '文档预览'

  // #ifdef WEAPP
  Taro.setNavigationBarTitle({ title })
  // #endif
})

useReady(() => {
  console.log('文档预览页面 ready')
})

/**
 * web-view 加载完成
 */
const handleLoad = () => {
  console.log('web-view 加载完成')
  loading.value = false

  // #ifdef WEAPP
  Taro.hideLoading()
  // #endif
}

/**
 * web-view 错误
 */
const handleError = (e) => {
  console.error('web-view 加载失败:', e)
  loading.value = false

  // #ifdef WEAPP
  Taro.hideLoading()
  Taro.showToast({
    title: '预览加载失败',
    icon: 'none'
  })
  // #endif
}

/**
 * 接收 web-view 消息
 */
const handleMessage = (e) => {
  console.log('收到 web-view 消息:', e.detail.data)
}
</script>

<style lang="less" scoped>
.document-preview-page {
  width: 100%;
  height: 100vh;
  background: #fff;
}

// #ifdef WEAPP
web-view {
  width: 100%;
  height: 100%;
}
// #endif

// #ifdef H5
.preview-iframe {
  width: 100%;
  height: 100vh;
  border: none;
}
// #endif
</style>