refactor: 改用 Imgur 图床上传图片
This commit is contained in:
@@ -810,9 +810,12 @@ export class ForumService {
|
|||||||
// 图片上传 | Image Upload
|
// 图片上传 | Image Upload
|
||||||
// =====================================================
|
// =====================================================
|
||||||
|
|
||||||
|
/** Imgur Client ID (匿名上传) | Imgur Client ID (anonymous upload) */
|
||||||
|
private readonly IMGUR_CLIENT_ID = '546c25a59c58ad7';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 上传图片到 GitHub 仓库
|
* 上传图片到 Imgur 图床
|
||||||
* Upload image to GitHub repository
|
* Upload image to Imgur
|
||||||
* @param file 图片文件 | Image file
|
* @param file 图片文件 | Image file
|
||||||
* @param onProgress 进度回调 | Progress callback
|
* @param onProgress 进度回调 | Progress callback
|
||||||
* @returns 图片 URL | Image URL
|
* @returns 图片 URL | Image URL
|
||||||
@@ -821,72 +824,54 @@ export class ForumService {
|
|||||||
file: File,
|
file: File,
|
||||||
onProgress?: (progress: number) => void
|
onProgress?: (progress: number) => void
|
||||||
): Promise<string> {
|
): Promise<string> {
|
||||||
const token = this.currentUser?.accessToken;
|
|
||||||
if (!token) {
|
|
||||||
throw new Error('Not authenticated');
|
|
||||||
}
|
|
||||||
|
|
||||||
// 验证文件类型 | Validate file type
|
// 验证文件类型 | Validate file type
|
||||||
const allowedTypes = ['image/png', 'image/jpeg', 'image/gif', 'image/webp'];
|
const allowedTypes = ['image/png', 'image/jpeg', 'image/gif', 'image/webp'];
|
||||||
if (!allowedTypes.includes(file.type)) {
|
if (!allowedTypes.includes(file.type)) {
|
||||||
throw new Error('Only PNG, JPEG, GIF, and WebP images are allowed');
|
throw new Error('Only PNG, JPEG, GIF, and WebP images are allowed');
|
||||||
}
|
}
|
||||||
|
|
||||||
// 限制文件大小 (5MB) | Limit file size (5MB)
|
// 限制文件大小 (10MB - Imgur 限制) | Limit file size (10MB - Imgur limit)
|
||||||
const maxSize = 5 * 1024 * 1024;
|
const maxSize = 10 * 1024 * 1024;
|
||||||
if (file.size > maxSize) {
|
if (file.size > maxSize) {
|
||||||
throw new Error('Image size must be less than 5MB');
|
throw new Error('Image size must be less than 10MB');
|
||||||
}
|
}
|
||||||
|
|
||||||
onProgress?.(10);
|
onProgress?.(10);
|
||||||
|
|
||||||
// 生成唯一文件名 | Generate unique filename
|
|
||||||
const ext = file.name.split('.').pop() || 'png';
|
|
||||||
const timestamp = Date.now();
|
|
||||||
const randomStr = Math.random().toString(36).substring(2, 8);
|
|
||||||
const fileName = `${timestamp}-${randomStr}.${ext}`;
|
|
||||||
const filePath = `forum-images/${fileName}`;
|
|
||||||
|
|
||||||
onProgress?.(20);
|
|
||||||
|
|
||||||
// 读取文件为 base64 | Read file as base64
|
// 读取文件为 base64 | Read file as base64
|
||||||
const base64Content = await this.fileToBase64(file);
|
const base64Content = await this.fileToBase64(file);
|
||||||
|
|
||||||
onProgress?.(40);
|
onProgress?.(30);
|
||||||
|
|
||||||
// 使用 GitHub REST API 上传文件 | Upload file using GitHub REST API
|
// 使用 Imgur API 上传 | Upload using Imgur API
|
||||||
const response = await fetch(
|
const response = await fetch('https://api.imgur.com/3/image', {
|
||||||
`https://api.github.com/repos/${REPO_OWNER}/${REPO_NAME}/contents/${filePath}`,
|
method: 'POST',
|
||||||
{
|
headers: {
|
||||||
method: 'PUT',
|
'Authorization': `Client-ID ${this.IMGUR_CLIENT_ID}`,
|
||||||
headers: {
|
'Content-Type': 'application/json'
|
||||||
'Authorization': `Bearer ${token}`,
|
},
|
||||||
'Content-Type': 'application/json',
|
body: JSON.stringify({
|
||||||
'Accept': 'application/vnd.github.v3+json'
|
image: base64Content,
|
||||||
},
|
type: 'base64'
|
||||||
body: JSON.stringify({
|
})
|
||||||
message: `Upload forum image: ${fileName}`,
|
});
|
||||||
content: base64Content,
|
|
||||||
branch: 'master'
|
|
||||||
})
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
onProgress?.(80);
|
onProgress?.(80);
|
||||||
|
|
||||||
if (!response.ok) {
|
if (!response.ok) {
|
||||||
const errorData = await response.json().catch(() => ({}));
|
const errorData = await response.json().catch(() => ({}));
|
||||||
console.error('[ForumService] Upload failed:', errorData);
|
console.error('[ForumService] Imgur upload failed:', errorData);
|
||||||
throw new Error(`Failed to upload image: ${response.status}`);
|
throw new Error(`Failed to upload image: ${response.status}`);
|
||||||
}
|
}
|
||||||
|
|
||||||
const data = await response.json();
|
const data = await response.json();
|
||||||
onProgress?.(100);
|
onProgress?.(100);
|
||||||
|
|
||||||
// 返回 raw URL | Return raw URL
|
if (!data.success || !data.data?.link) {
|
||||||
// 使用 jsdelivr CDN 加速 | Use jsdelivr CDN for acceleration
|
throw new Error('Imgur upload failed: invalid response');
|
||||||
const cdnUrl = `https://cdn.jsdelivr.net/gh/${REPO_OWNER}/${REPO_NAME}@master/${filePath}`;
|
}
|
||||||
return cdnUrl;
|
|
||||||
|
return data.data.link;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
Reference in New Issue
Block a user