|
@@ -1,58 +1,78 @@
|
|
|
-import request from '@/utils/request'
|
|
|
|
|
-
|
|
|
|
|
-/**
|
|
|
|
|
- * 通过后端 presigned URL 上传到华为 OBS(AK/SK 仅在后端)
|
|
|
|
|
- * @param file 文件
|
|
|
|
|
- * @param progressCallback 进度 0-100
|
|
|
|
|
- * @param type 1=课程视频, 2=用户视频
|
|
|
|
|
- * @param cancelCallback { cancel: fn }
|
|
|
|
|
- */
|
|
|
|
|
|
|
+import ObsClient from "esdk-obs-browserjs/src/obs"
|
|
|
|
|
+import Vue from "vue";
|
|
|
export const uploadToOBS = async (file, progressCallback, type, cancelCallback) => {
|
|
export const uploadToOBS = async (file, progressCallback, type, cancelCallback) => {
|
|
|
- const suffix = (file.name || 'mp4').split('.').pop() || 'mp4'
|
|
|
|
|
- const presignRes = await request({
|
|
|
|
|
- url: '/common/obs/presignedUploadUrl',
|
|
|
|
|
- method: 'get',
|
|
|
|
|
- params: { type: type || 2, suffix }
|
|
|
|
|
- })
|
|
|
|
|
-
|
|
|
|
|
- if (!presignRes || !presignRes.url) {
|
|
|
|
|
- throw new Error(presignRes?.msg || '获取 OBS 签名 URL 失败,请检查租户 OSS 是否配置为华为云')
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- const presignedUrl = presignRes.url
|
|
|
|
|
- const objKey = presignRes.objKey
|
|
|
|
|
-
|
|
|
|
|
- return new Promise((resolve, reject) => {
|
|
|
|
|
- const xhr = new XMLHttpRequest()
|
|
|
|
|
|
|
+ try {
|
|
|
|
|
+ const obsClient = new ObsClient({
|
|
|
|
|
+ access_key_id: Vue.prototype.$runtimeConfig.VUE_APP_OBS_ACCESS_KEY_ID,
|
|
|
|
|
+ secret_access_key: Vue.prototype.$runtimeConfig.VUE_APP_OBS_SECRET_ACCESS_KEY,
|
|
|
|
|
+ server: Vue.prototype.$runtimeConfig.VUE_APP_OBS_SERVER,
|
|
|
|
|
+ timeout: 1200,
|
|
|
|
|
+ })
|
|
|
|
|
|
|
|
- if (cancelCallback) {
|
|
|
|
|
- cancelCallback({
|
|
|
|
|
- cancel: () => {
|
|
|
|
|
- xhr.abort()
|
|
|
|
|
- reject(new Error('Upload cancelled by user'))
|
|
|
|
|
- }
|
|
|
|
|
- })
|
|
|
|
|
- }
|
|
|
|
|
|
|
+ const fileName = file.name || ""
|
|
|
|
|
+ const upload_file_name = new Date().getTime() + "." + fileName.split(".")[fileName.split(".").length - 1]
|
|
|
|
|
+ const date = new Date()
|
|
|
|
|
+ const year = date.getFullYear()
|
|
|
|
|
+ const month = date.getMonth() + 1
|
|
|
|
|
+ const strDate = date.getDate()
|
|
|
|
|
+ const uploadDay = `${year}${month}${strDate}`
|
|
|
|
|
+ const videoKey = `userVideo/${uploadDay}/${upload_file_name}`
|
|
|
|
|
+ const courseKey = `course/${uploadDay}/${upload_file_name}`
|
|
|
|
|
+ const key = type === 1 ? courseKey : videoKey
|
|
|
|
|
|
|
|
- xhr.upload.onprogress = (event) => {
|
|
|
|
|
- if (event.lengthComputable && progressCallback) {
|
|
|
|
|
- progressCallback(Math.round((event.loaded / event.total) * 100))
|
|
|
|
|
|
|
+ var callback = (transferredAmount, totalAmount, totalSeconds) => {
|
|
|
|
|
+ const progress = Number.parseInt((transferredAmount * 100.0) / totalAmount)
|
|
|
|
|
+ if (progressCallback) {
|
|
|
|
|
+ progressCallback(progress)
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- xhr.onload = () => {
|
|
|
|
|
- if (xhr.status >= 200 && xhr.status < 300) {
|
|
|
|
|
- resolve({ urlPath: objKey })
|
|
|
|
|
- } else {
|
|
|
|
|
- reject(new Error('OBS 上传失败: HTTP ' + xhr.status))
|
|
|
|
|
- }
|
|
|
|
|
- }
|
|
|
|
|
|
|
+ return new Promise((resolve, reject) => {
|
|
|
|
|
+ let isCancelled = false
|
|
|
|
|
|
|
|
- xhr.onerror = () => reject(new Error('OBS 上传网络错误'))
|
|
|
|
|
- xhr.onabort = () => reject(new Error('上传已取消'))
|
|
|
|
|
|
|
+ if (cancelCallback) {
|
|
|
|
|
+ cancelCallback({
|
|
|
|
|
+ cancel: () => {
|
|
|
|
|
+ console.log("Cancelling OBS upload")
|
|
|
|
|
+ isCancelled = true
|
|
|
|
|
+ reject(new Error("Upload cancelled by user"))
|
|
|
|
|
+ },
|
|
|
|
|
+ })
|
|
|
|
|
+ }
|
|
|
|
|
+ //四福堂专属配置
|
|
|
|
|
+ /* resolve({
|
|
|
|
|
+ "RequestId": "",
|
|
|
|
|
+ "urlPath": ""
|
|
|
|
|
+ })*/
|
|
|
|
|
+ obsClient.putObject(
|
|
|
|
|
+ {
|
|
|
|
|
+ Bucket: Vue.prototype.$runtimeConfig.VUE_APP_OBS_BUCKET,
|
|
|
|
|
+ Key: key,
|
|
|
|
|
+ Body: file,
|
|
|
|
|
+ ProgressCallback: callback,
|
|
|
|
|
+ },
|
|
|
|
|
+ (err, result) => {
|
|
|
|
|
+ if (isCancelled) {
|
|
|
|
|
+ return // Don't process result if cancelled
|
|
|
|
|
+ }
|
|
|
|
|
|
|
|
- xhr.open('PUT', presignedUrl, true)
|
|
|
|
|
- xhr.setRequestHeader('Content-Type', file.type || 'application/octet-stream')
|
|
|
|
|
- xhr.send(file)
|
|
|
|
|
- })
|
|
|
|
|
|
|
+ if (err) {
|
|
|
|
|
+ reject(err)
|
|
|
|
|
+ console.error("Error-->" + err)
|
|
|
|
|
+ } else {
|
|
|
|
|
+ const a = {
|
|
|
|
|
+ ...result,
|
|
|
|
|
+ urlPath: key,
|
|
|
|
|
+ }
|
|
|
|
|
+ console.log("上传成功", a)
|
|
|
|
|
+ resolve(a)
|
|
|
|
|
+ }
|
|
|
|
|
+ },
|
|
|
|
|
+ )
|
|
|
|
|
+ //注释到这里【四福堂】
|
|
|
|
|
+ })
|
|
|
|
|
+ } catch (error) {
|
|
|
|
|
+ console.error("Error during upload:", error)
|
|
|
|
|
+ throw error
|
|
|
|
|
+ }
|
|
|
}
|
|
}
|