hookehuyr

feat(上传): 实现视频文件上传功能并添加文件校验

添加 `browser-md5-file` 依赖,实现视频文件上传功能,包括文件校验、上传进度跟踪及七牛云上传逻辑。移除不再使用的 `@uppy` 相关依赖。
......@@ -9,13 +9,10 @@
"version": "0.0.0",
"dependencies": {
"@heroicons/vue": "^2.2.0",
"@uppy/core": "^4.4.3",
"@uppy/dashboard": "^4.3.2",
"@uppy/vue": "^2.1.1",
"@uppy/xhr-upload": "^4.3.3",
"@vant/touch-emulator": "^1.4.0",
"@vant/use": "^1.6.0",
"@videojs-player/vue": "^1.0.0",
"browser-md5-file": "^1.1.1",
"dayjs": "^1.11.13",
"swiper": "^11.2.6",
"vant": "^4.9.18",
......@@ -1196,22 +1193,12 @@
"win32"
]
},
"node_modules/@transloadit/prettier-bytes": {
"version": "0.3.5",
"resolved": "https://registry.npmjs.org/@transloadit/prettier-bytes/-/prettier-bytes-0.3.5.tgz",
"integrity": "sha512-xF4A3d/ZyX2LJWeQZREZQw+qFX4TGQ8bGVP97OLRt6sPO6T0TNHBFTuRHOJh7RNmYOBmQ9MHxpolD9bXihpuVA=="
},
"node_modules/@types/estree": {
"version": "1.0.6",
"resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.6.tgz",
"integrity": "sha512-AYnb1nQyY49te+VRAVgmzfcgjYS91mY5P0TKUDCLEM+gNnA+3T6rWITXRLYCpahpqSQbN5cE+gHpnPyXjHWxcw==",
"dev": true
},
"node_modules/@types/retry": {
"version": "0.12.2",
"resolved": "https://registry.npmjs.org/@types/retry/-/retry-0.12.2.tgz",
"integrity": "sha512-XISRgDJ2Tc5q4TRqvgJtzsRkFYNJzZrhTdtMoGVBttwzzQJkPnS3WWTFc7kuDRoPtPakl+T+OfdEUjYJj7Jbow=="
},
"node_modules/@types/video.js": {
"version": "7.3.58",
"resolved": "https://registry.npmjs.org/@types/video.js/-/video.js-7.3.58.tgz",
......@@ -1224,220 +1211,6 @@
"integrity": "sha512-oIQLCGWtcFZy2JW77j9k8nHzAOpqMHLQejDA48XXMWH6tjCQHz5RCFz1bzsmROyL6PUm+LLnUiI4BCn221inxA==",
"dev": true
},
"node_modules/@uppy/companion-client": {
"version": "4.4.1",
"resolved": "https://registry.npmjs.org/@uppy/companion-client/-/companion-client-4.4.1.tgz",
"integrity": "sha512-ardMacShsfzaIbqHEH48YlpzWZkBj1qhAj0Dvn3r31p9d0HA5xFUvAdLYrZ6ezKvZ0RcDbf0SB5qCrQMkjscXQ==",
"dependencies": {
"@uppy/utils": "^6.1.1",
"namespace-emitter": "^2.0.1",
"p-retry": "^6.1.0"
},
"peerDependencies": {
"@uppy/core": "^4.4.1"
}
},
"node_modules/@uppy/core": {
"version": "4.4.3",
"resolved": "https://registry.npmjs.org/@uppy/core/-/core-4.4.3.tgz",
"integrity": "sha512-Ma/v9+u0xYoxFcTajBpe0TUHI0Vjw2IKgB0AUNevhgFsBRgA03nL5n8Fac8TrC0QjPkYu7h0n2xf2EgzvyxAQA==",
"dependencies": {
"@transloadit/prettier-bytes": "^0.3.4",
"@uppy/store-default": "^4.2.0",
"@uppy/utils": "^6.1.2",
"lodash": "^4.17.21",
"mime-match": "^1.0.2",
"namespace-emitter": "^2.0.1",
"nanoid": "^5.0.9",
"preact": "^10.5.13"
}
},
"node_modules/@uppy/core/node_modules/nanoid": {
"version": "5.1.5",
"resolved": "https://registry.npmjs.org/nanoid/-/nanoid-5.1.5.tgz",
"integrity": "sha512-Ir/+ZpE9fDsNH0hQ3C68uyThDXzYcim2EqcZ8zn8Chtt1iylPT9xXJB0kPCnqzgcEGikO9RxSrh63MsmVCU7Fw==",
"funding": [
{
"type": "github",
"url": "https://github.com/sponsors/ai"
}
],
"bin": {
"nanoid": "bin/nanoid.js"
},
"engines": {
"node": "^18 || >=20"
}
},
"node_modules/@uppy/dashboard": {
"version": "4.3.2",
"resolved": "https://registry.npmjs.org/@uppy/dashboard/-/dashboard-4.3.2.tgz",
"integrity": "sha512-6cikgcY/TMy+Fq/v03QI1BNocfm1kOxii3kuUaxnz1SFGeuZ/55+C7KKL7SP/IdeoVwH7KV+550HThT0uwIQEw==",
"dependencies": {
"@transloadit/prettier-bytes": "^0.3.4",
"@uppy/informer": "^4.2.1",
"@uppy/provider-views": "^4.4.2",
"@uppy/status-bar": "^4.1.2",
"@uppy/thumbnail-generator": "^4.1.1",
"@uppy/utils": "^6.1.2",
"classnames": "^2.2.6",
"lodash": "^4.17.21",
"memoize-one": "^6.0.0",
"nanoid": "^5.0.9",
"preact": "^10.5.13",
"shallow-equal": "^3.0.0"
},
"peerDependencies": {
"@uppy/core": "^4.4.2"
}
},
"node_modules/@uppy/dashboard/node_modules/nanoid": {
"version": "5.1.5",
"resolved": "https://registry.npmjs.org/nanoid/-/nanoid-5.1.5.tgz",
"integrity": "sha512-Ir/+ZpE9fDsNH0hQ3C68uyThDXzYcim2EqcZ8zn8Chtt1iylPT9xXJB0kPCnqzgcEGikO9RxSrh63MsmVCU7Fw==",
"funding": [
{
"type": "github",
"url": "https://github.com/sponsors/ai"
}
],
"bin": {
"nanoid": "bin/nanoid.js"
},
"engines": {
"node": "^18 || >=20"
}
},
"node_modules/@uppy/informer": {
"version": "4.2.1",
"resolved": "https://registry.npmjs.org/@uppy/informer/-/informer-4.2.1.tgz",
"integrity": "sha512-0en8Py47pl6RMDrgUfqFoF807W5kK5AKVJNT1SkTsLiGg5anmTIMuvmNG3k6LN4cn9P/rKyEHSdGcoBBUj9u7Q==",
"dependencies": {
"@uppy/utils": "^6.1.1",
"preact": "^10.5.13"
},
"peerDependencies": {
"@uppy/core": "^4.4.1"
}
},
"node_modules/@uppy/provider-views": {
"version": "4.4.2",
"resolved": "https://registry.npmjs.org/@uppy/provider-views/-/provider-views-4.4.2.tgz",
"integrity": "sha512-YGrPJuydrksmMCjvo7Ty7/lDLNo/Y8zsOgWgWmVbXB0V5aRvqY49LeKY8HDlOXclKmn6dl5CeQFf7p46txRNGQ==",
"dependencies": {
"@uppy/utils": "^6.1.2",
"classnames": "^2.2.6",
"nanoid": "^5.0.9",
"p-queue": "^8.0.0",
"preact": "^10.5.13"
},
"peerDependencies": {
"@uppy/core": "^4.4.2"
}
},
"node_modules/@uppy/provider-views/node_modules/nanoid": {
"version": "5.1.5",
"resolved": "https://registry.npmjs.org/nanoid/-/nanoid-5.1.5.tgz",
"integrity": "sha512-Ir/+ZpE9fDsNH0hQ3C68uyThDXzYcim2EqcZ8zn8Chtt1iylPT9xXJB0kPCnqzgcEGikO9RxSrh63MsmVCU7Fw==",
"funding": [
{
"type": "github",
"url": "https://github.com/sponsors/ai"
}
],
"bin": {
"nanoid": "bin/nanoid.js"
},
"engines": {
"node": "^18 || >=20"
}
},
"node_modules/@uppy/status-bar": {
"version": "4.1.2",
"resolved": "https://registry.npmjs.org/@uppy/status-bar/-/status-bar-4.1.2.tgz",
"integrity": "sha512-Z2fDXItoE940uMo3kwdDo4ZFPjTk5GY6y/C/G5+tSl6nL/IaDtWo5iVbAKHIH4s9SIRwCBgllEhxbmEPhuK7eA==",
"dependencies": {
"@transloadit/prettier-bytes": "^0.3.4",
"@uppy/utils": "^6.1.2",
"classnames": "^2.2.6",
"preact": "^10.5.13"
},
"peerDependencies": {
"@uppy/core": "^4.4.2"
}
},
"node_modules/@uppy/store-default": {
"version": "4.2.0",
"resolved": "https://registry.npmjs.org/@uppy/store-default/-/store-default-4.2.0.tgz",
"integrity": "sha512-PieFVa8yTvRHIqsNKfpO/yaJw5Ae/hT7uT58ryw7gvCBY5bHrNWxH5N0XFe8PFHMpLpLn8v3UXGx9ib9QkB6+Q=="
},
"node_modules/@uppy/thumbnail-generator": {
"version": "4.1.1",
"resolved": "https://registry.npmjs.org/@uppy/thumbnail-generator/-/thumbnail-generator-4.1.1.tgz",
"integrity": "sha512-65znkGNgVTbVte51IKOhgxOpHGSwYj9Qik2jF2ZBocMbhBY4gPkWFwqMrKQBfddA9KbUa4jVe1psxhAQTzYgiA==",
"dependencies": {
"@uppy/utils": "^6.1.1",
"exifr": "^7.0.0"
},
"peerDependencies": {
"@uppy/core": "^4.4.1"
}
},
"node_modules/@uppy/utils": {
"version": "6.1.2",
"resolved": "https://registry.npmjs.org/@uppy/utils/-/utils-6.1.2.tgz",
"integrity": "sha512-PCrw6v51M6p3hlrlB2INmcocen4Dyjun1SobjVZRBkg4wutQE8ihZfSrH5ZE8UXFelufhtO16wlaZMi0EHk84w==",
"dependencies": {
"lodash": "^4.17.21",
"preact": "^10.5.13"
}
},
"node_modules/@uppy/vue": {
"version": "2.1.1",
"resolved": "https://registry.npmjs.org/@uppy/vue/-/vue-2.1.1.tgz",
"integrity": "sha512-svmkqO3QObuPOyVE0ttTFcwjrjzsxiDGgqau0tuV27FNO0/50GGzrJcBOy+P7kkZhQ23qEBltScQzOc75s7uUQ==",
"dependencies": {
"shallow-equal": "^3.0.0"
},
"peerDependencies": {
"@uppy/core": "^4.4.1",
"@uppy/dashboard": "^4.3.1",
"@uppy/drag-drop": "^4.1.1",
"@uppy/file-input": "^4.1.1",
"@uppy/progress-bar": "^4.2.1",
"@uppy/status-bar": "^4.1.1",
"vue": ">=3.0.0"
},
"peerDependenciesMeta": {
"@uppy/dashboard": {
"optional": true
},
"@uppy/drag-drop": {
"optional": true
},
"@uppy/file-input": {
"optional": true
},
"@uppy/progress-bar": {
"optional": true
},
"@uppy/status-bar": {
"optional": true
}
}
},
"node_modules/@uppy/xhr-upload": {
"version": "4.3.3",
"resolved": "https://registry.npmjs.org/@uppy/xhr-upload/-/xhr-upload-4.3.3.tgz",
"integrity": "sha512-I7RVppwTvLRlVfoW5piMxcZKzWF42E6CwYFQ42d2LzizrkG4tVLQkQrTZlw85za3nhcSrX3o/d1eNx3pzLmsdw==",
"dependencies": {
"@uppy/companion-client": "^4.4.1",
"@uppy/utils": "^6.1.2"
},
"peerDependencies": {
"@uppy/core": "^4.4.2"
}
},
"node_modules/@vant/popperjs": {
"version": "1.3.0",
"resolved": "https://registry.npmjs.org/@vant/popperjs/-/popperjs-1.3.0.tgz",
......@@ -1900,6 +1673,14 @@
"node": ">=8"
}
},
"node_modules/browser-md5-file": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/browser-md5-file/-/browser-md5-file-1.1.1.tgz",
"integrity": "sha512-9h2UViTtZPhBa7oHvp5mb7MvJaX5OKEPUsplDwJ800OIV+In7BOR3RXOMB78obn2iQVIiS3WkVLhG7Zu1EMwbw==",
"dependencies": {
"spark-md5": "^2.0.2"
}
},
"node_modules/browserslist": {
"version": "4.24.4",
"resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.24.4.tgz",
......@@ -2026,11 +1807,6 @@
"node": ">= 6"
}
},
"node_modules/classnames": {
"version": "2.5.1",
"resolved": "https://registry.npmjs.org/classnames/-/classnames-2.5.1.tgz",
"integrity": "sha512-saHYOzhIQs6wy2sVxTM6bUDsQO4F50V9RQ22qBpEdCW+I+/Wmke2HOl6lS6dTpdxVhb88/I6+Hs+438c3lfUow=="
},
"node_modules/color-convert": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
......@@ -2336,16 +2112,6 @@
"resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-2.0.2.tgz",
"integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w=="
},
"node_modules/eventemitter3": {
"version": "5.0.1",
"resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-5.0.1.tgz",
"integrity": "sha512-GWkBvjiSZK87ELrYOSESUYeVIc9mvLLf/nXalMOS5dYrgZq9o5OVkbZAVM06CVxYsCwH9BDZFPlQTlPA1j4ahA=="
},
"node_modules/exifr": {
"version": "7.1.3",
"resolved": "https://registry.npmjs.org/exifr/-/exifr-7.1.3.tgz",
"integrity": "sha512-g/aje2noHivrRSLbAUtBPWFbxKdKhgj/xr1vATDdUXPOFYJlQ62Ft0oy+72V6XLIpDJfHs6gXLbBLAolqOXYRw=="
},
"node_modules/exsolve": {
"version": "1.0.4",
"resolved": "https://registry.npmjs.org/exsolve/-/exsolve-1.0.4.tgz",
......@@ -2702,17 +2468,6 @@
"node": ">=0.10.0"
}
},
"node_modules/is-network-error": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/is-network-error/-/is-network-error-1.1.0.tgz",
"integrity": "sha512-tUdRRAnhT+OtCZR/LxZelH/C7QtjtFrTu5tXCA8pl55eTUElUHT+GPYV8MBMBvea/j+NxQqVt3LbWMRir7Gx9g==",
"engines": {
"node": ">=16"
},
"funding": {
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/is-number": {
"version": "7.0.0",
"resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz",
......@@ -2822,11 +2577,6 @@
"url": "https://github.com/sponsors/antfu"
}
},
"node_modules/lodash": {
"version": "4.17.21",
"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz",
"integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg=="
},
"node_modules/lru-cache": {
"version": "5.1.1",
"resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz",
......@@ -2863,11 +2613,6 @@
"node": ">= 0.4"
}
},
"node_modules/memoize-one": {
"version": "6.0.0",
"resolved": "https://registry.npmjs.org/memoize-one/-/memoize-one-6.0.0.tgz",
"integrity": "sha512-rkpe71W0N0c0Xz6QD0eJETuWAJGnJ9afsl1srmwPrI+yBCkge5EycXXbYRyvL29zZVUWQCY7InPRCv3GDXuZNw=="
},
"node_modules/merge2": {
"version": "1.4.1",
"resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz",
......@@ -2899,14 +2644,6 @@
"node": ">= 0.6"
}
},
"node_modules/mime-match": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/mime-match/-/mime-match-1.0.2.tgz",
"integrity": "sha512-VXp/ugGDVh3eCLOBCiHZMYWQaTNUHv2IJrut+yXA6+JbLPXHglHwfS/5A5L0ll+jkCY7fIzRJcH6OIunF+c6Cg==",
"dependencies": {
"wildcard": "^1.1.0"
}
},
"node_modules/mime-types": {
"version": "2.1.35",
"resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz",
......@@ -3032,11 +2769,6 @@
"thenify-all": "^1.0.0"
}
},
"node_modules/namespace-emitter": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/namespace-emitter/-/namespace-emitter-2.0.1.tgz",
"integrity": "sha512-N/sMKHniSDJBjfrkbS/tpkPj4RAbvW3mr8UAzvlMHyun93XEm83IAvhWtJVHo+RHn/oO8Job5YN4b+wRjSVp5g=="
},
"node_modules/nanoid": {
"version": "3.3.11",
"resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.11.tgz",
......@@ -3108,48 +2840,6 @@
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/p-queue": {
"version": "8.1.0",
"resolved": "https://registry.npmjs.org/p-queue/-/p-queue-8.1.0.tgz",
"integrity": "sha512-mxLDbbGIBEXTJL0zEx8JIylaj3xQ7Z/7eEVjcF9fJX4DBiH9oqe+oahYnlKKxm0Ci9TlWTyhSHgygxMxjIB2jw==",
"dependencies": {
"eventemitter3": "^5.0.1",
"p-timeout": "^6.1.2"
},
"engines": {
"node": ">=18"
},
"funding": {
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/p-retry": {
"version": "6.2.1",
"resolved": "https://registry.npmjs.org/p-retry/-/p-retry-6.2.1.tgz",
"integrity": "sha512-hEt02O4hUct5wtwg4H4KcWgDdm+l1bOaEy/hWzd8xtXB9BqxTWBBhb+2ImAtH4Cv4rPjV76xN3Zumqk3k3AhhQ==",
"dependencies": {
"@types/retry": "0.12.2",
"is-network-error": "^1.0.0",
"retry": "^0.13.1"
},
"engines": {
"node": ">=16.17"
},
"funding": {
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/p-timeout": {
"version": "6.1.4",
"resolved": "https://registry.npmjs.org/p-timeout/-/p-timeout-6.1.4.tgz",
"integrity": "sha512-MyIV3ZA/PmyBN/ud8vV9XzwTrNtR4jFrObymZYnZqMmW0zA8Z17vnT0rBgFE/TlohB+YCHqXMgZzb3Csp49vqg==",
"engines": {
"node": ">=14.16"
},
"funding": {
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/package-json-from-dist": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/package-json-from-dist/-/package-json-from-dist-1.0.1.tgz",
......@@ -3398,15 +3088,6 @@
"integrity": "sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==",
"dev": true
},
"node_modules/preact": {
"version": "10.26.4",
"resolved": "https://registry.npmjs.org/preact/-/preact-10.26.4.tgz",
"integrity": "sha512-KJhO7LBFTjP71d83trW+Ilnjbo+ySsaAgCfXOXUlmGzJ4ygYPWmysm77yg4emwfmoz3b22yvH5IsVFHbhUaH5w==",
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/preact"
}
},
"node_modules/process": {
"version": "0.11.10",
"resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz",
......@@ -3518,14 +3199,6 @@
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/retry": {
"version": "0.13.1",
"resolved": "https://registry.npmjs.org/retry/-/retry-0.13.1.tgz",
"integrity": "sha512-XQBQ3I8W1Cge0Seh+6gjj03LbmRFWuoszgK9ooCpwYIrhhoO80pfq4cUkU5DkknwfOfFteRwlZ56PYOGYyFWdg==",
"engines": {
"node": ">= 4"
}
},
"node_modules/reusify": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/reusify/-/reusify-1.1.0.tgz",
......@@ -3628,11 +3301,6 @@
"semver": "bin/semver.js"
}
},
"node_modules/shallow-equal": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/shallow-equal/-/shallow-equal-3.1.0.tgz",
"integrity": "sha512-pfVOw8QZIXpMbhBWvzBISicvToTiM5WBF1EeAUZDDSb5Dt29yl4AYbyywbJFSEsRUMr7gJaxqCdr4L3tQf9wVg=="
},
"node_modules/shebang-command": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz",
......@@ -3746,6 +3414,11 @@
"node": ">=0.10.0"
}
},
"node_modules/spark-md5": {
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/spark-md5/-/spark-md5-2.0.2.tgz",
"integrity": "sha512-9WfT+FYBEvlrOOBEs484/zmbtSX4BlGjzXih1qIEWA1yhHbcqgcMHkiwXoWk2Sq1aJjLpcs6ZKV7JxrDNjIlNg=="
},
"node_modules/string-width": {
"version": "5.1.2",
"resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz",
......@@ -4448,11 +4121,6 @@
"node": ">= 8"
}
},
"node_modules/wildcard": {
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/wildcard/-/wildcard-1.1.2.tgz",
"integrity": "sha512-DXukZJxpHA8LuotRwL0pP1+rS6CS7FF2qStDDE1C7DDg2rLud2PXRMuEDYIPhgEezwnlHNL4c+N6MfMTjCGTng=="
},
"node_modules/wrap-ansi": {
"version": "8.1.0",
"resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz",
......
......@@ -19,6 +19,7 @@
"@vant/touch-emulator": "^1.4.0",
"@vant/use": "^1.6.0",
"@videojs-player/vue": "^1.0.0",
"browser-md5-file": "^1.1.1",
"dayjs": "^1.11.13",
"swiper": "^11.2.6",
"vant": "^4.9.18",
......
......@@ -41,7 +41,7 @@
import { ref, defineProps, defineEmits, watch } from 'vue';
import { showToast } from 'vant';
import VideoPlayer from '@/components/ui/VideoPlayer.vue';
import { v4 as uuidv4 } from 'uuid';
import { uploadFile, validateFile } from '@/utils/upload';
const props = defineProps({
modelValue: {
......@@ -76,8 +76,9 @@ const uploadProgress = ref(0);
const maxSize = 100 * 1024 * 1024; // 100MB
const beforeRead = (file) => {
if (!file.type.includes('video/')) {
showToast('请上传视频文件');
const validation = validateFile(file);
if (!validation.valid) {
showToast(validation.message);
return false;
}
return true;
......@@ -90,28 +91,22 @@ const afterRead = async (file) => {
videoName.value = '';
uploadProgress.value = 0;
const formData = new FormData();
formData.append('file', file.file);
try {
// 模拟上传进度
const timer = setInterval(() => {
uploadProgress.value += 10;
if (uploadProgress.value >= 100) {
clearInterval(timer);
// 模拟上传成功后的视频URL
videoUrl.value = URL.createObjectURL(file.file);
videoId.value = uuidv4();
videoName.value = file.file.name;
}
}, 300);
// TODO: 实际的上传逻辑
// const response = await uploadVideo(formData);
// videoUrl.value = response.data.url;
// videoId.value = uuidv4();
// videoName.value = file.file.name;
// 实际上传逻辑
const fileCode = 'video'; // 视频上传的fileCode
const result = await uploadFile(file.file, fileCode, (progress) => {
uploadProgress.value = progress;
});
if (result && result.src) {
videoUrl.value = result.src;
videoId.value = result.meta_id || result.hash;
videoName.value = file.file.name;
} else {
throw new Error('上传失败');
}
} catch (error) {
uploadProgress.value = 0;
showToast('上传失败');
console.error('Upload error:', error);
}
......
import { qiniuTokenAPI, qiniuUploadAPI, saveFileAPI } from '@/api/common';
import BMF from 'browser-md5-file';
// import { v4 as uuidv4 } from 'uuid';
// 获取文件后缀
const getFileSuffix = (fileName) => {
return /.[^.]+$/.exec(fileName) || '';
};
// 获取文件MD5
const getFileMD5 = (file) => {
return new Promise((resolve, reject) => {
const bmf = new BMF();
bmf.md5(file, (err, md5) => {
if (err) {
reject(err);
return;
}
resolve(md5);
});
});
};
// 上传文件到七牛云
const uploadToQiniu = async (file, token, fileName, onProgress) => {
const formData = new FormData();
formData.append('file', file);
formData.append('token', token);
formData.append('key', fileName);
const config = {
headers: { 'Content-Type': 'multipart/form-data' },
onUploadProgress: (progressEvent) => {
if (progressEvent.total > 0) {
const percent = Math.round((progressEvent.loaded * 100) / progressEvent.total);
// 使用requestAnimationFrame确保进度更新的平滑性
requestAnimationFrame(() => {
onProgress?.(percent);
});
}
}
};
// 根据协议选择上传地址
const qiniuUploadUrl = window.location.protocol === 'https:'
? 'https://up.qbox.me'
: 'http://upload.qiniu.com';
return await qiniuUploadAPI(qiniuUploadUrl, formData, config);
};
// 校验文件
export const validateFile = (file, options = {}) => {
const {
maxSize = 100, // 默认100MB
allowedTypes = ['video/mp4', 'video/quicktime'],
} = options;
if (!allowedTypes.includes(file.type)) {
return {
valid: false,
message: '请上传正确格式的视频文件'
};
}
const fileSize = (file.size / 1024 / 1024).toFixed(2);
if (fileSize > maxSize) {
return {
valid: false,
message: `文件大小不能超过${maxSize}MB`
};
}
return { valid: true };
};
// 上传文件
export const uploadFile = async (file, fileCode, onProgress) => {
try {
// 获取文件MD5
const md5 = await getFileMD5(file);
// 获取七牛token
const tokenResult = await qiniuTokenAPI({
name: file.name,
hash: md5
});
// 如果文件已存在,直接返回
if (tokenResult.data) {
onProgress?.(100);
return tokenResult.data;
}
// 新文件上传
if (tokenResult.token) {
const suffix = getFileSuffix(file.name);
const fileName = `uploadForm/${fileCode}/${md5}${suffix}`;
// TODO: image_info 为七牛返回的图片信息,现在是上传视频看后期适配
const { filekey, image_info } = await uploadToQiniu(
file,
tokenResult.token,
fileName,
onProgress
);
if (filekey) {
// 保存文件信息
const { data } = await saveFileAPI({
name: file.name,
filekey,
hash: md5,
height: image_info?.height,
width: image_info?.width,
});
return data;
}
}
throw new Error('上传失败');
} catch (error) {
console.error('Upload error:', error);
throw error;
}
};