|
@@ -550,7 +550,7 @@
|
|
|
</el-form-item>
|
|
</el-form-item>
|
|
|
|
|
|
|
|
<el-form-item label="子分类" prop="typeSubId" :rules="[{ required: true, message: '请选择子分类', trigger: 'blur' }]">
|
|
<el-form-item label="子分类" prop="typeSubId" :rules="[{ required: true, message: '请选择子分类', trigger: 'blur' }]">
|
|
|
- <el-select v-model="batchUploadForm.typeSubId" clearable placeholder="请选择子分类" style="width: 100%">
|
|
|
|
|
|
|
+ <el-select v-model="batchUploadForm.typeSubId" clearable placeholder="请选择子分类" style="width: 100%" @change="changeSubType">
|
|
|
<el-option
|
|
<el-option
|
|
|
v-for="item in subTypeList"
|
|
v-for="item in subTypeList"
|
|
|
:key="item.dictValue"
|
|
:key="item.dictValue"
|
|
@@ -560,7 +560,7 @@
|
|
|
</el-select>
|
|
</el-select>
|
|
|
</el-form-item>
|
|
</el-form-item>
|
|
|
|
|
|
|
|
- <el-form-item label="关联题目" prop="projectIds" style="display: none">
|
|
|
|
|
|
|
+ <el-form-item label="关联题目" prop="projectIds" v-show="currentProject === 'myhk'">
|
|
|
<el-select
|
|
<el-select
|
|
|
ref="customSelect"
|
|
ref="customSelect"
|
|
|
class="custom-select-class"
|
|
class="custom-select-class"
|
|
@@ -774,7 +774,9 @@ import {getByIds, listCourseQuestionBank} from '@/api/course/courseQuestionBank'
|
|
|
import {getThumbnail} from "@/api/course/userVideo";
|
|
import {getThumbnail} from "@/api/course/userVideo";
|
|
|
import {uploadObject} from "@/utils/cos.js";
|
|
import {uploadObject} from "@/utils/cos.js";
|
|
|
import {uploadToOBS} from "@/utils/obs.js";
|
|
import {uploadToOBS} from "@/utils/obs.js";
|
|
|
|
|
+import {uploadToHSY} from "@/utils/hsy.js";
|
|
|
import MinimizableDialog from "@/components/MinimizableDialog"
|
|
import MinimizableDialog from "@/components/MinimizableDialog"
|
|
|
|
|
+import log from "@/views/monitor/job/log.vue";
|
|
|
|
|
|
|
|
export default {
|
|
export default {
|
|
|
name: 'VideoResource',
|
|
name: 'VideoResource',
|
|
@@ -827,6 +829,8 @@ export default {
|
|
|
typeSubId: null,
|
|
typeSubId: null,
|
|
|
projectIds: [],
|
|
projectIds: [],
|
|
|
sort: null,
|
|
sort: null,
|
|
|
|
|
+ hsyVid:null,//火山云上传视频返回vid
|
|
|
|
|
+ hsyVodUrl:null,//火山云url
|
|
|
// 新增上传状态字段
|
|
// 新增上传状态字段
|
|
|
uploadStatus: 'pending', // pending, uploading, success, failed
|
|
uploadStatus: 'pending', // pending, uploading, success, failed
|
|
|
uploadProgress: {
|
|
uploadProgress: {
|
|
@@ -945,6 +949,7 @@ export default {
|
|
|
isProcessingBatch: false, // 是否正在处理批次
|
|
isProcessingBatch: false, // 是否正在处理批次
|
|
|
currentBatchIndex: 0, // 当前批次索引
|
|
currentBatchIndex: 0, // 当前批次索引
|
|
|
uploadCancellationTokens: new Map(), // Store cancellation functions by video ID
|
|
uploadCancellationTokens: new Map(), // Store cancellation functions by video ID
|
|
|
|
|
+ currentProject: process.env.VUE_APP_PROJECT
|
|
|
}
|
|
}
|
|
|
},
|
|
},
|
|
|
watch: {
|
|
watch: {
|
|
@@ -1107,6 +1112,7 @@ export default {
|
|
|
this.add = true
|
|
this.add = true
|
|
|
|
|
|
|
|
const params = Object.assign({}, this.form);
|
|
const params = Object.assign({}, this.form);
|
|
|
|
|
+ console.log("提交素材表单参数",this.form)
|
|
|
params.projectIds = this.form.projectIds.join(',');
|
|
params.projectIds = this.form.projectIds.join(',');
|
|
|
if (this.form.id != null) {
|
|
if (this.form.id != null) {
|
|
|
updateVideoResource(params).then(response => {
|
|
updateVideoResource(params).then(response => {
|
|
@@ -1162,6 +1168,9 @@ export default {
|
|
|
}
|
|
}
|
|
|
if (type === 3) {
|
|
if (type === 3) {
|
|
|
this.batchUploadForm.typeSubId = null
|
|
this.batchUploadForm.typeSubId = null
|
|
|
|
|
+ if (this.currentProject === 'myhk') {
|
|
|
|
|
+ this.batchUploadForm.projectIds = []
|
|
|
|
|
+ }
|
|
|
}
|
|
}
|
|
|
this.subTypeList = []
|
|
this.subTypeList = []
|
|
|
if (!val) {
|
|
if (!val) {
|
|
@@ -1171,6 +1180,25 @@ export default {
|
|
|
this.subTypeList = response.data
|
|
this.subTypeList = response.data
|
|
|
})
|
|
})
|
|
|
},
|
|
},
|
|
|
|
|
+ changeSubType(val) {
|
|
|
|
|
+ if (this.currentProject !== 'myhk') {
|
|
|
|
|
+ return
|
|
|
|
|
+ }
|
|
|
|
|
+ this.projectShowList = []
|
|
|
|
|
+ this.batchUploadForm.projectIds = []
|
|
|
|
|
+ listCourseQuestionBank({questionSubType: val}).then(async response => {
|
|
|
|
|
+ const projectIds = response.rows.map(item => item.id)
|
|
|
|
|
+
|
|
|
|
|
+ // 如果存在关联项目,获取项目详情用于回显
|
|
|
|
|
+ if (projectIds && projectIds.length > 0) {
|
|
|
|
|
+ // 加载项目列表信息用于回显
|
|
|
|
|
+ await getByIds({ids: projectIds.join(',')}).then(reponse => {
|
|
|
|
|
+ this.projectShowList = reponse.data
|
|
|
|
|
+ this.batchUploadForm.projectIds = projectIds
|
|
|
|
|
+ });
|
|
|
|
|
+ }
|
|
|
|
|
+ })
|
|
|
|
|
+ },
|
|
|
/** 预览视频 */
|
|
/** 预览视频 */
|
|
|
handleVideoPreview(url) {
|
|
handleVideoPreview(url) {
|
|
|
this.videoPreviewVisible = true;
|
|
this.videoPreviewVisible = true;
|
|
@@ -1301,37 +1329,95 @@ export default {
|
|
|
}
|
|
}
|
|
|
},
|
|
},
|
|
|
//上传华为云Obs
|
|
//上传华为云Obs
|
|
|
- async uploadVideoToHwObs(file, form, onProgress) {
|
|
|
|
|
|
|
+ // async uploadVideoToHwObs(file, form, onProgress) {
|
|
|
|
|
+ // try {
|
|
|
|
|
+ // // 更新线路2状态为上传中
|
|
|
|
|
+ // this.updateUploadProgress('line2Status', 'uploading');
|
|
|
|
|
+ //
|
|
|
|
|
+ // const data = await uploadToOBS(file, (progress) => {
|
|
|
|
|
+ // const progressPercent = Math.floor(progress);
|
|
|
|
|
+ // this.updateUploadProgress('line2', progressPercent);
|
|
|
|
|
+ // const progressEvent = { percent: progressPercent, loaded: progress, total: progress, lengthComputable: true };
|
|
|
|
|
+ // onProgress(progressEvent);
|
|
|
|
|
+ // }, 1, (uploadInfo) => {
|
|
|
|
|
+ // if (form.tempId) {
|
|
|
|
|
+ // const tokens = this.uploadCancellationTokens.get(form.tempId) || {};
|
|
|
|
|
+ // tokens.obs = uploadInfo.cancel;
|
|
|
|
|
+ // this.uploadCancellationTokens.set(form.tempId, tokens);
|
|
|
|
|
+ // }
|
|
|
|
|
+ // });
|
|
|
|
|
+ //
|
|
|
|
|
+ // form.line2 = `${process.env.VUE_APP_VIDEO_LINE_2}/${data.urlPath}`;
|
|
|
|
|
+ //
|
|
|
|
|
+ // // 更新线路2状态为成功
|
|
|
|
|
+ // this.updateUploadProgress('line2Status', 'success');
|
|
|
|
|
+ // this.updateUploadProgress('line2', 100);
|
|
|
|
|
+ //
|
|
|
|
|
+ // this.$message.success("线路二上传成功");
|
|
|
|
|
+ // return { success: true, url: form.line2 };
|
|
|
|
|
+ // } catch (error) {
|
|
|
|
|
+ // // 更新线路2状态为失败
|
|
|
|
|
+ // this.updateUploadProgress('line2Status', 'failed');
|
|
|
|
|
+ // this.$message.error("线路二上传失败");
|
|
|
|
|
+ // return { success: false, error: error.message };
|
|
|
|
|
+ // }
|
|
|
|
|
+ // },
|
|
|
|
|
+ //上传火山云
|
|
|
|
|
+ async uploadVideoToHsy(file, form, onProgress) {
|
|
|
try {
|
|
try {
|
|
|
- // 更新线路2状态为上传中
|
|
|
|
|
this.updateUploadProgress('line2Status', 'uploading');
|
|
this.updateUploadProgress('line2Status', 'uploading');
|
|
|
|
|
|
|
|
- const data = await uploadToOBS(file, (progress) => {
|
|
|
|
|
- const progressPercent = Math.floor(progress);
|
|
|
|
|
- this.updateUploadProgress('line2', progressPercent);
|
|
|
|
|
- const progressEvent = { percent: progressPercent, loaded: progress, total: progress, lengthComputable: true };
|
|
|
|
|
- onProgress(progressEvent);
|
|
|
|
|
- }, 1, (uploadInfo) => {
|
|
|
|
|
- if (form.tempId) {
|
|
|
|
|
- const tokens = this.uploadCancellationTokens.get(form.tempId) || {};
|
|
|
|
|
- tokens.obs = uploadInfo.cancel;
|
|
|
|
|
- this.uploadCancellationTokens.set(form.tempId, tokens);
|
|
|
|
|
- }
|
|
|
|
|
- });
|
|
|
|
|
|
|
+ const data = await uploadToHSY(
|
|
|
|
|
+ file,
|
|
|
|
|
+ (progress) => {
|
|
|
|
|
+ // 火山云的进度是小数0-1
|
|
|
|
|
+ if (typeof progress.percent === 'number') {
|
|
|
|
|
+ const percent = Math.floor(progress.percent * 100);
|
|
|
|
|
+
|
|
|
|
|
+ // 更新线路2进度
|
|
|
|
|
+ this.updateUploadProgress('line2', percent);
|
|
|
|
|
+
|
|
|
|
|
+ // 对外统一 progress 事件(模拟 xhr)
|
|
|
|
|
+ onProgress?.({
|
|
|
|
|
+ percent,
|
|
|
|
|
+ loaded: percent,
|
|
|
|
|
+ total: 100,
|
|
|
|
|
+ lengthComputable: true
|
|
|
|
|
+ });
|
|
|
|
|
+ }
|
|
|
|
|
|
|
|
- form.line2 = `${process.env.VUE_APP_VIDEO_LINE_2}/${data.urlPath}`;
|
|
|
|
|
|
|
+ // 状态同步(成功 / 失败)
|
|
|
|
|
+ if (progress.status === 'success') {
|
|
|
|
|
+ this.updateUploadProgress('line2Status', 'success');
|
|
|
|
|
+ this.updateUploadProgress('line2', 100);
|
|
|
|
|
+ }
|
|
|
|
|
|
|
|
- // 更新线路2状态为成功
|
|
|
|
|
- this.updateUploadProgress('line2Status', 'success');
|
|
|
|
|
- this.updateUploadProgress('line2', 100);
|
|
|
|
|
|
|
+ if (progress.status === 'failed') {
|
|
|
|
|
+ this.updateUploadProgress('line2Status', 'failed');
|
|
|
|
|
+ }
|
|
|
|
|
+ },
|
|
|
|
|
+ 1,
|
|
|
|
|
+ (uploadInfo) => {
|
|
|
|
|
+ if (form.tempId) {
|
|
|
|
|
+ const tokens = this.uploadCancellationTokens.get(form.tempId) || {};
|
|
|
|
|
+ tokens.hsy = uploadInfo.cancel;
|
|
|
|
|
+ this.uploadCancellationTokens.set(form.tempId, tokens);
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ );
|
|
|
|
|
+ console.log("上传火山云返回参数",data)
|
|
|
|
|
|
|
|
- this.$message.success("线路二上传成功");
|
|
|
|
|
|
|
+ form.line2 = `${process.env.VUE_APP_VIDEO_URL}/${data.SourceInfo.FileName}`;
|
|
|
|
|
+ this.form.hsyVid = data.Vid
|
|
|
|
|
+ this.form.hsyVodUrl = process.env.VUE_APP_VIDEO_URL+"/"+data.SourceInfo.FileName
|
|
|
|
|
+ console.log("this.form",this.form)
|
|
|
|
|
+ this.$message.success('线路二上传成功');
|
|
|
return { success: true, url: form.line2 };
|
|
return { success: true, url: form.line2 };
|
|
|
|
|
+
|
|
|
} catch (error) {
|
|
} catch (error) {
|
|
|
- // 更新线路2状态为失败
|
|
|
|
|
this.updateUploadProgress('line2Status', 'failed');
|
|
this.updateUploadProgress('line2Status', 'failed');
|
|
|
- this.$message.error("线路二上传失败");
|
|
|
|
|
- return { success: false, error: error.message };
|
|
|
|
|
|
|
+ this.$message.error('线路二上传失败');
|
|
|
|
|
+ return { success: false, error: error?.message || 'upload failed' };
|
|
|
}
|
|
}
|
|
|
},
|
|
},
|
|
|
// 更新上传进度的辅助方法
|
|
// 更新上传进度的辅助方法
|
|
@@ -1368,7 +1454,8 @@ export default {
|
|
|
await this.getFirstThumbnail(file, this.form);
|
|
await this.getFirstThumbnail(file, this.form);
|
|
|
const [line1Result, line2Result] = await Promise.allSettled([
|
|
const [line1Result, line2Result] = await Promise.allSettled([
|
|
|
this.uploadVideoToTxPcdn(file, this.form, options.onProgress),
|
|
this.uploadVideoToTxPcdn(file, this.form, options.onProgress),
|
|
|
- this.uploadVideoToHwObs(file, this.form, options.onProgress)
|
|
|
|
|
|
|
+ //this.uploadVideoToHwObs(file, this.form, options.onProgress)
|
|
|
|
|
+ this.uploadVideoToHsy(file, this.form, options.onProgress)
|
|
|
]);
|
|
]);
|
|
|
|
|
|
|
|
const line1Success = line1Result.status === 'fulfilled' && line1Result.value.success;
|
|
const line1Success = line1Result.status === 'fulfilled' && line1Result.value.success;
|
|
@@ -1454,6 +1541,8 @@ export default {
|
|
|
cancelBatch() {
|
|
cancelBatch() {
|
|
|
if (!this.videoList || this.videoList.length === 0) {
|
|
if (!this.videoList || this.videoList.length === 0) {
|
|
|
this.batchAddVisible = false
|
|
this.batchAddVisible = false
|
|
|
|
|
+ this.batchUpdateVisible = false
|
|
|
|
|
+
|
|
|
return
|
|
return
|
|
|
}
|
|
}
|
|
|
this.$confirm('关闭窗口视频需要重新上传,确定关闭吗?', '提示', {
|
|
this.$confirm('关闭窗口视频需要重新上传,确定关闭吗?', '提示', {
|
|
@@ -1462,11 +1551,13 @@ export default {
|
|
|
type: 'warning'
|
|
type: 'warning'
|
|
|
}).then(() => {
|
|
}).then(() => {
|
|
|
this.batchAddVisible = false
|
|
this.batchAddVisible = false
|
|
|
|
|
+ this.batchUpdateVisible = false
|
|
|
this.changeCateType(this.queryParams.typeId)
|
|
this.changeCateType(this.queryParams.typeId)
|
|
|
}).catch(() => { });
|
|
}).catch(() => { });
|
|
|
},
|
|
},
|
|
|
/** 批量修改 */
|
|
/** 批量修改 */
|
|
|
submitBatchUpdate() {
|
|
submitBatchUpdate() {
|
|
|
|
|
+ console.log("批量上传表单提交参数",this.form)
|
|
|
this.$refs["form"].validate(valid => {
|
|
this.$refs["form"].validate(valid => {
|
|
|
if (valid) {
|
|
if (valid) {
|
|
|
if (this.batchUpdateForm.ids.length === 0) {
|
|
if (this.batchUpdateForm.ids.length === 0) {
|
|
@@ -1500,6 +1591,7 @@ export default {
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
// 检查是否所有选中的视频都已上传完成
|
|
// 检查是否所有选中的视频都已上传完成
|
|
|
|
|
+ console.log("videoList",this.videoList)
|
|
|
const incompleteVideos = this.videoList.filter(item => (item.progress || 0) < 100);
|
|
const incompleteVideos = this.videoList.filter(item => (item.progress || 0) < 100);
|
|
|
if (incompleteVideos.length > 0) {
|
|
if (incompleteVideos.length > 0) {
|
|
|
this.$message.warning('有未完成上传的视频,请先完成上传');
|
|
this.$message.warning('有未完成上传的视频,请先完成上传');
|
|
@@ -1658,14 +1750,23 @@ export default {
|
|
|
/** 显示上传面板 */
|
|
/** 显示上传面板 */
|
|
|
showUploadPanel() {
|
|
showUploadPanel() {
|
|
|
this.showUpload = true;
|
|
this.showUpload = true;
|
|
|
- this.batchUploadForm = {
|
|
|
|
|
- typeId: null,
|
|
|
|
|
- typeSubId: null,
|
|
|
|
|
- projectIds: [],
|
|
|
|
|
- files: []
|
|
|
|
|
- };
|
|
|
|
|
|
|
+
|
|
|
|
|
+ if (this.currentProject === 'myhk') {
|
|
|
|
|
+ this.batchUploadForm = {
|
|
|
|
|
+ ...this.batchUploadForm,
|
|
|
|
|
+ files: []
|
|
|
|
|
+ };
|
|
|
|
|
+ } else {
|
|
|
|
|
+ this.batchUploadForm = {
|
|
|
|
|
+ typeId: null,
|
|
|
|
|
+ typeSubId: null,
|
|
|
|
|
+ projectIds: [],
|
|
|
|
|
+ files: []
|
|
|
|
|
+ };
|
|
|
|
|
+ this.subTypeList = []
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
this.batchFileList = [];
|
|
this.batchFileList = [];
|
|
|
- this.subTypeList = []
|
|
|
|
|
if (this.$refs.batchVideoUpload) {
|
|
if (this.$refs.batchVideoUpload) {
|
|
|
this.$refs.batchVideoUpload.clearFiles();
|
|
this.$refs.batchVideoUpload.clearFiles();
|
|
|
}
|
|
}
|
|
@@ -1773,6 +1874,7 @@ export default {
|
|
|
this.isProcessingBatch = false;
|
|
this.isProcessingBatch = false;
|
|
|
this.isUploading = false;
|
|
this.isUploading = false;
|
|
|
this.$message.success('所有视频上传队列处理完成!');
|
|
this.$message.success('所有视频上传队列处理完成!');
|
|
|
|
|
+ console.log("批量上传form",this.form)
|
|
|
},
|
|
},
|
|
|
|
|
|
|
|
async uploadSingleVideo(tempVideo) {
|
|
async uploadSingleVideo(tempVideo) {
|
|
@@ -1783,7 +1885,9 @@ export default {
|
|
|
// 并行上传到两个服务器
|
|
// 并行上传到两个服务器
|
|
|
const [line1Result, line2Result] = await Promise.allSettled([
|
|
const [line1Result, line2Result] = await Promise.allSettled([
|
|
|
this.uploadVideoToTxPcdnBatch(tempVideo.file, tempVideo),
|
|
this.uploadVideoToTxPcdnBatch(tempVideo.file, tempVideo),
|
|
|
- this.uploadVideoToHwObsBatch(tempVideo.file, tempVideo)
|
|
|
|
|
|
|
+ // this.uploadVideoToHwObsBatch(tempVideo.file, tempVideo)
|
|
|
|
|
+ this.uploadVideoToHSYBatch(tempVideo.file, tempVideo),
|
|
|
|
|
+
|
|
|
]);
|
|
]);
|
|
|
|
|
|
|
|
// 检查上传结果
|
|
// 检查上传结果
|
|
@@ -2107,9 +2211,31 @@ export default {
|
|
|
}
|
|
}
|
|
|
},
|
|
},
|
|
|
// 批量上传 - 华为云
|
|
// 批量上传 - 华为云
|
|
|
- async uploadVideoToHwObsBatch(file, tempVideo) {
|
|
|
|
|
|
|
+ // async uploadVideoToHwObsBatch(file, tempVideo) {
|
|
|
|
|
+ // try {
|
|
|
|
|
+ // const data = await uploadToOBS(file, (progress) => {
|
|
|
|
|
+ // const progressPercent = Math.floor(progress);
|
|
|
|
|
+ // const index = this.videoList.findIndex(item => item.tempId === tempVideo.tempId);
|
|
|
|
|
+ // if (index !== -1) {
|
|
|
|
|
+ // this.videoList[index].uploadDetails.line2 = progressPercent;
|
|
|
|
|
+ // this.videoList[index].uploadDetails.line2Status = 'uploading';
|
|
|
|
|
+ // this.updateBatchProgress(index);
|
|
|
|
|
+ // }
|
|
|
|
|
+ // }, 1, (uploadInfo) => {
|
|
|
|
|
+ // const tokens = this.uploadCancellationTokens.get(tempVideo.tempId) || {};
|
|
|
|
|
+ // tokens.obs = uploadInfo.cancel;
|
|
|
|
|
+ // this.uploadCancellationTokens.set(tempVideo.tempId, tokens);
|
|
|
|
|
+ // });
|
|
|
|
|
+ //
|
|
|
|
|
+ // tempVideo.line2 = `${process.env.VUE_APP_VIDEO_LINE_2}/${data.urlPath}`;
|
|
|
|
|
+ // return { success: true, url: tempVideo.line2 };
|
|
|
|
|
+ // } catch (error) {
|
|
|
|
|
+ // return { success: false, error: error.message };
|
|
|
|
|
+ // }
|
|
|
|
|
+ // },
|
|
|
|
|
+ async uploadVideoToHSYBatch(file, tempVideo) {
|
|
|
try {
|
|
try {
|
|
|
- const data = await uploadToOBS(file, (progress) => {
|
|
|
|
|
|
|
+ const data = await uploadToHSY(file, (progress) => {
|
|
|
const progressPercent = Math.floor(progress);
|
|
const progressPercent = Math.floor(progress);
|
|
|
const index = this.videoList.findIndex(item => item.tempId === tempVideo.tempId);
|
|
const index = this.videoList.findIndex(item => item.tempId === tempVideo.tempId);
|
|
|
if (index !== -1) {
|
|
if (index !== -1) {
|
|
@@ -2122,9 +2248,11 @@ export default {
|
|
|
tokens.obs = uploadInfo.cancel;
|
|
tokens.obs = uploadInfo.cancel;
|
|
|
this.uploadCancellationTokens.set(tempVideo.tempId, tokens);
|
|
this.uploadCancellationTokens.set(tempVideo.tempId, tokens);
|
|
|
});
|
|
});
|
|
|
|
|
+ console.log("批量上传返回参数",data)
|
|
|
|
|
+ tempVideo.line2 = `${process.env.VUE_APP_VIDEO_URL}/${data.SourceInfo.FileName}`;
|
|
|
|
|
+ tempVideo.hsyVid = data.Vid;
|
|
|
|
|
|
|
|
- tempVideo.line2 = `${process.env.VUE_APP_VIDEO_LINE_2}/${data.urlPath}`;
|
|
|
|
|
- return { success: true, url: tempVideo.line2 };
|
|
|
|
|
|
|
+ return { success: true, url: tempVideo.line2};
|
|
|
} catch (error) {
|
|
} catch (error) {
|
|
|
return { success: false, error: error.message };
|
|
return { success: false, error: error.message };
|
|
|
}
|
|
}
|