فهرست منبع

fix: 去掉更新头像功能

liangan 1 ماه پیش
والد
کامیت
6c7ec5e55b
7فایلهای تغییر یافته به همراه447 افزوده شده و 839 حذف شده
  1. 4 0
      manifest.config.ts
  2. 25 25
      package.json
  3. 315 231
      pnpm-lock.yaml
  4. 0 160
      src/hooks/useUpload.ts
  5. 6 2
      src/manifest.json
  6. 97 97
      src/pages/mine/myProfile.vue
  7. 0 324
      src/utils/uploadFile.ts

+ 4 - 0
manifest.config.ts

@@ -90,6 +90,10 @@ export default defineManifestConfig({
           '<uses-feature android:name="android.hardware.camera"/>',
           '<uses-permission android:name="android.permission.WRITE_SETTINGS"/>',
         ],
+        excludePermissions: [
+          '<uses-permission android:name="android.permission.READ_MEDIA_IMAGES"/>',
+          '<uses-permission android:name="android.permission.READ_MEDIA_VIDEO"/>',
+        ],
       },
       /* ios打包配置 */
       ios: {

+ 25 - 25
package.json

@@ -4,7 +4,7 @@
   "version": "3.2.0",
   "packageManager": "pnpm@10.10.0",
   "description": "BandhuBuy - APP",
-  "update-time": "2026-01-13",
+  "update-time": "2026-01-16",
   "engines": {
     "node": ">=18",
     "pnpm": ">=7.30"
@@ -67,22 +67,22 @@
   "dependencies": {
     "@alova/adapter-uniapp": "^2.0.14",
     "@alova/shared": "^1.3.1",
-    "@dcloudio/uni-app": "3.0.0-4060620250520001",
-    "@dcloudio/uni-app-harmony": "3.0.0-4060620250520001",
-    "@dcloudio/uni-app-plus": "3.0.0-4060620250520001",
-    "@dcloudio/uni-components": "3.0.0-4060620250520001",
-    "@dcloudio/uni-h5": "3.0.0-4060620250520001",
-    "@dcloudio/uni-mp-alipay": "3.0.0-4060620250520001",
-    "@dcloudio/uni-mp-baidu": "3.0.0-4060620250520001",
-    "@dcloudio/uni-mp-harmony": "3.0.0-4060620250520001",
-    "@dcloudio/uni-mp-jd": "3.0.0-4060620250520001",
-    "@dcloudio/uni-mp-kuaishou": "3.0.0-4060620250520001",
-    "@dcloudio/uni-mp-lark": "3.0.0-4060620250520001",
-    "@dcloudio/uni-mp-qq": "3.0.0-4060620250520001",
-    "@dcloudio/uni-mp-toutiao": "3.0.0-4060620250520001",
-    "@dcloudio/uni-mp-weixin": "3.0.0-4060620250520001",
-    "@dcloudio/uni-mp-xhs": "3.0.0-4060620250520001",
-    "@dcloudio/uni-quickapp-webview": "3.0.0-4060620250520001",
+    "@dcloudio/uni-app": "3.0.0-4080720251210001",
+    "@dcloudio/uni-app-harmony": "3.0.0-4080720251210001",
+    "@dcloudio/uni-app-plus": "3.0.0-4080720251210001",
+    "@dcloudio/uni-components": "3.0.0-4080720251210001",
+    "@dcloudio/uni-h5": "3.0.0-4080720251210001",
+    "@dcloudio/uni-mp-alipay": "3.0.0-4080720251210001",
+    "@dcloudio/uni-mp-baidu": "3.0.0-4080720251210001",
+    "@dcloudio/uni-mp-harmony": "3.0.0-4080720251210001",
+    "@dcloudio/uni-mp-jd": "3.0.0-4080720251210001",
+    "@dcloudio/uni-mp-kuaishou": "3.0.0-4080720251210001",
+    "@dcloudio/uni-mp-lark": "3.0.0-4080720251210001",
+    "@dcloudio/uni-mp-qq": "3.0.0-4080720251210001",
+    "@dcloudio/uni-mp-toutiao": "3.0.0-4080720251210001",
+    "@dcloudio/uni-mp-weixin": "3.0.0-4080720251210001",
+    "@dcloudio/uni-mp-xhs": "3.0.0-4080720251210001",
+    "@dcloudio/uni-quickapp-webview": "3.0.0-4080720251210001",
     "@tanstack/vue-query": "^5.62.16",
     "abortcontroller-polyfill": "^1.7.8",
     "alova": "^3.3.3",
@@ -91,7 +91,7 @@
     "pinia": "2.0.36",
     "pinia-plugin-persistedstate": "3.2.1",
     "tki-qrcode": "^0.1.6",
-    "vue": "^3.4.21",
+    "vue": "^3.5.17",
     "vue-i18n": "^9.1.9",
     "wot-design-uni": "^1.10.0",
     "z-paging": "2.8.7"
@@ -100,12 +100,12 @@
     "@antfu/eslint-config": "^4.15.0",
     "@commitlint/cli": "^19.8.1",
     "@commitlint/config-conventional": "^19.8.1",
-    "@dcloudio/types": "^3.4.8",
-    "@dcloudio/uni-automator": "3.0.0-4060620250520001",
-    "@dcloudio/uni-cli-shared": "3.0.0-4060620250520001",
-    "@dcloudio/uni-stacktracey": "3.0.0-4060620250520001",
-    "@dcloudio/uni-uts-v1": "3.0.0-4060620250520001",
-    "@dcloudio/vite-plugin-uni": "3.0.0-4060620250520001",
+    "@dcloudio/types": "^3.4.14",
+    "@dcloudio/uni-automator": "3.0.0-4080720251210001",
+    "@dcloudio/uni-cli-shared": "3.0.0-4080720251210001",
+    "@dcloudio/uni-stacktracey": "3.0.0-4080720251210001",
+    "@dcloudio/uni-uts-v1": "3.0.0-4080720251210001",
+    "@dcloudio/vite-plugin-uni": "3.0.0-4080720251210001",
     "@esbuild/darwin-arm64": "0.20.2",
     "@esbuild/darwin-x64": "0.20.2",
     "@iconify-json/carbon": "^1.2.4",
@@ -123,7 +123,7 @@
     "@uni-ku/bundle-optimizer": "^1.3.3",
     "@unocss/eslint-plugin": "^66.2.3",
     "@unocss/preset-legacy-compat": "^0.59.4",
-    "@vue/runtime-core": "^3.4.21",
+    "@vue/runtime-core": "^3.5.17",
     "@vue/tsconfig": "^0.1.3",
     "autoprefixer": "^10.4.20",
     "eslint": "^9.29.0",

تفاوت فایلی نمایش داده نمی شود زیرا این فایل بسیار بزرگ است
+ 315 - 231
pnpm-lock.yaml


+ 0 - 160
src/hooks/useUpload.ts

@@ -1,160 +0,0 @@
-import { ref } from 'vue'
-import { getEnvBaseUploadUrl } from '@/utils'
-
-const VITE_UPLOAD_BASEURL = `${getEnvBaseUploadUrl()}`
-
-type TfileType = 'image' | 'file'
-type TImage = 'png' | 'jpg' | 'jpeg' | 'webp' | '*'
-type TFile = 'doc' | 'docx' | 'ppt' | 'zip' | 'xls' | 'xlsx' | 'txt' | TImage
-
-interface TOptions<T extends TfileType> {
-  formData?: Record<string, any>
-  maxSize?: number
-  accept?: T extends 'image' ? TImage[] : TFile[]
-  fileType?: T
-  success?: (params: any) => void
-  error?: (err: any) => void
-}
-
-export default function useUpload<T extends TfileType>(options: TOptions<T> = {} as TOptions<T>) {
-  const {
-    formData = {},
-    maxSize = 5 * 1024 * 1024,
-    accept = ['*'],
-    fileType = 'image',
-    success,
-    error: onError,
-  } = options
-
-  const loading = ref(false)
-  const error = ref<Error | null>(null)
-  const data = ref<any>(null)
-
-  const handleFileChoose = ({ tempFilePath, size }: { tempFilePath: string, size: number }) => {
-    if (size > maxSize) {
-      uni.showToast({
-        title: `文件大小不能超过 ${maxSize / 1024 / 1024}MB`,
-        icon: 'none',
-      })
-      return
-    }
-
-    // const fileExtension = file?.tempFiles?.name?.split('.').pop()?.toLowerCase()
-    // const isTypeValid = accept.some((type) => type === '*' || type.toLowerCase() === fileExtension)
-
-    // if (!isTypeValid) {
-    //   uni.showToast({
-    //     title: `仅支持 ${accept.join(', ')} 格式的文件`,
-    //     icon: 'none',
-    //   })
-    //   return
-    // }
-
-    loading.value = true
-    uploadFile({
-      tempFilePath,
-      formData,
-      onSuccess: (res) => {
-        const { data: _data } = JSON.parse(res)
-        data.value = _data
-        // console.log('上传成功', res)
-        success?.(_data)
-      },
-      onError: (err) => {
-        error.value = err
-        onError?.(err)
-      },
-      onComplete: () => {
-        loading.value = false
-      },
-    })
-  }
-
-  const run = () => {
-    // 微信小程序从基础库 2.21.0 开始, wx.chooseImage 停止维护,请使用 uni.chooseMedia 代替。
-    // 微信小程序在2023年10月17日之后,使用本API需要配置隐私协议
-    const chooseFileOptions = {
-      count: 1,
-      success: (res: any) => {
-        console.log('File selected successfully:', res)
-        // 小程序中res:{errMsg: "chooseImage:ok", tempFiles: [{fileType: "image", size: 48976, tempFilePath: "http://tmp/5iG1WpIxTaJf3ece38692a337dc06df7eb69ecb49c6b.jpeg"}]}
-        // h5中res:{errMsg: "chooseImage:ok", tempFilePaths: "blob:http://localhost:9000/f74ab6b8-a14d-4cb6-a10d-fcf4511a0de5", tempFiles: [File]}
-        // h5的File有以下字段:{name: "girl.jpeg", size: 48976, type: "image/jpeg"}
-        // App中res:{errMsg: "chooseImage:ok", tempFilePaths: "file:///Users/feige/xxx/gallery/1522437259-compressed-IMG_0006.jpg", tempFiles: [File]}
-        // App的File有以下字段:{path: "file:///Users/feige/xxx/gallery/1522437259-compressed-IMG_0006.jpg", size: 48976}
-        let tempFilePath = ''
-        let size = 0
-        // #ifdef MP-WEIXIN
-        tempFilePath = res.tempFiles[0].tempFilePath
-        size = res.tempFiles[0].size
-        // #endif
-        // #ifndef MP-WEIXIN
-        tempFilePath = res.tempFilePaths[0]
-        size = res.tempFiles[0].size
-        // #endif
-        handleFileChoose({ tempFilePath, size })
-      },
-      fail: (err: any) => {
-        console.error('File selection failed:', err)
-        error.value = err
-        onError?.(err)
-      },
-    }
-
-    if (fileType === 'image') {
-      // #ifdef MP-WEIXIN
-      uni.chooseMedia({
-        ...chooseFileOptions,
-        mediaType: ['image'],
-      })
-      // #endif
-
-      // #ifndef MP-WEIXIN
-      uni.chooseImage(chooseFileOptions)
-      // #endif
-    }
-    else {
-      uni.chooseFile({
-        ...chooseFileOptions,
-        type: 'all',
-      })
-    }
-  }
-
-  return { loading, error, data, run }
-}
-
-async function uploadFile({
-  tempFilePath,
-  formData,
-  onSuccess,
-  onError,
-  onComplete,
-}: {
-  tempFilePath: string
-  formData: Record<string, any>
-  onSuccess: (data: any) => void
-  onError: (err: any) => void
-  onComplete: () => void
-}) {
-  uni.uploadFile({
-    url: VITE_UPLOAD_BASEURL,
-    filePath: tempFilePath,
-    name: 'file',
-    formData,
-    success: (uploadFileRes) => {
-      try {
-        const data = uploadFileRes.data
-        onSuccess(data)
-      }
-      catch (err) {
-        onError(err)
-      }
-    },
-    fail: (err) => {
-      console.error('Upload failed:', err)
-      onError(err)
-    },
-    complete: onComplete,
-  })
-}

+ 6 - 2
src/manifest.json

@@ -1,6 +1,6 @@
 {
   "name": "BandhuBuy",
-  "appid": "__UNI__BA8433E",
+  "appid": "__UNI__FDE416C",
   "description": "",
   "versionName": "1.0.1",
   "versionCode": "101",
@@ -45,6 +45,10 @@
           "armeabi-v7a",
           "arm64-v8a",
           "x86"
+        ],
+        "excludePermissions": [
+          "<uses-permission android:name=\"android.permission.READ_MEDIA_IMAGES\"/>",
+          "<uses-permission android:name=\"android.permission.READ_MEDIA_VIDEO\"/>"
         ]
       },
       "ios": {
@@ -117,7 +121,7 @@
         "MTPUSH_ISPRODUCTION_IOS": "",
         "MTPUSH_ADVERTISINGID_IOS": "",
         "MTPUSH_DEFAULTINIT_IOS": "",
-        "MTPUSH_APPKEY_ANDROID": "0655e889f95b4325a6712905",
+        "MTPUSH_APPKEY_ANDROID": "c95a2cb077c243ebbfa896f5",
         "MTPUSH_CHANNEL_ANDROID": "",
         "MTPUSH_PROCESS_ANDROID": "",
         "MTPUSH_XIAOMI_APPKEY": "",

+ 97 - 97
src/pages/mine/myProfile.vue

@@ -10,11 +10,11 @@
 </route>
 
 <script lang="ts" setup>
-import { updateInfo } from '@/api/login'
+// import { updateInfo } from '@/api/login'
 import { t } from '@/locale'
 import { useUserStore } from '@/store'
-import { getEnvBaseUploadUrl } from '@/utils'
-import { toast } from '@/utils/toast'
+// import { getEnvBaseUploadUrl } from '@/utils'
+// import { toast } from '@/utils/toast'
 
 defineOptions({
   name: 'MyProfile', // 我的资料
@@ -28,99 +28,99 @@ const userInfo = computed(() => {
 const uploading = ref(false)
 
 // 更新头像
-async function updateAvatar() {
-  try {
-    // 微信小程序从基础库 2.21.0 开始,wx.chooseImage 停止维护,请使用 uni.chooseMedia 代替。
-    const res: any = await new Promise((resolve, reject) => {
-      // #ifdef MP-WEIXIN
-      uni.chooseMedia({
-        count: 1,
-        mediaType: ['image'],
-        sourceType: ['album', 'camera'],
-        success: resolve,
-        fail: reject,
-      })
-      // #endif
-
-      // #ifndef MP-WEIXIN
-      uni.chooseImage({
-        count: 1,
-        sourceType: ['album', 'camera'],
-        success: resolve,
-        fail: reject,
-      })
-      // #endif
-    })
-
-    let tempFilePath = ''
-    let size = 0
-
-    // #ifdef MP-WEIXIN
-    if (!res.tempFiles || res.tempFiles.length === 0)
-      return
-    tempFilePath = res.tempFiles[0].tempFilePath
-    size = res.tempFiles[0].size
-    // #endif
-
-    // #ifndef MP-WEIXIN
-    if (!res.tempFilePaths || res.tempFilePaths.length === 0)
-      return
-    tempFilePath = res.tempFilePaths[0]
-    size = res.tempFiles?.[0]?.size || 0
-    // #endif
-
-    // 检查文件大小(限制为5MB)
-    const maxSize = 5 * 1024 * 1024
-    if (size > maxSize) {
-      toast.error(t('myProfile.upload.sizeLimit'))
-      return
-    }
-
-    uploading.value = true
-    await uni.showLoading({
-      title: t('myProfile.upload.uploading'),
-      mask: true,
-    })
-
-    // 上传图片
-    const uploadRes: any = await new Promise((resolve, reject) => {
-      uni.uploadFile({
-        url: `${getEnvBaseUploadUrl()}`,
-        filePath: tempFilePath,
-        name: 'file',
-        success: resolve,
-        fail: reject,
-      })
-    })
-    console.log('uploadRes', uploadRes)
-    // 解析上传结果
-    const uploadData = JSON.parse(uploadRes.data)
-    if (uploadData.code !== '200') {
-      throw new Error(uploadData.message)
-    }
-
-    const avatarUrl = uploadData.data
-    // 调用更新用户信息接口
-    await updateInfo({
-      headPic: avatarUrl,
-    })
-    // 更新本地用户信息
-    const newUserInfo = { ...userInfo.value, headPic: avatarUrl }
-    userStore.setUserInfo(newUserInfo)
-    userStore.getUserInfo()
-
-    uni.hideLoading()
-    toast.success(t('myProfile.upload.success'))
-  }
-  catch (error: any) {
-    uni.hideLoading()
-    console.error('Update avatar failed:', error)
-    toast.error(error.message || t('myProfile.upload.error'))
-  }
-  finally {
-    uploading.value = false
-  }
-}
+// async function updateAvatar() {
+//   try {
+//     // 微信小程序从基础库 2.21.0 开始,wx.chooseImage 停止维护,请使用 uni.chooseMedia 代替。
+//     const res: any = await new Promise((resolve, reject) => {
+//       // #ifdef MP-WEIXIN
+//       uni.chooseMedia({
+//         count: 1,
+//         mediaType: ['image'],
+//         sourceType: ['album', 'camera'],
+//         success: resolve,
+//         fail: reject,
+//       })
+//       // #endif
+
+//       // #ifndef MP-WEIXIN
+//       uni.chooseImage({
+//         count: 1,
+//         sourceType: ['album', 'camera'],
+//         success: resolve,
+//         fail: reject,
+//       })
+//       // #endif
+//     })
+
+//     let tempFilePath = ''
+//     let size = 0
+
+//     // #ifdef MP-WEIXIN
+//     if (!res.tempFiles || res.tempFiles.length === 0)
+//       return
+//     tempFilePath = res.tempFiles[0].tempFilePath
+//     size = res.tempFiles[0].size
+//     // #endif
+
+//     // #ifndef MP-WEIXIN
+//     if (!res.tempFilePaths || res.tempFilePaths.length === 0)
+//       return
+//     tempFilePath = res.tempFilePaths[0]
+//     size = res.tempFiles?.[0]?.size || 0
+//     // #endif
+
+//     // 检查文件大小(限制为5MB)
+//     const maxSize = 5 * 1024 * 1024
+//     if (size > maxSize) {
+//       toast.error(t('myProfile.upload.sizeLimit'))
+//       return
+//     }
+
+//     uploading.value = true
+//     await uni.showLoading({
+//       title: t('myProfile.upload.uploading'),
+//       mask: true,
+//     })
+
+//     // 上传图片
+//     const uploadRes: any = await new Promise((resolve, reject) => {
+//       uni.uploadFile({
+//         url: `${getEnvBaseUploadUrl()}`,
+//         filePath: tempFilePath,
+//         name: 'file',
+//         success: resolve,
+//         fail: reject,
+//       })
+//     })
+//     console.log('uploadRes', uploadRes)
+//     // 解析上传结果
+//     const uploadData = JSON.parse(uploadRes.data)
+//     if (uploadData.code !== '200') {
+//       throw new Error(uploadData.message)
+//     }
+
+//     const avatarUrl = uploadData.data
+//     // 调用更新用户信息接口
+//     await updateInfo({
+//       headPic: avatarUrl,
+//     })
+//     // 更新本地用户信息
+//     const newUserInfo = { ...userInfo.value, headPic: avatarUrl }
+//     userStore.setUserInfo(newUserInfo)
+//     userStore.getUserInfo()
+
+//     uni.hideLoading()
+//     toast.success(t('myProfile.upload.success'))
+//   }
+//   catch (error: any) {
+//     uni.hideLoading()
+//     console.error('Update avatar failed:', error)
+//     toast.error(error.message || t('myProfile.upload.error'))
+//   }
+//   finally {
+//     uploading.value = false
+//   }
+// }
 onLoad(() => {
   // 页面加载时的逻辑
   userStore.getUserInfo()
@@ -132,7 +132,7 @@ onLoad(() => {
     <view class="py-20rpx">
       <wd-cell-group custom-class="mb-20rpx" border>
         <wd-cell :title="t('myProfile.avatar')" center>
-          <view class="flex items-center justify-end" @click="updateAvatar">
+          <view class="flex items-center justify-end">
             <view class="relative flex items-center justify-center">
               <wd-img width="64rpx" height="64rpx" round :src="userInfo.headPic" />
               <view v-if="uploading" class="absolute inset-0 flex items-center justify-center rounded-full bg-black bg-opacity-50">

+ 0 - 324
src/utils/uploadFile.ts

@@ -1,324 +0,0 @@
-import { toast } from './toast'
-
-/**
- * 文件上传钩子函数使用示例
- * @example
- * const { loading, error, data, progress, run } = useUpload<IUploadResult>(
- *   uploadUrl,
- *   {},
- *   {
- *     maxSize: 5, // 最大5MB
- *     sourceType: ['album'], // 仅支持从相册选择
- *     onProgress: (p) => console.log(`上传进度:${p}%`),
- *     onSuccess: (res) => console.log('上传成功', res),
- *     onError: (err) => console.error('上传失败', err),
- *   },
- * )
- */
-
-/**
- * 上传文件的URL配置
- */
-export const uploadFileUrl = {
-  /** 用户头像上传地址 */
-  USER_AVATAR: `${import.meta.env.VITE_SERVER_BASEURL}/user/avatar`,
-}
-
-/**
- * 通用文件上传函数(支持直接传入文件路径)
- * @param url 上传地址
- * @param filePath 本地文件路径
- * @param formData 额外表单数据
- * @param options 上传选项
- */
-export function useFileUpload<T = string>(url: string, filePath: string, formData: Record<string, any> = {}, options: Omit<UploadOptions, 'sourceType' | 'sizeType' | 'count'> = {}) {
-  return useUpload<T>(
-    url,
-    formData,
-    {
-      ...options,
-      sourceType: ['album'],
-      sizeType: ['original'],
-    },
-    filePath,
-  )
-}
-
-export interface UploadOptions {
-  /** 最大可选择的图片数量,默认为1 */
-  count?: number
-  /** 所选的图片的尺寸,original-原图,compressed-压缩图 */
-  sizeType?: Array<'original' | 'compressed'>
-  /** 选择图片的来源,album-相册,camera-相机 */
-  sourceType?: Array<'album' | 'camera'>
-  /** 文件大小限制,单位:MB */
-  maxSize?: number //
-  /** 上传进度回调函数 */
-  onProgress?: (progress: number) => void
-  /** 上传成功回调函数 */
-  onSuccess?: (res: Record<string, any>) => void
-  /** 上传失败回调函数 */
-  onError?: (err: Error | UniApp.GeneralCallbackResult) => void
-  /** 上传完成回调函数(无论成功失败) */
-  onComplete?: () => void
-}
-
-/**
- * 文件上传钩子函数
- * @template T 上传成功后返回的数据类型
- * @param url 上传地址
- * @param formData 额外的表单数据
- * @param options 上传选项
- * @returns 上传状态和控制对象
- */
-export function useUpload<T = string>(url: string, formData: Record<string, any> = {}, options: UploadOptions = {},
-  /** 直接传入文件路径,跳过选择器 */
-  directFilePath?: string) {
-  /** 上传中状态 */
-  const loading = ref(false)
-  /** 上传错误状态 */
-  const error = ref(false)
-  /** 上传成功后的响应数据 */
-  const data = ref<T>()
-  /** 上传进度(0-100) */
-  const progress = ref(0)
-
-  /** 解构上传选项,设置默认值 */
-  const {
-    /** 最大可选择的图片数量 */
-    count = 1,
-    /** 所选的图片的尺寸 */
-    sizeType = ['original', 'compressed'],
-    /** 选择图片的来源 */
-    sourceType = ['album', 'camera'],
-    /** 文件大小限制(MB) */
-    maxSize = 10,
-    /** 进度回调 */
-    onProgress,
-    /** 成功回调 */
-    onSuccess,
-    /** 失败回调 */
-    onError,
-    /** 完成回调 */
-    onComplete,
-  } = options
-
-  /**
-   * 检查文件大小是否超过限制
-   * @param size 文件大小(字节)
-   * @returns 是否通过检查
-   */
-  const checkFileSize = (size: number) => {
-    const sizeInMB = size / 1024 / 1024
-    if (sizeInMB > maxSize) {
-      toast.warning(`文件大小不能超过${maxSize}MB`)
-      return false
-    }
-    return true
-  }
-  /**
-   * 触发文件选择和上传
-   * 根据平台使用不同的选择器:
-   * - 微信小程序使用 chooseMedia
-   * - 其他平台使用 chooseImage
-   */
-  const run = () => {
-    if (directFilePath) {
-      // 直接使用传入的文件路径
-      loading.value = true
-      progress.value = 0
-      uploadFile<T>({
-        url,
-        tempFilePath: directFilePath,
-        formData,
-        data,
-        error,
-        loading,
-        progress,
-        onProgress,
-        onSuccess,
-        onError,
-        onComplete,
-      })
-      return
-    }
-
-    // #ifdef MP-WEIXIN
-    // 微信小程序环境下使用 chooseMedia API
-    uni.chooseMedia({
-      count,
-      mediaType: ['image'], // 仅支持图片类型
-      sourceType,
-      success: (res) => {
-        const file = res.tempFiles[0]
-        // 检查文件大小是否符合限制
-        if (!checkFileSize(file.size))
-          return
-
-        // 开始上传
-        loading.value = true
-        progress.value = 0
-        uploadFile<T>({
-          url,
-          tempFilePath: file.tempFilePath,
-          formData,
-          data,
-          error,
-          loading,
-          progress,
-          onProgress,
-          onSuccess,
-          onError,
-          onComplete,
-        })
-      },
-      fail: (err) => {
-        console.error('选择媒体文件失败:', err)
-        error.value = true
-        onError?.(err)
-      },
-    })
-    // #endif
-
-    // #ifndef MP-WEIXIN
-    // 非微信小程序环境下使用 chooseImage API
-    uni.chooseImage({
-      count,
-      sizeType,
-      sourceType,
-      success: (res) => {
-        console.log('选择图片成功:', res)
-
-        // 开始上传
-        loading.value = true
-        progress.value = 0
-        uploadFile<T>({
-          url,
-          tempFilePath: res.tempFilePaths[0],
-          formData,
-          data,
-          error,
-          loading,
-          progress,
-          onProgress,
-          onSuccess,
-          onError,
-          onComplete,
-        })
-      },
-      fail: (err) => {
-        console.error('选择图片失败:', err)
-        error.value = true
-        onError?.(err)
-      },
-    })
-    // #endif
-  }
-
-  return { loading, error, data, progress, run }
-}
-
-/**
- * 文件上传选项接口
- * @template T 上传成功后返回的数据类型
- */
-interface UploadFileOptions<T> {
-  /** 上传地址 */
-  url: string
-  /** 临时文件路径 */
-  tempFilePath: string
-  /** 额外的表单数据 */
-  formData: Record<string, any>
-  /** 上传成功后的响应数据 */
-  data: Ref<T | undefined>
-  /** 上传错误状态 */
-  error: Ref<boolean>
-  /** 上传中状态 */
-  loading: Ref<boolean>
-  /** 上传进度(0-100) */
-  progress: Ref<number>
-  /** 上传进度回调 */
-  onProgress?: (progress: number) => void
-  /** 上传成功回调 */
-  onSuccess?: (res: Record<string, any>) => void
-  /** 上传失败回调 */
-  onError?: (err: Error | UniApp.GeneralCallbackResult) => void
-  /** 上传完成回调 */
-  onComplete?: () => void
-}
-
-/**
- * 执行文件上传
- * @template T 上传成功后返回的数据类型
- * @param options 上传选项
- */
-function uploadFile<T>({
-  url,
-  tempFilePath,
-  formData,
-  data,
-  error,
-  loading,
-  progress,
-  onProgress,
-  onSuccess,
-  onError,
-  onComplete,
-}: UploadFileOptions<T>) {
-  try {
-    // 创建上传任务
-    const uploadTask = uni.uploadFile({
-      url,
-      filePath: tempFilePath,
-      name: 'file', // 文件对应的 key
-      formData,
-      header: {
-        // H5环境下不需要手动设置Content-Type,让浏览器自动处理multipart格式
-        // #ifndef H5
-        'Content-Type': 'multipart/form-data',
-        // #endif
-      },
-      // 确保文件名称合法
-      success: (uploadFileRes) => {
-        console.log('上传文件成功:', uploadFileRes)
-        try {
-          // 解析响应数据
-          const { data: _data } = JSON.parse(uploadFileRes.data)
-          // 上传成功
-          data.value = _data as T
-          onSuccess?.(_data)
-        }
-        catch (err) {
-          // 响应解析错误
-          console.error('解析上传响应失败:', err)
-          error.value = true
-          onError?.(new Error('上传响应解析失败'))
-        }
-      },
-      fail: (err) => {
-        // 上传请求失败
-        console.error('上传文件失败:', err)
-        error.value = true
-        onError?.(err)
-      },
-      complete: () => {
-        // 无论成功失败都执行
-        loading.value = false
-        onComplete?.()
-      },
-    })
-
-    // 监听上传进度
-    uploadTask.onProgressUpdate((res) => {
-      progress.value = res.progress
-      onProgress?.(res.progress)
-    })
-  }
-  catch (err) {
-    // 创建上传任务失败
-    console.error('创建上传任务失败:', err)
-    error.value = true
-    loading.value = false
-    onError?.(new Error('创建上传任务失败'))
-  }
-}

برخی فایل ها در این مقایسه diff نمایش داده نمی شوند زیرا تعداد فایل ها بسیار زیاد است