utils.js
3.59 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
/**
* @Description: 文档预览工具函数
* @Date: 2025-01-30
*/
/**
* 从 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) {
// 检测运行环境
const isWeapp = typeof wx !== 'undefined' || typeof my !== 'undefined'
// 小程序环境:使用 Taro.request
if (isWeapp) {
try {
const Taro = (await import('@tarojs/taro')).default
const res = await Taro.request({
url: url,
method: 'HEAD'
})
const contentLength = res.header['Content-Length'] || res.header['content-length']
if (contentLength) {
return parseInt(contentLength, 10)
}
} catch (err) {
console.error('获取文件大小失败:', err)
}
return 0
}
// H5 环境:使用 fetch
try {
const response = await fetch(url, { method: 'HEAD' })
const contentLength = response.headers.get('Content-Length')
if (contentLength) {
return parseInt(contentLength, 10)
}
} catch (err) {
console.error('获取文件大小失败:', err)
}
// 无法获取大小,返回 0(将使用 web-view)
return 0
}
/**
* 格式化文件大小显示
* @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}`
}