|
|
@@ -17,11 +17,15 @@ const OSS_FINALIZE_PATH = "/upload/oss/finalize";
|
|
|
/** 浏览器默认可达;内网可配 VITE_OSS_UPLOAD_ENDPOINT=oss-cn-beijing-internal.aliyuncs.com */
|
|
|
const DEFAULT_OSS_UPLOAD_ENDPOINT = "oss-cn-beijing.aliyuncs.com";
|
|
|
|
|
|
-/** 商户 Web 端上传统一上限:图 20MB、视频 500MB(与门店封面、发布动态一致) */
|
|
|
+/** 商户 Web 端默认上限:图 20MB、视频 200MB */
|
|
|
const WEB_UPLOAD_IMAGE_MAX_BYTES = 20 * 1024 * 1024;
|
|
|
-const WEB_UPLOAD_VIDEO_MAX_BYTES = 500 * 1024 * 1024;
|
|
|
+const WEB_UPLOAD_VIDEO_MAX_BYTES = 200 * 1024 * 1024;
|
|
|
const WEB_UPLOAD_TIP_IMAGE = "图片建议不超过 20MB";
|
|
|
-const WEB_UPLOAD_TIP_VIDEO = "视频建议不超过 500MB";
|
|
|
+const WEB_UPLOAD_TIP_VIDEO = "视频建议不超过 200MB";
|
|
|
+
|
|
|
+/** 仅门店封面、发布动态等业务放宽至 500MB(通过 options.maxVideoMb 传入) */
|
|
|
+export const WEB_UPLOAD_VIDEO_MAX_MB_DEFAULT = 200;
|
|
|
+export const WEB_UPLOAD_VIDEO_MAX_MB_LARGE = 500;
|
|
|
|
|
|
/** STS / finalize 等 fetch 超时(毫秒) */
|
|
|
const OSS_STS_FETCH_TIMEOUT_MS = 120000;
|
|
|
@@ -112,19 +116,40 @@ function resolveOssFinalizeFetchTimeoutMs(file) {
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
+ * @param {{ maxVideoMb?: number }} [options]
|
|
|
+ * @returns {number}
|
|
|
+ */
|
|
|
+function resolveMaxVideoBytes(options = {}) {
|
|
|
+ const mb = Number(options.maxVideoMb);
|
|
|
+ if (Number.isFinite(mb) && mb > 0) {
|
|
|
+ return mb * 1024 * 1024;
|
|
|
+ }
|
|
|
+ return WEB_UPLOAD_VIDEO_MAX_BYTES;
|
|
|
+}
|
|
|
+
|
|
|
+/**
|
|
|
* @param {File[]} fileArr
|
|
|
* @param {string} [fileType] image | video
|
|
|
+ * @param {{ maxVideoMb?: number }} [options]
|
|
|
*/
|
|
|
-function assertWebUploadFilesWithinLimit(fileArr, fileType) {
|
|
|
+function assertWebUploadFilesWithinLimit(fileArr, fileType, options = {}) {
|
|
|
const kind = fileType === "video" ? "video" : fileType === "image" ? "image" : "";
|
|
|
+ const maxVideoBytes = resolveMaxVideoBytes(options);
|
|
|
+ const maxVideoMb = Math.round(maxVideoBytes / 1024 / 1024);
|
|
|
+ const videoTip =
|
|
|
+ maxVideoMb === WEB_UPLOAD_VIDEO_MAX_MB_LARGE
|
|
|
+ ? "视频建议不超过 500MB"
|
|
|
+ : maxVideoMb === WEB_UPLOAD_VIDEO_MAX_MB_DEFAULT
|
|
|
+ ? WEB_UPLOAD_TIP_VIDEO
|
|
|
+ : `视频建议不超过 ${maxVideoMb}MB`;
|
|
|
for (const file of fileArr) {
|
|
|
const size = Number(file?.size);
|
|
|
if (!Number.isFinite(size) || size <= 0) continue;
|
|
|
const mime = String(file?.type || "").toLowerCase();
|
|
|
const isVideo = kind === "video" || mime.startsWith("video/");
|
|
|
const isImage = kind === "image" || mime.startsWith("image/");
|
|
|
- if (isVideo && size > WEB_UPLOAD_VIDEO_MAX_BYTES) {
|
|
|
- throw new Error(WEB_UPLOAD_TIP_VIDEO);
|
|
|
+ if (isVideo && size > maxVideoBytes) {
|
|
|
+ throw new Error(videoTip);
|
|
|
}
|
|
|
if (isImage && size > WEB_UPLOAD_IMAGE_MAX_BYTES) {
|
|
|
throw new Error(WEB_UPLOAD_TIP_IMAGE);
|
|
|
@@ -1044,7 +1069,7 @@ async function postFileToSimpleUpload(file, fetchOptions = {}) {
|
|
|
* 上传文件:GET sts-token → OSS 直传 → POST finalize 审核
|
|
|
* @param {File | File[] | FileList} files 浏览器文件对象;支持单个 File、数组或 FileList
|
|
|
* @param {string} [_fileType] 保留参数,兼容旧调用(当前不参与分支)
|
|
|
- * @param {{ showLoading?: boolean; skipSimpleUploadOverlay?: boolean; skipFinalize?: boolean; uploadSuccessMessage?: string | null; uploadOverlayTitle?: string }} [options]
|
|
|
+ * @param {{ showLoading?: boolean; skipSimpleUploadOverlay?: boolean; skipFinalize?: boolean; maxVideoMb?: number; uploadSuccessMessage?: string | null; uploadOverlayTitle?: string }} [options]
|
|
|
* @returns {Promise<string[]>} 上传成功后的文件 URL 列表
|
|
|
*/
|
|
|
export async function uploadFilesToOss(files, _fileType, options = {}) {
|
|
|
@@ -1052,6 +1077,7 @@ export async function uploadFilesToOss(files, _fileType, options = {}) {
|
|
|
showLoading = false,
|
|
|
skipSimpleUploadOverlay = false,
|
|
|
skipFinalize = false,
|
|
|
+ maxVideoMb,
|
|
|
uploadSuccessMessage,
|
|
|
uploadOverlayTitle
|
|
|
} = options;
|
|
|
@@ -1067,7 +1093,7 @@ export async function uploadFilesToOss(files, _fileType, options = {}) {
|
|
|
}
|
|
|
|
|
|
try {
|
|
|
- assertWebUploadFilesWithinLimit(fileArr, _fileType);
|
|
|
+ assertWebUploadFilesWithinLimit(fileArr, _fileType, { maxVideoMb });
|
|
|
const runUpload = async signal => {
|
|
|
const uploadedUrls = [];
|
|
|
const fetchOpts = signal ? { signal } : {};
|