Przeglądaj źródła

fix: 修复视频发布功能,支持直接使用videoUrl发布

- 移除chapter-detail.vue中的'视频发布功能开发中'提示
- 修改goToPublish函数,传递videoUrl和title参数到发布页面
- 发布页面新增videoUrl参数支持,兼容原有的projectId方式
- 后端publish.controller.ts支持videoProjectId或videoUrl两种方式
- 前端publish-api.ts类型定义更新,videoProjectId改为可选
- 实现书籍章节视频直接发布到第三方平台功能
MyFramework User 4 miesięcy temu
rodzic
commit
060dff9087

+ 3 - 7
my-uniapp-vue3/src/pages/book-generator/chapter-detail.vue

@@ -358,14 +358,10 @@ function goToPublish() {
   
   if (chapterVideoUrl.value) {
     // 有视频,发布视频
-    // 需要从后端获取 videoProjectId
-    uni.showToast({ 
-      title: '视频发布功能开发中', 
-      icon: 'none',
-      duration: 2000
+    // 直接使用 videoUrl 发布
+    uni.navigateTo({ 
+      url: `/pages/publish/index?videoUrl=${encodeURIComponent(chapterVideoUrl.value)}&title=${encodeURIComponent(chapterTitle.value)}` 
     });
-    // TODO: 实现视频发布
-    // uni.navigateTo({ url: `/pages/publish/index?projectId=${videoProjectId}` });
   } else if (chapterAudioUrl.value) {
     // 只有音频,发布音频
     uni.navigateTo({ 

+ 22 - 5
my-uniapp-vue3/src/pages/publish/index.vue

@@ -419,6 +419,7 @@ const audioInfo = ref<any>(null);
 const selectedPlatform = ref<string | null>(null);
 const videoInfo = ref<VideoPreview | null>(null);
 const projectId = ref<number>(0);
+const videoUrl = ref<string>(''); // 直接使用视频URL发布
 const publishing = ref(false);
 
 // 发布表单
@@ -628,20 +629,29 @@ async function handlePublish() {
       return;
     } else {
       // 视频发布
-      if (!projectId.value) {
+      // 支持两种方式:projectId 或 videoUrl
+      if (!projectId.value && !videoUrl.value) {
         uni.hideLoading();
         publishing.value = false;
-        uni.showToast({ title: '项目ID无效', icon: 'none' });
+        uni.showToast({ title: '视频信息无效', icon: 'none' });
         return;
       }
 
-      const result = await createAndPublishTask({
-        videoProjectId: projectId.value,
+      const publishData: any = {
         platform: selectedPlatform.value as any,
         title: publishTitle.value,
         description: publishDesc.value,
         tags: publishTags.value,
-      });
+      };
+
+      // 如果有 projectId 则使用 projectId,否则使用 videoUrl
+      if (projectId.value) {
+        publishData.videoProjectId = projectId.value;
+      } else {
+        publishData.videoUrl = videoUrl.value;
+      }
+
+      const result = await createAndPublishTask(publishData);
 
       uni.hideLoading();
 
@@ -710,6 +720,13 @@ onLoad(async (query: any) => {
       publishTitle.value = '音频';
       publishDesc.value = '';
     }
+  } else if (query?.videoUrl) {
+    // 直接使用视频URL发布(来自书籍章节)
+    isAudioPublish.value = false;
+    videoUrl.value = decodeURIComponent(query.videoUrl);
+    publishTitle.value = query.title || '视频';
+    publishDesc.value = '';
+    console.log('[Publish] 使用视频URL发布:', videoUrl.value);
   } else if (query?.projectId) {
     projectId.value = Number(query.projectId);
 

+ 2 - 1
my-uniapp-vue3/src/utils/publish-api.ts

@@ -102,7 +102,8 @@ export async function getPublishTask(id: number): Promise<PublishTask> {
  * 创建发布任务并立即发布
  */
 export async function createAndPublishTask(data: {
-  videoProjectId: number;
+  videoProjectId?: number;
+  videoUrl?: string;
   platform: 'douyin' | 'kuaishou' | 'bilibili';
   title: string;
   description?: string;

+ 26 - 11
server/src/modules/publish/publish.controller.ts

@@ -211,35 +211,50 @@ router.post('/tasks', async (ctx) => {
   }
 
   const body = ctx.request.body as any;
-  const { videoProjectId, platform, title, description, tags, coverUrl } = body;
+  const { videoProjectId, videoUrl, platform, title, description, tags, coverUrl } = body;
 
-  if (!videoProjectId || !platform || !title) {
+  if (!platform || !title) {
     ctx.status = 400;
     ctx.body = { success: false, error: '缺少必要参数' };
     return;
   }
 
-  // 获取视频项目信息
-  const projectInfo = await getVideoProjectForPublish(videoProjectId);
-  if (!projectInfo) {
-    ctx.status = 404;
-    ctx.body = { success: false, error: '视频项目不存在或未生成视频' };
+  // 支持两种方式:1. 使用 videoProjectId  2. 直接使用 videoUrl
+  let finalVideoUrl = videoUrl;
+  let finalDescription = description || '';
+  let finalCoverUrl = coverUrl;
+
+  if (videoProjectId) {
+    // 方式1:通过 videoProjectId 获取视频信息
+    const projectInfo = await getVideoProjectForPublish(videoProjectId);
+    if (!projectInfo) {
+      ctx.status = 404;
+      ctx.body = { success: false, error: '视频项目不存在或未生成视频' };
+      return;
+    }
+    finalVideoUrl = projectInfo.videoUrl;
+    finalDescription = description || projectInfo.description;
+    finalCoverUrl = coverUrl || projectInfo.coverUrl;
+  } else if (!videoUrl) {
+    // 两种方式都没有
+    ctx.status = 400;
+    ctx.body = { success: false, error: '请提供 videoProjectId 或 videoUrl' };
     return;
   }
 
   // 创建发布任务
   const task = await createPublishTask(userId, {
-    videoProjectId,
+    videoProjectId: videoProjectId || 0, // 如果没有 projectId 则用 0
     platform,
     title,
-    description: description || projectInfo.description,
+    description: finalDescription,
     tags,
-    coverUrl: coverUrl || projectInfo.coverUrl,
+    coverUrl: finalCoverUrl,
   });
 
   // 更新视频URL
   const { updatePublishTask } = await import('./publish.service');
-  await updatePublishTask(task.id!, { videoUrl: projectInfo.videoUrl });
+  await updatePublishTask(task.id!, { videoUrl: finalVideoUrl });
 
   // 根据平台执行发布
   let result: { success: boolean; publishedUrl?: string; error?: string };