feat:【antd】【ai】chat “附件列表功能”的迁移

This commit is contained in:
YunaiV
2025-11-15 21:25:14 +08:00
parent 844d4b9b1c
commit a35485e618
7 changed files with 522 additions and 3 deletions

View File

@@ -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';
}