feat:【antd】【ai】chat “附件列表功能”的迁移
This commit is contained in:
@@ -65,3 +65,127 @@ export function generateAcceptedFileTypes(
|
||||
|
||||
return [...mimeTypes, ...extensions].join(',');
|
||||
}
|
||||
|
||||
/**
|
||||
* 从 URL 中提取文件名
|
||||
*
|
||||
* @param url 文件 URL
|
||||
* @returns 文件名,如果无法提取则返回 'unknown'
|
||||
*/
|
||||
export function getFileNameFromUrl(url: null | string | undefined): string {
|
||||
// 处理空值
|
||||
if (!url) {
|
||||
return 'unknown';
|
||||
}
|
||||
|
||||
try {
|
||||
const urlObj = new URL(url);
|
||||
const pathname = urlObj.pathname;
|
||||
const fileName = pathname.split('/').pop() || 'unknown';
|
||||
return decodeURIComponent(fileName);
|
||||
} catch {
|
||||
// 如果 URL 解析失败,尝试从字符串中提取
|
||||
const parts = url.split('/');
|
||||
return parts[parts.length - 1] || 'unknown';
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 判断文件是否为图片
|
||||
*
|
||||
* @param filename 文件名
|
||||
* @returns 是否为图片
|
||||
*/
|
||||
export function isImage(filename: null | string | undefined): boolean {
|
||||
if (!filename) {
|
||||
return false;
|
||||
}
|
||||
const ext = filename.split('.').pop()?.toLowerCase() || '';
|
||||
return ['bmp', 'gif', 'jpeg', 'jpg', 'png', 'svg', 'webp'].includes(ext);
|
||||
}
|
||||
|
||||
/**
|
||||
* 格式化文件大小
|
||||
*
|
||||
* @param bytes 文件大小(字节)
|
||||
* @returns 格式化后的文件大小字符串
|
||||
*/
|
||||
export function formatFileSize(bytes: number): string {
|
||||
if (bytes === 0) {
|
||||
return '0 B';
|
||||
}
|
||||
const k = 1024;
|
||||
const sizes = ['B', 'KB', 'MB', 'GB'];
|
||||
const i = Math.floor(Math.log(bytes) / Math.log(k));
|
||||
return `${Number.parseFloat((bytes / k ** i).toFixed(2))} ${sizes[i]}`;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取文件图标(Lucide Icons)
|
||||
*
|
||||
* @param filename 文件名
|
||||
* @returns Lucide 图标名称
|
||||
*/
|
||||
export function getFileIcon(filename: null | string | undefined): string {
|
||||
if (!filename) {
|
||||
return 'lucide:file';
|
||||
}
|
||||
const ext = filename.split('.').pop()?.toLowerCase() || '';
|
||||
if (isImage(ext)) {
|
||||
return 'lucide:image';
|
||||
}
|
||||
if (['pdf'].includes(ext)) {
|
||||
return 'lucide:file-text';
|
||||
}
|
||||
if (['doc', 'docx'].includes(ext)) {
|
||||
return 'lucide:file-text';
|
||||
}
|
||||
if (['xls', 'xlsx'].includes(ext)) {
|
||||
return 'lucide:file-spreadsheet';
|
||||
}
|
||||
if (['ppt', 'pptx'].includes(ext)) {
|
||||
return 'lucide:presentation';
|
||||
}
|
||||
if (['aac', 'm4a', 'mp3', 'wav'].includes(ext)) {
|
||||
return 'lucide:music';
|
||||
}
|
||||
if (['avi', 'mov', 'mp4', 'wmv'].includes(ext)) {
|
||||
return 'lucide:video';
|
||||
}
|
||||
return 'lucide:file';
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取文件类型样式类(Tailwind CSS 渐变色)
|
||||
*
|
||||
* @param filename 文件名
|
||||
* @returns Tailwind CSS 渐变类名
|
||||
*/
|
||||
export function getFileTypeClass(filename: null | string | undefined): string {
|
||||
if (!filename) {
|
||||
return 'from-gray-500 to-gray-700';
|
||||
}
|
||||
const ext = filename.split('.').pop()?.toLowerCase() || '';
|
||||
if (isImage(ext)) {
|
||||
return 'from-yellow-400 to-orange-500';
|
||||
}
|
||||
if (['pdf'].includes(ext)) {
|
||||
return 'from-red-500 to-red-700';
|
||||
}
|
||||
if (['doc', 'docx'].includes(ext)) {
|
||||
return 'from-blue-600 to-blue-800';
|
||||
}
|
||||
if (['xls', 'xlsx'].includes(ext)) {
|
||||
return 'from-green-600 to-green-800';
|
||||
}
|
||||
if (['ppt', 'pptx'].includes(ext)) {
|
||||
return 'from-orange-600 to-orange-800';
|
||||
}
|
||||
if (['aac', 'm4a', 'mp3', 'wav'].includes(ext)) {
|
||||
return 'from-purple-500 to-purple-700';
|
||||
}
|
||||
if (['avi', 'mov', 'mp4', 'wmv'].includes(ext)) {
|
||||
return 'from-red-500 to-red-700';
|
||||
}
|
||||
return 'from-gray-500 to-gray-700';
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user