p-honggang.li
2025-09-03 9577bfd83282afad65a758321eec7186a10222f9
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
<template>
  <div>
    <!-- <el-dialog
      width="70%"
      height="800px"
      v-model="state.visible"
      :title="state.title"
      @closed="closeDialog"
      :close-on-click-modal="false"
    > -->
    <div class="boxDiv">
      <div class="close-icon" @click="closeDialog">
        <el-icon size="24"><CloseBold color="#fff" /></el-icon>
      </div>
      <el-scrollbar>
        <div
          v-if="state.fileType == '.docx' && state.visible"
          ref="file"
          class="files"
        ></div>
        <div
          v-if="state.fileType == '.doc' && state.visible"
          ref="fileT"
          class="files"
        ></div>
        <div v-if="state.fileType == '.pdf' && state.visible">
          <iframe
            :src="pdfurl"
            type="application/x-google-chrome-pdf"
            width="100%"
            height="780px"
          />
        </div>
      </el-scrollbar>
    </div>
    <!-- </el-dialog> -->
  </div>
</template>
 
<script setup lang="ts">
import { ref, nextTick, onMounted, getCurrentInstance, reactive } from 'vue'
import * as docx from 'docx-preview'
import commonApi from '@/api/commonApi'
 
// 获取dome
const { proxy } = getCurrentInstance()
//
const pdfurl = ref('')
 
interface BasicInfoType {
  id?: string // 客户id
  parentId: string
}
 
interface State {
  visible: boolean // 控制弹窗显示
  title?: string // 弹窗标题
  fileId?: string | number //文件id
  fileType: string
}
 
const state = reactive<any>({
  visible: false,
  title: '文件预览',
  fileId: '',
  fileType: '',
  file: '',
})
 
// 控制弹窗的显示
const visibleShow = (data?: any) => {
  state.visible = true
  state.fileId = data?.fileId ?? ''
  state.fileType = data?.suffix ?? ''
  if (state.fileType == '.docx') {
    previewDocxFun()
  } else if (state.fileType == '.doc') {
    previewDocFun()
  } else if (state.fileType == '.pdf') {
    previewPdfFun()
  }
}
 
// 调用预览接口
const previewDocxFun = () => {
  commonApi
    .getFileFlowById({ fileId: state.fileId })
    .then((res) => {
      if (res) {
        docx.renderAsync(res.data, proxy.$refs.file)
      } else {
        // ElMessage.warning(res.msg)
      }
    })
    .finally(() => {})
}
 
const fileT = ref()
 
const previewDocFun = () => {
  commonApi
    .getFileFlowById({ fileId: state.fileId })
    .then((res: any) => {
      if (res) {
        // let docx = require("docx-preview");
        docx.renderAsync(res.data, fileT.value)
      } else {
        // ElMessage.warning(res.msg)
      }
    })
    .finally(() => {})
}
 
const previewPdfFun = () => {
  commonApi
    .getFileFlowById({ fileId: state.fileId })
    .then((res) => {
      console.log('res', res)
      if (res) {
        let blob = new Blob([res.data], { type: 'application/pdf' })
        const url = URL.createObjectURL(blob)
        pdfurl.value = url
      }
    })
    .finally(() => {})
}
 
// 将方法暴露给父组件
defineExpose({
  visibleShow,
})
 
// 将子组件的事件触发暴露给父组件
const emit = defineEmits(['closePreview'])
// 关闭弹窗
const closeDialog = () => {
  pdfurl.value = ''
  if (state.fileType == '.docx') {
    docx?.renderAsync('', proxy.$refs.file)
  } else if (state.fileType == '.doc') {
  } else if (state.fileType == '.pdf') {
    pdfurl.value = ''
  }
  emit('closePreview')
}
</script>
 
<style scoped lang="scss">
.boxDiv {
  z-index: 999;
  position: absolute;
  top: 0;
  right: 0;
  left: 0;
  bottom: 0;
  .files {
    // width: 100%;
  }
}
.close-icon {
  position: absolute;
  right: 0;
  top: 0;
  width: 40px;
  height: 40px;
  background-color: #666;
  border-bottom-left-radius: 60px;
  padding-left: 10px;
  padding-top: 5px;
  cursor: pointer;
  z-index: 99999;
}
</style>