|
|
@@ -894,12 +894,29 @@
|
|
|
|
|
|
<div class="form-item">
|
|
|
<div class="form-label">上传视频</div>
|
|
|
- <el-upload class="video-uploader" action="#" :auto-upload="false" :show-file-list="false" accept="video/*">
|
|
|
+ <el-upload
|
|
|
+ class="video-uploader"
|
|
|
+ :action="uploadUrl"
|
|
|
+ :auto-upload="true"
|
|
|
+ :show-file-list="false"
|
|
|
+ accept="video/*"
|
|
|
+ :data="{ tenant_id: Session.get('tenant_id') }"
|
|
|
+ :headers="{ Authorization: `JWT ${Session.get('token')}` }"
|
|
|
+ :before-upload="beforeVideoUpload"
|
|
|
+ :on-success="handleVideoUploadSuccess"
|
|
|
+ :on-error="handleVideoUploadError"
|
|
|
+ >
|
|
|
<div class="upload-area">
|
|
|
- <el-icon>
|
|
|
- <Plus />
|
|
|
- </el-icon>
|
|
|
- <div class="upload-text">上传文件大小不超过500M</div>
|
|
|
+ <template v-if="videoLectureForm.video_url">
|
|
|
+ <video :src="videoLectureForm.video_url" style="width:100%;height:180px; border-radius: 6px; " controls />
|
|
|
+
|
|
|
+ </template>
|
|
|
+ <template v-else>
|
|
|
+ <el-icon>
|
|
|
+ <Plus />
|
|
|
+ </el-icon>
|
|
|
+ <div class="upload-text">上传文件大小不超过500M</div>
|
|
|
+ </template>
|
|
|
</div>
|
|
|
</el-upload>
|
|
|
</div>
|
|
|
@@ -2582,9 +2599,11 @@ const validityEnabled = ref(false);
|
|
|
|
|
|
// 在 script setup 部分添加以下响应式变量
|
|
|
const showVideoLectureDialog = ref(false); // 控制视频宣讲弹窗显示
|
|
|
+const uploadUrl = `${import.meta.env.VITE_API_URL}/api/system/admin_upload/`;
|
|
|
const videoLectureForm = reactive({
|
|
|
title: '', // 步骤名称
|
|
|
- videoFile: null, // 视频文件
|
|
|
+ videoFile: null, // 视频文件(仅本地选择时临时占位,不入库)
|
|
|
+ video_url: '', // 上传成功后的地址
|
|
|
description: '', // 视频简介
|
|
|
broadcastType: 'required', // 播放设置:必须看完/看过即可
|
|
|
});
|
|
|
@@ -3208,6 +3227,14 @@ const showStepOptions = (index: number, event: MouseEvent) => {
|
|
|
// 修改添加选定类型的步骤方法
|
|
|
const addSelectedStepType = async (type: string, label: string) => {
|
|
|
// 检查是否已存在相同类型的步骤,防止重复添加
|
|
|
+ if (type === 'video_presentation') {
|
|
|
+ const exists = recruitmentProcess.some((s: any) => s.type === 'video_presentation' && s.visible !== false);
|
|
|
+ if (exists) {
|
|
|
+ ElMessage.warning('已存在一个“视频宣讲”步骤');
|
|
|
+ showOptionsMenu.value = false;
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ }
|
|
|
if (type === 'ai_video') {
|
|
|
UpdateConfig({
|
|
|
id: getConfigId.value,
|
|
|
@@ -3646,6 +3673,7 @@ const cancelVideoLecture = () => {
|
|
|
Object.assign(videoLectureForm, {
|
|
|
title: '',
|
|
|
videoFile: null,
|
|
|
+ video_url: '',
|
|
|
description: '',
|
|
|
broadcastType: 'required'
|
|
|
});
|
|
|
@@ -3653,29 +3681,77 @@ const cancelVideoLecture = () => {
|
|
|
|
|
|
// 确认添加视频宣讲
|
|
|
const confirmVideoLecture = () => {
|
|
|
- // 创建新的视频宣讲步骤
|
|
|
- const newStep = {
|
|
|
- id: Date.now(),
|
|
|
- name: videoLectureForm.title || '视频宣讲',
|
|
|
- description: videoLectureForm.description || '视频宣讲',
|
|
|
- active: true,
|
|
|
- type: 'video_presentation',
|
|
|
- config: {
|
|
|
- ...videoLectureForm
|
|
|
- }
|
|
|
- };
|
|
|
+ if (!videoLectureForm.video_url) {
|
|
|
+ ElMessage.warning('请先上传视频文件');
|
|
|
+ return;
|
|
|
+ }
|
|
|
|
|
|
- // 添加到流程中
|
|
|
- recruitmentProcess.splice(currentAddIndex.value, 0, newStep);
|
|
|
+ // 编辑模式
|
|
|
+ if (editingVideoLectureIndex.value >= 0) {
|
|
|
+ const step = recruitmentProcess[editingVideoLectureIndex.value];
|
|
|
+ step.name = videoLectureForm.title || '视频宣讲';
|
|
|
+ step.description = videoLectureForm.description || '视频宣讲';
|
|
|
+ step.config = {
|
|
|
+ video_url: videoLectureForm.video_url,
|
|
|
+ description: videoLectureForm.description,
|
|
|
+ broadcastType: videoLectureForm.broadcastType
|
|
|
+ };
|
|
|
+ ElMessage.success('视频宣讲步骤已更新');
|
|
|
+ } else {
|
|
|
+ // 新增模式
|
|
|
+ const newStep = {
|
|
|
+ id: Date.now(),
|
|
|
+ name: videoLectureForm.title || '视频宣讲',
|
|
|
+ description: videoLectureForm.description || '视频宣讲',
|
|
|
+ active: true,
|
|
|
+ type: 'video_presentation',
|
|
|
+ visible: true,
|
|
|
+ config: {
|
|
|
+ video_url: videoLectureForm.video_url,
|
|
|
+ description: videoLectureForm.description,
|
|
|
+ broadcastType: videoLectureForm.broadcastType
|
|
|
+ }
|
|
|
+ };
|
|
|
+ recruitmentProcess.splice(currentAddIndex.value, 0, newStep);
|
|
|
+ ElMessage.success('视频宣讲步骤已添加');
|
|
|
+ }
|
|
|
|
|
|
- // 关闭弹窗
|
|
|
showVideoLectureDialog.value = false;
|
|
|
+ // 重置编辑索引与表单
|
|
|
+ editingVideoLectureIndex.value = -1;
|
|
|
+ cancelVideoLecture();
|
|
|
+};
|
|
|
|
|
|
- // 提示成功
|
|
|
- ElMessage.success('视频宣讲步骤已添加');
|
|
|
+// 上传前校验
|
|
|
+const beforeVideoUpload = (file: File) => {
|
|
|
+ const isVideo = file.type.startsWith('video/');
|
|
|
+ const isLt500M = file.size / 1024 / 1024 < 500;
|
|
|
+ if (!isVideo) {
|
|
|
+ ElMessage.error('只能上传视频文件');
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ if (!isLt500M) {
|
|
|
+ ElMessage.error('视频大小不能超过500M');
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ return true;
|
|
|
+};
|
|
|
|
|
|
- // 重置表单
|
|
|
- cancelVideoLecture();
|
|
|
+// 上传成功
|
|
|
+const handleVideoUploadSuccess = (res: any) => {
|
|
|
+ // 兼容后端返回 {url: ...} 或 {data: {url: ...}}
|
|
|
+ const url = res?.url || res?.data?.url || res?.data;
|
|
|
+ if (url) {
|
|
|
+ videoLectureForm.video_url = url;
|
|
|
+ ElMessage.success('视频上传成功');
|
|
|
+ } else {
|
|
|
+ ElMessage.warning('上传成功但未返回地址');
|
|
|
+ }
|
|
|
+};
|
|
|
+
|
|
|
+// 上传失败
|
|
|
+const handleVideoUploadError = () => {
|
|
|
+ ElMessage.error('视频上传失败');
|
|
|
};
|
|
|
|
|
|
// 添加 AI 实时对话相关方法
|
|
|
@@ -6624,6 +6700,9 @@ const editProcessStep = (step: any, index: number) => {
|
|
|
case 'ai_video':
|
|
|
editAIVideo(step);
|
|
|
break;
|
|
|
+ case 'video_presentation':
|
|
|
+ editVideoLecture(step, index);
|
|
|
+ break;
|
|
|
case 'candidate_questions':
|
|
|
editCandidateQuestions(step, index);
|
|
|
break;
|
|
|
@@ -6642,6 +6721,18 @@ const editProcessStep = (step: any, index: number) => {
|
|
|
}
|
|
|
};
|
|
|
|
|
|
+// 编辑视频宣讲
|
|
|
+const editingVideoLectureIndex = ref(-1);
|
|
|
+const editVideoLecture = (step: any, index: number) => {
|
|
|
+ editingVideoLectureIndex.value = index;
|
|
|
+ // 将已有配置回填到表单
|
|
|
+ videoLectureForm.title = step.name || '视频宣讲';
|
|
|
+ videoLectureForm.description = step?.config?.description || '';
|
|
|
+ videoLectureForm.broadcastType = step?.config?.broadcastType || 'required';
|
|
|
+ videoLectureForm.video_url = step?.config?.video_url || '';
|
|
|
+ showVideoLectureDialog.value = true;
|
|
|
+};
|
|
|
+
|
|
|
// 权重变化处理函数
|
|
|
const handleWeightChange = (index: number, value: number | null) => {
|
|
|
if (value === null || value < 0) value = 0;
|