hookehuyr

refactor(utils): 提取统一的文件扩展名判断函数

- 新增 extractExtensionFromFile() 统一函数
- 优先使用 extension 字段
- 更新 documentIcons.js/tools.js/useFileOperation.js 使用统一函数
- 更新 API 类型定义和组件

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
...@@ -40,6 +40,7 @@ const Api = { ...@@ -40,6 +40,7 @@ const Api = {
40 file_name: string; // 附件名 40 file_name: string; // 附件名
41 file_size: string; // 附件大小 41 file_size: string; // 附件大小
42 file_size_formatted: string; // 附件大小(转换过显示) 42 file_size_formatted: string; // 附件大小(转换过显示)
43 + extension?: string; // 文件扩展名(优先使用)
43 }>; 44 }>;
44 cover_image: string; // 产品封面图 45 cover_image: string; // 产品封面图
45 * }; 46 * };
......
...@@ -129,18 +129,24 @@ const emit = defineEmits({ ...@@ -129,18 +129,24 @@ const emit = defineEmits({
129 /** 129 /**
130 * 获取文档图标 URL 130 * 获取文档图标 URL
131 * 131 *
132 - * @description 根据文件名获取对应的文档类型图标 132 + * @description 优先使用 extension 字段,其次从 fileName 解析
133 * @returns {string} 图标 URL 133 * @returns {string} 图标 URL
134 */ 134 */
135 -const iconUrl = props.fileName ? getDocumentIcon(props.fileName) : ''; 135 +const iconUrl = getDocumentIcon({
136 + extension: props.extension,
137 + fileName: props.fileName
138 +});
136 139
137 /** 140 /**
138 * 获取文档类型标签 141 * 获取文档类型标签
139 * 142 *
140 - * @description 根据文件名获取文档类型标签文本 143 + * @description 优先使用 extension 字段,其次从 fileName 解析
141 * @returns {string} 文档类型标签 144 * @returns {string} 文档类型标签
142 */ 145 */
143 -const docTypeLabel = props.fileName ? getDocumentLabel(props.fileName) : ''; 146 +const docTypeLabel = getDocumentLabel({
147 + extension: props.extension,
148 + fileName: props.fileName
149 +});
144 150
145 /** 151 /**
146 * 使用收藏操作 composable 152 * 使用收藏操作 composable
......
...@@ -10,6 +10,7 @@ ...@@ -10,6 +10,7 @@
10 10
11 import { showToast, showLoading, hideLoading, showModal, openDocument, downloadFile, previewImage } from '@tarojs/taro' 11 import { showToast, showLoading, hideLoading, showModal, openDocument, downloadFile, previewImage } from '@tarojs/taro'
12 import { isVideoFile } from '@/utils/tools' 12 import { isVideoFile } from '@/utils/tools'
13 +import { extractExtensionFromFile } from '@/utils/documentIcons'
13 14
14 /** 15 /**
15 * 文件操作 Hook 16 * 文件操作 Hook
...@@ -20,13 +21,18 @@ export function useFileOperation() { ...@@ -20,13 +21,18 @@ export function useFileOperation() {
20 /** 21 /**
21 * 判断是否为图片文件 22 * 判断是否为图片文件
22 * 23 *
23 - * @param {string} fileName - 文件名 24 + * @description 支持传入文件名或包含 extension 字段的对象,优先使用 extension 字段
25 + * @param {string|Object} fileNameOrItem - 文件名或文件对象
26 + * @param {string} [fileNameOrItem.fileName] - 文件名
27 + * @param {string} [fileNameOrItem.extension] - 文件扩展名(优先使用)
24 * @returns {boolean} 是否为图片文件 28 * @returns {boolean} 是否为图片文件
25 */ 29 */
26 - const isImageFile = (fileName) => { 30 + const isImageFile = (fileNameOrItem) => {
27 - if (!fileName) return false 31 + const extension = extractExtensionFromFile(fileNameOrItem)
32 +
33 + if (!extension) return false
34 +
28 const imageExtensions = ['jpg', 'jpeg', 'png', 'gif', 'webp', 'bmp', 'svg'] 35 const imageExtensions = ['jpg', 'jpeg', 'png', 'gif', 'webp', 'bmp', 'svg']
29 - const extension = fileName.split('.').pop()?.toLowerCase() || ''
30 return imageExtensions.includes(extension) 36 return imageExtensions.includes(extension)
31 } 37 }
32 /** 38 /**
...@@ -36,12 +42,14 @@ export function useFileOperation() { ...@@ -36,12 +42,14 @@ export function useFileOperation() {
36 * @async 42 * @async
37 * @param {string} filePath - 本地文件路径 43 * @param {string} filePath - 本地文件路径
38 * @param {Object} item - 文件信息对象 44 * @param {Object} item - 文件信息对象
39 - * @param {string} item.fileName - 文件名(用于判断文件类型) 45 + * @param {string} [item.fileName] - 文件名(用于判断文件类型)
46 + * @param {string} [item.extension] - 文件扩展名(优先使用)
40 * @returns {Promise<void>} 47 * @returns {Promise<void>}
41 * 48 *
42 * @example 49 * @example
43 * const { openFile } = useFileOperation() 50 * const { openFile } = useFileOperation()
44 * await openFile(tempFilePath, { fileName: 'document.pdf' }) 51 * await openFile(tempFilePath, { fileName: 'document.pdf' })
52 + * await openFile(tempFilePath, { extension: 'pdf' }) // 优先使用 extension
45 */ 53 */
46 const openFile = async (filePath, item) => { 54 const openFile = async (filePath, item) => {
47 try { 55 try {
...@@ -51,7 +59,8 @@ export function useFileOperation() { ...@@ -51,7 +59,8 @@ export function useFileOperation() {
51 success: () => { 59 success: () => {
52 console.log('文件打开成功') 60 console.log('文件打开成功')
53 // 文件打开后,延迟提示用户如果看不到内容该如何操作 61 // 文件打开后,延迟提示用户如果看不到内容该如何操作
54 - const fileExt = item.fileName.split('.').pop()?.toLowerCase() || '' 62 + // 使用统一的扩展名提取函数
63 + const fileExt = extractExtensionFromFile(item)
55 const unsupportedFormats = ['docx', 'doc', 'pptx', 'ppt', 'xlsx', 'xls'] 64 const unsupportedFormats = ['docx', 'doc', 'pptx', 'ppt', 'xlsx', 'xls']
56 65
57 if (unsupportedFormats.includes(fileExt)) { 66 if (unsupportedFormats.includes(fileExt)) {
...@@ -67,8 +76,8 @@ export function useFileOperation() { ...@@ -67,8 +76,8 @@ export function useFileOperation() {
67 fail: (err) => { 76 fail: (err) => {
68 console.error('打开文件失败:', err) 77 console.error('打开文件失败:', err)
69 78
70 - // 获取文件扩展名 79 + // 获取文件扩展名(使用统一的扩展名提取函数)
71 - const fileExt = item.fileName.split('.').pop()?.toLowerCase() || '' 80 + const fileExt = extractExtensionFromFile(item)
72 81
73 // 根据文件类型给出提示 82 // 根据文件类型给出提示
74 let message = '文件打开失败' 83 let message = '文件打开失败'
...@@ -110,7 +119,8 @@ export function useFileOperation() { ...@@ -110,7 +119,8 @@ export function useFileOperation() {
110 * @async 119 * @async
111 * @param {Object} item - 文件信息对象 120 * @param {Object} item - 文件信息对象
112 * @param {string} item.downloadUrl - 文件下载地址 121 * @param {string} item.downloadUrl - 文件下载地址
113 - * @param {string} item.fileName - 文件名 122 + * @param {string} [item.fileName] - 文件名
123 + * @param {string} [item.extension] - 文件扩展名(优先使用)
114 * @returns {Promise<void>} 124 * @returns {Promise<void>}
115 * 125 *
116 * @example 126 * @example
...@@ -119,10 +129,14 @@ export function useFileOperation() { ...@@ -119,10 +129,14 @@ export function useFileOperation() {
119 * downloadUrl: 'https://example.com/file.pdf', 129 * downloadUrl: 'https://example.com/file.pdf',
120 * fileName: 'document.pdf' 130 * fileName: 'document.pdf'
121 * }) 131 * })
132 + * await downloadAndOpenFile({
133 + * downloadUrl: 'https://example.com/file.pdf',
134 + * extension: 'pdf' // 优先使用 extension
135 + * })
122 */ 136 */
123 const downloadAndOpenFile = async (item) => { 137 const downloadAndOpenFile = async (item) => {
124 try { 138 try {
125 - // 下载文件 139 + //下载文件
126 const downloadResult = await downloadFile({ 140 const downloadResult = await downloadFile({
127 url: item.downloadUrl 141 url: item.downloadUrl
128 }) 142 })
...@@ -139,8 +153,8 @@ export function useFileOperation() { ...@@ -139,8 +153,8 @@ export function useFileOperation() {
139 // 隐藏加载提示 153 // 隐藏加载提示
140 hideLoading() 154 hideLoading()
141 155
142 - // 获取文件扩展名 156 + // 获取文件扩展名(使用统一的扩展名提取函数)
143 - const fileExt = item.fileName.split('.').pop()?.toLowerCase() || '' 157 + const fileExt = extractExtensionFromFile(item)
144 158
145 // 微信小程序对 Office 文档支持有限,提前提示用户 159 // 微信小程序对 Office 文档支持有限,提前提示用户
146 const unsupportedFormats = ['docx', 'doc', 'pptx', 'ppt', 'xlsx', 'xls'] 160 const unsupportedFormats = ['docx', 'doc', 'pptx', 'ppt', 'xlsx', 'xls']
...@@ -194,7 +208,8 @@ export function useFileOperation() { ...@@ -194,7 +208,8 @@ export function useFileOperation() {
194 * @async 208 * @async
195 * @param {Object} item - 文件信息对象 209 * @param {Object} item - 文件信息对象
196 * @param {string} [item.downloadUrl] - 文件下载地址 210 * @param {string} [item.downloadUrl] - 文件下载地址
197 - * @param {string} item.fileName - 文件名 211 + * @param {string} [item.fileName] - 文件名
212 + * @param {string} [item.extension] - 文件扩展名(优先使用)
198 * @returns {Promise<void>} 213 * @returns {Promise<void>}
199 * 214 *
200 * @example 215 * @example
...@@ -203,6 +218,10 @@ export function useFileOperation() { ...@@ -203,6 +218,10 @@ export function useFileOperation() {
203 * downloadUrl: 'https://example.com/file.pdf', 218 * downloadUrl: 'https://example.com/file.pdf',
204 * fileName: 'document.pdf' 219 * fileName: 'document.pdf'
205 * }) 220 * })
221 + * await viewFile({
222 + * downloadUrl: 'https://example.com/file.pdf',
223 + * extension: 'pdf' // 优先使用 extension
224 + * })
206 */ 225 */
207 const viewFile = async (item) => { 226 const viewFile = async (item) => {
208 // 检查是否有下载地址 227 // 检查是否有下载地址
...@@ -215,8 +234,8 @@ export function useFileOperation() { ...@@ -215,8 +234,8 @@ export function useFileOperation() {
215 return 234 return
216 } 235 }
217 236
218 - // 判断是否为图片文件 237 + // 判断是否为图片文件(优先使用 extension 字段)
219 - if (isImageFile(item.fileName)) { 238 + if (isImageFile(item)) {
220 // 图片文件:使用图片预览 239 // 图片文件:使用图片预览
221 console.log('[文件操作] 检测到图片文件,使用图片预览') 240 console.log('[文件操作] 检测到图片文件,使用图片预览')
222 try { 241 try {
...@@ -235,8 +254,8 @@ export function useFileOperation() { ...@@ -235,8 +254,8 @@ export function useFileOperation() {
235 return 254 return
236 } 255 }
237 256
238 - // 判断是否为视频文件 257 + // 判断是否为视频文件(优先使用 extension 字段)
239 - if (isVideoFile(item.fileName)) { 258 + if (isVideoFile(item)) {
240 // 视频文件:跳转到视频播放页面 259 // 视频文件:跳转到视频播放页面
241 // 需要动态导入 navigateTo 以避免循环依赖 260 // 需要动态导入 navigateTo 以避免循环依赖
242 const Taro = await import('@tarojs/taro') 261 const Taro = await import('@tarojs/taro')
......
...@@ -28,7 +28,7 @@ ...@@ -28,7 +28,7 @@
28 <view class="flex gap-[24rpx] mb-[12rpx]"> 28 <view class="flex gap-[24rpx] mb-[12rpx]">
29 <!-- Document Icon --> 29 <!-- Document Icon -->
30 <view class="w-[88rpx] h-[88rpx] mr-[24rpx] flex-shrink-0 flex items-center justify-center bg-gradient-to-br from-blue-50 to-blue-100 rounded-[20rpx] shadow-inner self-start"> 30 <view class="w-[88rpx] h-[88rpx] mr-[24rpx] flex-shrink-0 flex items-center justify-center bg-gradient-to-br from-blue-50 to-blue-100 rounded-[20rpx] shadow-inner self-start">
31 - <image :src="getDocumentIcon(item.name)" class="w-[48rpx] h-[48rpx]" mode="aspectFit" /> 31 + <image :src="getDocumentIcon({ extension: item.extension, fileName: item.name })" class="w-[48rpx] h-[48rpx]" mode="aspectFit" />
32 </view> 32 </view>
33 33
34 <!-- Title --> 34 <!-- Title -->
......
...@@ -79,13 +79,13 @@ ...@@ -79,13 +79,13 @@
79 <div class="flex items-center justify-between"> 79 <div class="flex items-center justify-between">
80 <div class="flex items-center flex-1 mr-[24rpx]"> 80 <div class="flex items-center flex-1 mr-[24rpx]">
81 <image 81 <image
82 - :src="getDocumentIcon(doc.file_name)" 82 + :src="getDocumentIcon({ extension: doc.extension, fileName: doc.file_name })"
83 class="w-[58rpx] h-[58rpx] mr-[24rpx]" 83 class="w-[58rpx] h-[58rpx] mr-[24rpx]"
84 mode="aspectFit" 84 mode="aspectFit"
85 /> 85 />
86 <div class="flex flex-col"> 86 <div class="flex flex-col">
87 <span class="text-[#1F2937] text-[28rpx] font-medium mb-[4rpx] line-clamp-2">{{ doc.file_name }}</span> 87 <span class="text-[#1F2937] text-[28rpx] font-medium mb-[4rpx] line-clamp-2">{{ doc.file_name }}</span>
88 - <span class="text-[#9CA3AF] text-[24rpx]">{{ getDocumentLabel(doc.file_name) }} · {{ doc.file_size_formatted }}</span> 88 + <span class="text-[#9CA3AF] text-[24rpx]">{{ getDocumentLabel({ extension: doc.extension, fileName: doc.file_name }) }} · {{ doc.file_size_formatted }}</span>
89 </div> 89 </div>
90 </div> 90 </div>
91 <IconFont name="eye" size="14" color="#2563EB" @tap="viewDocument(doc)" /> 91 <IconFont name="eye" size="14" color="#2563EB" @tap="viewDocument(doc)" />
......
...@@ -104,110 +104,179 @@ const EXTENSION_LABEL_MAP = { ...@@ -104,110 +104,179 @@ const EXTENSION_LABEL_MAP = {
104 const DEFAULT_LABEL = 'DOC'; 104 const DEFAULT_LABEL = 'DOC';
105 105
106 /** 106 /**
107 - * 根据文件名获取文档图标路径 107 + * 根据文件名或扩展名获取文档图标路径
108 * 108 *
109 - * @description 从文件名中提取扩展名,返回对应的图标路径 109 + * @description 支持传入文件名或包含 extension 字段的对象,优先使用 extension 字段
110 - * @param {string} fileName - 文件名(如:document.pdf) 110 + * @param {string|Object} fileNameOrItem - 文件名(如:document.pdf)或文件对象(包含 extension 字段)
111 + * @param {string} [fileNameOrItem.fileName] - 文件名
112 + * @param {string} [fileNameOrItem.extension] - 文件扩展名(优先使用)
111 * @returns {string} 图标路径 113 * @returns {string} 图标路径
112 * 114 *
113 * @example 115 * @example
114 * getDocumentIcon('报告.pdf') // 返回 PDF 图标 116 * getDocumentIcon('报告.pdf') // 返回 PDF 图标
117 + * getDocumentIcon({ extension: 'pdf' }) // 返回 PDF 图标(优先使用 extension)
118 + * getDocumentIcon({ fileName: '报告.pdf' }) // 返回 PDF 图标
115 * getDocumentIcon('数据.xlsx') // 返回 Excel 图标 119 * getDocumentIcon('数据.xlsx') // 返回 Excel 图标
116 * getDocumentIcon('图片.png') // 返回 PNG 图标 120 * getDocumentIcon('图片.png') // 返回 PNG 图标
117 */ 121 */
118 -export function getDocumentIcon(fileName) { 122 +export function getDocumentIcon(fileNameOrItem) {
119 - if (!fileName || typeof fileName !== 'string') { 123 + const extension = extractExtensionFromFile(fileNameOrItem);
124 +
125 + if (!extension) {
120 return DEFAULT_ICON; 126 return DEFAULT_ICON;
121 } 127 }
122 128
129 + // 返回对应图标,找不到则返回默认图标
130 + return EXTENSION_ICON_MAP[extension.toLowerCase()] || DEFAULT_ICON;
131 +}
132 +
133 +/**
134 + * 从文件名或文件对象中提取扩展名(统一工具函数)
135 + *
136 + * @description 支持传入文件名或包含 extension 字段的对象,优先使用 extension 字段。
137 + * 这是项目中所有文件类型判断的核心工具函数。
138 + * @param {string|Object} fileNameOrItem - 文件名(如:document.pdf)或文件对象(包含 extension 字段)
139 + * @param {string} [fileNameOrItem.fileName] - 文件名
140 + * @param {string} [fileNameOrItem.extension] - 文件扩展名(优先使用)
141 + * @returns {string} 扩展名(小写),空字符串表示无法提取
142 + *
143 + * @example
144 + * extractExtensionFromFile('document.pdf') // 'pdf'
145 + * extractExtensionFromFile({ extension: 'PDF' }) // 'pdf'(自动转小写)
146 + * extractExtensionFromFile({ fileName: 'document.DOC' }) // 'doc'(从文件名解析)
147 + * extractExtensionFromFile({ extension: 'pdf', fileName: 'backup.doc' }) // 'pdf'(优先使用 extension)
148 + */
149 +export function extractExtensionFromFile(fileNameOrItem) {
150 + let extension = '';
151 +
152 + // 支持对象格式(优先使用 extension 字段)
153 + if (typeof fileNameOrItem === 'object' && fileNameOrItem !== null) {
154 + extension = fileNameOrItem.extension || '';
155 + // 如果没有 extension 字段,尝试从 fileName 解析
156 + if (!extension && fileNameOrItem.fileName) {
157 + extension = extractExtensionFromString(fileNameOrItem.fileName);
158 + }
159 + } else if (typeof fileNameOrItem === 'string') {
160 + // 兼容字符串格式,从文件名解析
161 + extension = extractExtensionFromString(fileNameOrItem);
162 + }
163 +
164 + return extension.toLowerCase();
165 +}
166 +
167 +/**
168 + * 从文件名字符串中提取扩展名
169 + *
170 + * @description 内部辅助函数,从文件名字符串中提取扩展名
171 + * @param {string} fileName - 文件名
172 + * @returns {string} 扩展名(小写)
173 + * @private
174 + */
175 +function extractExtensionFromString(fileName) {
176 + if (!fileName || typeof fileName !== 'string') {
177 + return '';
178 + }
179 +
123 // 提取文件扩展名 180 // 提取文件扩展名
124 const lastDotIndex = fileName.lastIndexOf('.'); 181 const lastDotIndex = fileName.lastIndexOf('.');
125 182
126 // 没有扩展名或以点结尾(如 "file.") 183 // 没有扩展名或以点结尾(如 "file.")
127 if (lastDotIndex === -1 || lastDotIndex === fileName.length - 1) { 184 if (lastDotIndex === -1 || lastDotIndex === fileName.length - 1) {
128 - return DEFAULT_ICON; 185 + return '';
129 } 186 }
130 187
131 - const extension = fileName.slice(lastDotIndex + 1).toLowerCase(); 188 + return fileName.slice(lastDotIndex + 1).toLowerCase();
132 -
133 - // 返回对应图标,找不到则返回默认图标
134 - return EXTENSION_ICON_MAP[extension] || DEFAULT_ICON;
135 } 189 }
136 190
137 /** 191 /**
138 - * 根据文件名获取文件类型标签 192 + * 根据文件名或扩展名获取文件类型标签
139 * 193 *
140 - * @description 从文件名中提取扩展名,返回对应的显示标签 194 + * @description 支持传入文件名或包含 extension 字段的对象,优先使用 extension 字段
141 - * @param {string} fileName - 文件名(如:document.pdf) 195 + * @param {string|Object} fileNameOrItem - 文件名(如:document.pdf)或文件对象(包含 extension 字段)
196 + * @param {string} [fileNameOrItem.fileName] - 文件名
197 + * @param {string} [fileNameOrItem.extension] - 文件扩展名(优先使用)
142 * @returns {string} 文件类型标签(如:PDF、Word、Excel) 198 * @returns {string} 文件类型标签(如:PDF、Word、Excel)
143 * 199 *
144 * @example 200 * @example
145 * getDocumentLabel('报告.pdf') // 'PDF' 201 * getDocumentLabel('报告.pdf') // 'PDF'
202 + * getDocumentLabel({ extension: 'pdf' }) // 'PDF'(优先使用 extension)
203 + * getDocumentLabel({ fileName: '报告.pdf' }) // 'PDF'
146 * getDocumentLabel('数据.xlsx') // 'Excel' 204 * getDocumentLabel('数据.xlsx') // 'Excel'
147 * getDocumentLabel('图片.png') // 'PNG' 205 * getDocumentLabel('图片.png') // 'PNG'
148 */ 206 */
149 -export function getDocumentLabel(fileName) { 207 +export function getDocumentLabel(fileNameOrItem) {
150 - if (!fileName || typeof fileName !== 'string') { 208 + const extension = extractExtensionFromFile(fileNameOrItem);
151 - return DEFAULT_LABEL;
152 - }
153 -
154 - // 提取文件扩展名
155 - const lastDotIndex = fileName.lastIndexOf('.');
156 209
157 - // 没有扩展名或以点结尾(如 "file.") 210 + if (!extension) {
158 - if (lastDotIndex === -1 || lastDotIndex === fileName.length - 1) {
159 return DEFAULT_LABEL; 211 return DEFAULT_LABEL;
160 } 212 }
161 213
162 - const extension = fileName.slice(lastDotIndex + 1).toLowerCase();
163 -
164 // 返回对应标签,找不到则返回默认标签 214 // 返回对应标签,找不到则返回默认标签
165 - return EXTENSION_LABEL_MAP[extension] || DEFAULT_LABEL; 215 + return EXTENSION_LABEL_MAP[extension.toLowerCase()] || DEFAULT_LABEL;
166 } 216 }
167 217
168 /** 218 /**
169 - * 根据文件名判断是否为 PDF 文件 219 + * 根据文件名或扩展名判断是否为 PDF 文件
170 * 220 *
171 - * @param {string} fileName - 文件名 221 + * @description 支持传入文件名或包含 extension 字段的对象,优先使用 extension 字段
222 + * @param {string|Object} fileNameOrItem - 文件名或文件对象(包含 extension 字段)
223 + * @param {string} [fileNameOrItem.fileName] - 文件名
224 + * @param {string} [fileNameOrItem.extension] - 文件扩展名(优先使用)
172 * @returns {boolean} 是否为 PDF 文件 225 * @returns {boolean} 是否为 PDF 文件
173 * 226 *
174 * @example 227 * @example
175 * isPDF('document.pdf') // true 228 * isPDF('document.pdf') // true
229 + * isPDF({ extension: 'pdf' }) // true(优先使用 extension)
230 + * isPDF({ fileName: 'document.pdf' }) // true
176 * isPDF('document.docx') // false 231 * isPDF('document.docx') // false
177 */ 232 */
178 -export function isPDF(fileName) { 233 +export function isPDF(fileNameOrItem) {
179 - const extension = fileName?.split('.').pop()?.toLowerCase(); 234 + const extension = extractExtensionFromFile(fileNameOrItem);
180 - return extension === 'pdf'; 235 + return extension.toLowerCase() === 'pdf';
181 } 236 }
182 237
183 /** 238 /**
184 - * 根据文件名判断是否为图片文件 239 + * 根据文件名或扩展名判断是否为图片文件
185 * 240 *
186 - * @param {string} fileName - 文件名 241 + * @description 支持传入文件名或包含 extension 字段的对象,优先使用 extension 字段
242 + * @param {string|Object} fileNameOrItem - 文件名或文件对象(包含 extension 字段)
243 + * @param {string} [fileNameOrItem.fileName] - 文件名
244 + * @param {string} [fileNameOrItem.extension] - 文件扩展名(优先使用)
187 * @returns {boolean} 是否为图片文件 245 * @returns {boolean} 是否为图片文件
188 * 246 *
189 * @example 247 * @example
190 * isImage('photo.jpg') // true 248 * isImage('photo.jpg') // true
249 + * isImage({ extension: 'jpg' }) // true(优先使用 extension)
191 * isImage('document.pdf') // false 250 * isImage('document.pdf') // false
192 */ 251 */
193 -export function isImage(fileName) { 252 +export function isImage(fileNameOrItem) {
194 - const extension = fileName?.split('.').pop()?.toLowerCase(); 253 + const extension = extractExtensionFromFile(fileNameOrItem);
254 +
255 + if (!extension) return false;
256 +
195 const imageExtensions = ['jpg', 'jpeg', 'png', 'gif', 'webp', 'svg']; 257 const imageExtensions = ['jpg', 'jpeg', 'png', 'gif', 'webp', 'svg'];
196 - return imageExtensions.includes(extension); 258 + return imageExtensions.includes(extension.toLowerCase());
197 } 259 }
198 260
199 /** 261 /**
200 - * 根据文件名判断是否为视频文件 262 + * 根据文件名或扩展名判断是否为视频文件
201 * 263 *
202 - * @param {string} fileName - 文件名 264 + * @description 支持传入文件名或包含 extension 字段的对象,优先使用 extension 字段
265 + * @param {string|Object} fileNameOrItem - 文件名或文件对象(包含 extension 字段)
266 + * @param {string} [fileNameOrItem.fileName] - 文件名
267 + * @param {string} [fileNameOrItem.extension] - 文件扩展名(优先使用)
203 * @returns {boolean} 是否为视频文件 268 * @returns {boolean} 是否为视频文件
204 * 269 *
205 * @example 270 * @example
206 * isVideo('movie.mp4') // true 271 * isVideo('movie.mp4') // true
272 + * isVideo({ extension: 'mp4' }) // true(优先使用 extension)
207 * isVideo('document.pdf') // false 273 * isVideo('document.pdf') // false
208 */ 274 */
209 -export function isVideo(fileName) { 275 +export function isVideo(fileNameOrItem) {
210 - const extension = fileName?.split('.').pop()?.toLowerCase(); 276 + const extension = extractExtensionFromFile(fileNameOrItem);
277 +
278 + if (!extension) return false;
279 +
211 const videoExtensions = ['mp4', 'mov', 'avi', 'mkv']; 280 const videoExtensions = ['mp4', 'mov', 'avi', 'mkv'];
212 - return videoExtensions.includes(extension); 281 + return videoExtensions.includes(extension.toLowerCase());
213 } 282 }
......
...@@ -8,6 +8,7 @@ ...@@ -8,6 +8,7 @@
8 import dayjs from 'dayjs'; 8 import dayjs from 'dayjs';
9 import Taro from '@tarojs/taro'; 9 import Taro from '@tarojs/taro';
10 import BASE_URL, { REQUEST_DEFAULT_PARAMS } from './config' 10 import BASE_URL, { REQUEST_DEFAULT_PARAMS } from './config'
11 +import { extractExtensionFromFile } from './documentIcons'
11 12
12 /** 13 /**
13 * @description 格式化时间 14 * @description 格式化时间
...@@ -199,24 +200,26 @@ const buildApiUrl = (action, params = {}) => { ...@@ -199,24 +200,26 @@ const buildApiUrl = (action, params = {}) => {
199 200
200 /** 201 /**
201 * @description 判断文件是否为视频文件 202 * @description 判断文件是否为视频文件
202 - * @param {string} fileName 文件名 203 + * @param {string|Object} fileNameOrItem 文件名或文件对象(支持 extension 字段)
204 + * @param {string} [fileNameOrItem.fileName] - 文件名
205 + * @param {string} [fileNameOrItem.extension] - 文件扩展名(优先使用)
203 * @returns {boolean} true=是视频文件,false=不是视频文件 206 * @returns {boolean} true=是视频文件,false=不是视频文件
204 * 207 *
205 * @example 208 * @example
206 * isVideoFile('video.mp4') // true 209 * isVideoFile('video.mp4') // true
210 + * isVideoFile({ extension: 'mp4' }) // true (优先使用 extension)
207 * isVideoFile('document.pdf') // false 211 * isVideoFile('document.pdf') // false
208 * isVideoFile('presentation.mov') // true 212 * isVideoFile('presentation.mov') // true
209 */ 213 */
210 -const isVideoFile = (fileName) => { 214 +const isVideoFile = (fileNameOrItem) => {
211 - if (!fileName || typeof fileName !== 'string') return false; 215 + const extension = extractExtensionFromFile(fileNameOrItem);
212 216
213 - // 提取文件扩展名 217 + if (!extension) return false;
214 - const ext = fileName.split('.').pop()?.toLowerCase() || '';
215 218
216 // 微信小程序支持的视频格式 219 // 微信小程序支持的视频格式
217 const videoExtensions = ['mp4', 'm4v', 'mov']; 220 const videoExtensions = ['mp4', 'm4v', 'mov'];
218 221
219 - return videoExtensions.includes(ext); 222 + return videoExtensions.includes(extension.toLowerCase());
220 }; 223 };
221 224
222 export { 225 export {
......