Просмотр исходного кода

fix: 只有发布动态和上传封面的视频 是500M 其余均为200M

sgc 3 недель назад
Родитель
Сommit
e6b38a6763

+ 34 - 8
src/api/upload.js

@@ -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 } : {};

+ 2 - 2
src/components/Upload/Imgs.vue

@@ -79,7 +79,7 @@ interface UploadFileProps {
   disabled?: boolean; // 是否禁用上传组件 ==> 非必传(默认为 false)
   limit?: number; // 最大图片上传数 ==> 非必传(默认为 5张)
   fileSize?: number; // 图片大小限制(MB)==> 非必传(默认 20M)
-  /** 视频大小限制(MB);含 video/* 的 fileType 时生效;默认 500(与 upload.js 一致) */
+  /** 视频大小限制(MB);含 video/* 的 fileType 时生效;默认 200 */
   videoFileSize?: number;
   fileType?: string[]; // 接受的 MIME(图片 + 可选视频)==> 非必传
   height?: string; // 组件高度 ==> 非必传(默认为 150px)
@@ -97,7 +97,7 @@ const props = withDefaults(defineProps<UploadFileProps>(), {
   disabled: false,
   limit: 5,
   fileSize: 20,
-  videoFileSize: 500,
+  videoFileSize: 200,
   fileType: () => ["image/jpeg", "image/png", "image/gif", "video/mp4", "video/webm", "video/quicktime", "video/ogg"],
   height: "150px",
   width: "150px",

+ 4 - 1
src/views/dynamicManagement/publishDynamic.vue

@@ -423,7 +423,10 @@ const uploadSingleFile = async (file: UploadFile) => {
 
   try {
     const isVideo = rawFile.type.startsWith("video/");
-    const urls = await uploadFilesToOss(rawFile, isVideo ? "video" : "image", { skipSimpleUploadOverlay: true });
+    const urls = await uploadFilesToOss(rawFile, isVideo ? "video" : "image", {
+      skipSimpleUploadOverlay: true,
+      maxVideoMb: DYNAMIC_VIDEO_MAX_MB
+    });
     const fileUrl = urls[0];
     if (!fileUrl) {
       ElMessage.error("上传失败,未返回文件地址");

+ 2 - 2
src/views/storeDecoration/add.vue

@@ -109,7 +109,7 @@
             </template>
             <el-icon><Plus /></el-icon>
           </el-upload>
-          <div class="upload-tip">支持图片或视频 ({{ fileList.length }}/9),图片单文件不超过 20MB,视频单文件不超过 500MB</div>
+          <div class="upload-tip">支持图片或视频 ({{ fileList.length }}/9),图片单文件不超过 20MB,视频单文件不超过 200MB</div>
         </el-form-item>
 
         <!-- 联系人 -->
@@ -648,7 +648,7 @@ const videoPreviewVisible = ref(false);
 const videoPreviewUrl = ref("");
 
 const ATTACHMENT_IMAGE_MAX_MB = 20;
-const ATTACHMENT_VIDEO_MAX_MB = 500;
+const ATTACHMENT_VIDEO_MAX_MB = 200;
 
 function isVideoUploadFile(file: UploadFile) {
   const resp = file.response as { isVideo?: boolean } | undefined;

+ 2 - 2
src/views/storeDecoration/personnelConfig/index.vue

@@ -278,7 +278,7 @@
               v-model:file-list="formData.backgroundImages"
               :limit="9"
               :file-size="20"
-              :video-file-size="500"
+              :video-file-size="200"
               :file-type="['image/jpeg', 'image/png', 'image/gif', 'image/webp', 'video/mp4']"
               :width="'150px'"
               :height="'150px'"
@@ -291,7 +291,7 @@
             >
               <template #tip>
                 <div class="upload-tip">
-                  上传图片或视频 ({{ formData.backgroundImages.length }}/9),图片单文件不超过 20M,视频单文件不超过 500M
+                  上传图片或视频 ({{ formData.backgroundImages.length }}/9),图片单文件不超过 20M,视频单文件不超过 200M
                 </div>
               </template>
             </UploadImgs>

+ 2 - 1
src/views/storeDecoration/storeCoverMap/index.vue

@@ -389,7 +389,8 @@ async function uploadOneToDraft(file: File, isVideo: boolean): Promise<DraftCove
   uploading.value = true;
   try {
     const urls = await uploadFilesToOss([file], isVideo ? "video" : "image", {
-      uploadSuccessMessage: null
+      uploadSuccessMessage: null,
+      maxVideoMb: VIDEO_MAX_MB
     });
     const url = urls[0];
     if (!url) throw new Error("上传成功但未返回地址");