utils.js
3.91 KB
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
/**
* @Description: 文档预览工具函数
* @Date: 2025-01-30
*/
// #ifdef WEAPP
import Taro from '@tarojs/taro'
// #endif
/**
* 从 URL 中检测文件类型
* @param {string} url - 文档 URL
* @returns {string} 文件类型(小写)
*/
export function detectFileType(url) {
if (!url) return ''
// 从 URL 中提取扩展名
const match = url.match(/\.([a-z0-9]+)(?:\?|#|$)/i)
if (match && match[1]) {
const ext = match[1].toLowerCase()
// 映射常见扩展名到统一类型
const typeMap = {
pdf: 'pdf',
doc: 'doc',
docx: 'docx',
xls: 'xls',
xlsx: 'xlsx',
ppt: 'ppt',
pptx: 'pptx'
}
return typeMap[ext] || ext
}
// 如果无法从 URL 判断,尝试从 Content-Type 头(需要后端支持)
return ''
}
/**
* 获取文件大小(通过 HEAD 请求)
* @param {string} url - 文档 URL
* @returns {Promise<number>} 文件大小(字节)
*/
export async function getFileSize(url) {
return new Promise((resolve) => {
// #ifdef H5
// H5 环境:使用 fetch HEAD 请求
fetch(url, { method: 'HEAD' })
.then(response => {
const contentLength = response.headers.get('Content-Length')
if (contentLength) {
resolve(parseInt(contentLength, 10))
} else {
// 无法获取大小,返回 0(将使用 web-view)
resolve(0)
}
})
.catch(err => {
console.error('获取文件大小失败:', err)
// 失败时返回 0,将使用 web-view
resolve(0)
})
// #endif
// #ifdef WEAPP
// 小程序环境:使用 Taro.request HEAD 请求
Taro.request({
url: url,
method: 'HEAD',
success: (res) => {
const contentLength = res.header['Content-Length'] || res.header['content-length']
if (contentLength) {
resolve(parseInt(contentLength, 10))
} else {
// 无法获取大小,返回 0(将使用 web-view)
resolve(0)
}
},
fail: (err) => {
console.error('获取文件大小失败:', err)
// 失败时返回 0,将使用 web-view
resolve(0)
}
})
// #endif
})
}
/**
* 格式化文件大小显示
* @param {number} bytes - 文件大小(字节)
* @returns {string} 格式化后的字符串
*/
export function formatFileSize(bytes) {
if (!bytes || bytes === 0) return '未知大小'
const units = ['B', 'KB', 'MB', 'GB']
let size = bytes
let unitIndex = 0
while (size >= 1024 && unitIndex < units.length - 1) {
size /= 1024
unitIndex++
}
// 保留两位小数
const formatted = size.toFixed(2).replace(/\.00$/, '')
return `${formatted} ${units[unitIndex]}`
}
/**
* 判断是否为支持的文档类型
* @param {string} fileType - 文件类型
* @returns {boolean}
*/
export function isSupportedDocumentType(fileType) {
const supportedTypes = ['pdf', 'doc', 'docx', 'xls', 'xlsx', 'ppt', 'pptx']
return supportedTypes.includes(fileType?.toLowerCase())
}
/**
* 获取文件图标名称
* @param {string} fileType - 文件类型
* @returns {string} 图标名称
*/
export function getFileIconName(fileType) {
const iconMap = {
pdf: 'pdf',
doc: 'word',
docx: 'word',
xls: 'excel',
xlsx: 'excel',
ppt: 'ppt',
pptx: 'ppt'
}
return iconMap[fileType?.toLowerCase()] || 'file'
}
/**
* 生成腾讯文档预览 URL
* @param {string} url - 原始文档 URL
* @returns {string} 腾讯文档预览 URL
*/
export function getTencentPreviewUrl(url) {
const encodedUrl = encodeURIComponent(url)
return `https://view.officeapps.live.com/op/view.aspx?src=${encodedUrl}`
}
/**
* 生成微软在线预览 URL
* @param {string} url - 原始文档 URL
* @returns {string} 微软预览 URL
*/
export function getMicrosoftPreviewUrl(url) {
const encodedUrl = encodeURIComponent(url)
return `https://view.officeapps.live.com/op/embed.aspx?src=${encodedUrl}`
}