fix(media): سقف آپلود ۱۰→۲۵ مگابایت (لبه ۳۰MB) + پیام مشخص ۴۱۳ و پیشچک حجم سمت کاربر — فایلهای بزرگ تیم محتوا در لبه رد میشدند
This commit is contained in:
@@ -26,7 +26,8 @@ class Settings(BaseSettings):
|
|||||||
s3_bucket: str = "aramesh-media"
|
s3_bucket: str = "aramesh-media"
|
||||||
# پیشوند عمومی مسیر تصاویر — Traefik آن را به باکت پروکسی میکند
|
# پیشوند عمومی مسیر تصاویر — Traefik آن را به باکت پروکسی میکند
|
||||||
media_public_base: str = "/media"
|
media_public_base: str = "/media"
|
||||||
media_max_upload_mb: int = 10
|
# رندرهای معماری حجیماند — لبه (Traefik api-bodylimit) باید همیشه بزرگتر از این باشد
|
||||||
|
media_max_upload_mb: int = 25
|
||||||
|
|
||||||
# نشانی کامل سایت (مثل https://aramesh.example) — برای sitemap و آدرس مطلق OG
|
# نشانی کامل سایت (مثل https://aramesh.example) — برای sitemap و آدرس مطلق OG
|
||||||
site_url: str = ""
|
site_url: str = ""
|
||||||
|
|||||||
@@ -3,6 +3,9 @@ import { API_URL } from '../config'
|
|||||||
|
|
||||||
const TOKEN_KEY = 'aramesh_admin_token'
|
const TOKEN_KEY = 'aramesh_admin_token'
|
||||||
|
|
||||||
|
/** سقف آپلود — هماندازهٔ media_max_upload_mb بکاند (تنظیمات) */
|
||||||
|
const MAX_UPLOAD_BYTES = 25 * 1024 * 1024
|
||||||
|
|
||||||
/** رویداد تغییر وضعیت ورود — لایههای دیگر (مثل نوار ادمین) با آن همگام میمانند */
|
/** رویداد تغییر وضعیت ورود — لایههای دیگر (مثل نوار ادمین) با آن همگام میمانند */
|
||||||
export const AUTH_CHANGE_EVENT = 'aramesh:auth-change'
|
export const AUTH_CHANGE_EVENT = 'aramesh:auth-change'
|
||||||
|
|
||||||
@@ -43,9 +46,11 @@ async function authFetch<T>(path: string, options: RequestInit = {}): Promise<T>
|
|||||||
const detail =
|
const detail =
|
||||||
typeof data?.detail === 'string'
|
typeof data?.detail === 'string'
|
||||||
? data.detail
|
? data.detail
|
||||||
: res.status === 409
|
: res.status === 413
|
||||||
? 'رکوردی با این مقدار تکراری وجود دارد'
|
? 'حجم فایل بیش از حد مجاز است (حداکثر ۲۵ مگابایت)'
|
||||||
: 'خطا در ذخیرهسازی — دوباره تلاش کنید'
|
: res.status === 409
|
||||||
|
? 'رکوردی با این مقدار تکراری وجود دارد'
|
||||||
|
: 'خطا در ذخیرهسازی — دوباره تلاش کنید'
|
||||||
throw new HttpError(res.status, detail)
|
throw new HttpError(res.status, detail)
|
||||||
}
|
}
|
||||||
return res.status === 204 ? (null as T) : ((await res.json()) as T)
|
return res.status === 204 ? (null as T) : ((await res.json()) as T)
|
||||||
@@ -88,6 +93,10 @@ export const adminApi = {
|
|||||||
authFetch<T[]>(`/api/admin/${resource}/reorder`, { method: 'POST', body: JSON.stringify({ ids }) }),
|
authFetch<T[]>(`/api/admin/${resource}/reorder`, { method: 'POST', body: JSON.stringify({ ids }) }),
|
||||||
|
|
||||||
upload: async (file: File, name?: string): Promise<{ url: string; key: string }> => {
|
upload: async (file: File, name?: string): Promise<{ url: string; key: string }> => {
|
||||||
|
// پیشچک سمت کاربر — خطای ۴۱۳ لبه/CDN بهصورت صفحه HTML میرسد و پیام خاص از دست میرود
|
||||||
|
if (file.size > MAX_UPLOAD_BYTES) {
|
||||||
|
throw new HttpError(413, 'حجم فایل بیش از ۲۵ مگابایت است — فایل را کوچکتر کنید')
|
||||||
|
}
|
||||||
const fd = new FormData()
|
const fd = new FormData()
|
||||||
fd.append('file', file)
|
fd.append('file', file)
|
||||||
if (name && name.trim()) fd.append('name', name.trim())
|
if (name && name.trim()) fd.append('name', name.trim())
|
||||||
|
|||||||
Reference in New Issue
Block a user