fix: 修复前端lint和类型错误
CI Build & Deploy Pipeline / Build Staging API Image (push) Has been skipped
CI Build & Deploy Pipeline / Build Staging Web Image (push) Has been skipped
CI Build & Deploy Pipeline / Build Staging Worker Image (push) Has been skipped
CI Build & Deploy Pipeline / Build Staging API Image (pull_request) Has been skipped
CI Build & Deploy Pipeline / Build Staging Web Image (pull_request) Has been skipped
CI Build & Deploy Pipeline / Deploy Staging (Watchtower auto-deploy) (push) Has been skipped
CI Build & Deploy Pipeline / Build Production API Image (push) Has been skipped
CI Build & Deploy Pipeline / Build Production Web Image (push) Has been skipped
CI Build & Deploy Pipeline / Build Staging Worker Image (pull_request) Has been skipped
CI Build & Deploy Pipeline / Build Production Worker Image (push) Has been skipped
CI Build & Deploy Pipeline / Build Production API Image (pull_request) Has been skipped
CI Build & Deploy Pipeline / Build Production Worker Image (pull_request) Has been skipped
CI Build & Deploy Pipeline / Build Production Web Image (pull_request) Has been skipped
CI Build & Deploy Pipeline / Staging E2E Tests (push) Has been skipped
CI Build & Deploy Pipeline / Staging API Integration Tests (push) Has been skipped
CI Build & Deploy Pipeline / Deploy Staging (Watchtower auto-deploy) (pull_request) Has been skipped
CI Build & Deploy Pipeline / Deploy Production (push) Has been skipped
CI Build & Deploy Pipeline / Production Browser E2E (push) Has been skipped
CI Build & Deploy Pipeline / Staging API Integration Tests (pull_request) Has been skipped
CI Build & Deploy Pipeline / Deploy Production (pull_request) Has been skipped
CI Build & Deploy Pipeline / Staging E2E Tests (pull_request) Has been skipped
CI Build & Deploy Pipeline / Production Browser E2E (pull_request) Has been skipped
CI/CD Pipeline / Frontend Lint (pull_request) Failing after 46s
CI/CD Pipeline / Frontend Lint (push) Failing after 52s
CI/CD Pipeline / Unit Tests (push) Successful in 2m18s
CI/CD Pipeline / Validate Code Quality And Tests (pull_request) Successful in 2m28s
CI/CD Pipeline / Unit Tests (pull_request) Successful in 2m40s
CI/CD Pipeline / Validate Code Quality And Tests (push) Successful in 2m57s
CI/CD Pipeline / Integration Tests (pull_request) Successful in 1m27s
CI/CD Pipeline / Integration Tests (push) Successful in 1m31s

- STATUS_CONFIG补充cancelled状态定义
- ClipData类型增加media_asset_id字段
- EditorClipList的onAdd包一层默认参数,修复类型不匹配
- handleClipUpdate改用useCallback包裹,修复exhaustive-deps
- 修复no-explicit-any警告
- 字幕类型和常量抽离到types/subtitle.ts,满足react-refresh规则
This commit is contained in:
2026-07-17 07:41:06 +08:00
parent beb447d602
commit dbc8cb9fb2
5 changed files with 75 additions and 54 deletions
@@ -26,6 +26,7 @@ import {
ThunderboltOutlined,
CopyOutlined,
UnorderedListOutlined,
StopOutlined,
} from "@ant-design/icons";
import type { ColumnsType } from "antd/es/table";
import {
@@ -82,6 +83,11 @@ const STATUS_CONFIG: Record<
color: "error",
icon: <CloseCircleOutlined />,
},
cancelled: {
label: "已取消",
color: "default",
icon: <StopOutlined />,
},
};
/* ──────────── 工具函数 ──────────── */
@@ -89,8 +89,8 @@ import ClipPropertiesPanel from "./components/ClipPropertiesPanel";
import EditorClipList from "./components/EditorClipList";
import BgmSelector from "./components/BgmSelector";
import SubtitleStylePanel from "./components/SubtitleStylePanel";
import type { SubtitleStyleConfig } from "./components/SubtitleStylePanel";
import { DEFAULT_SUBTITLE_STYLE } from "./components/SubtitleStylePanel";
import type { SubtitleStyleConfig } from "./types/subtitle";
import { DEFAULT_SUBTITLE_STYLE } from "./types/subtitle";
import TransitionSelector from "./components/TransitionSelector";
import SpeedPanel from "./components/SpeedPanel";
import TtsPanel from "./components/TtsPanel";
@@ -626,11 +626,14 @@ const EditingPlanner: React.FC = () => {
if (selectedClipId === clipId) setSelectedClipId(null);
};
const handleClipUpdate = (clipId: string, data: Partial<ClipData>) => {
setClips((prev) =>
prev.map((c) => (c.id === clipId ? { ...c, ...data } : c)),
);
};
const handleClipUpdate = useCallback(
(clipId: string, data: Partial<ClipData>) => {
setClips((prev) =>
prev.map((c) => (c.id === clipId ? { ...c, ...data } : c)),
);
},
[setClips],
);
/**
* 添加片段(不绑定任何素材)
@@ -738,7 +741,7 @@ const EditingPlanner: React.FC = () => {
}
// 同时更新全局默认转场(供新片段使用)
},
[transitionTargetClipId],
[transitionTargetClipId, handleClipUpdate],
);
/* ── 打开转场选择器 ── */
@@ -754,7 +757,7 @@ const EditingPlanner: React.FC = () => {
handleClipUpdate(speedTargetClipId, { speed: config });
}
},
[speedTargetClipId],
[speedTargetClipId, handleClipUpdate],
);
/* ── 打开调速面板 ── */
@@ -769,7 +772,7 @@ const EditingPlanner: React.FC = () => {
if (!ttsTargetClipId) return;
handleClipUpdate(ttsTargetClipId, { tts_config: ttsConfig });
},
[ttsTargetClipId],
[ttsTargetClipId, handleClipUpdate],
);
/* ── 打开 TTS 配音面板 ── */
@@ -782,7 +785,7 @@ const EditingPlanner: React.FC = () => {
const handleApplySpeedAll = useCallback((config: SpeedConfig) => {
setClips((prev) => prev.map((c) => ({ ...c, speed: { ...config } })));
message.success("已应用到所有片段");
}, []);
}, [setClips]);
/* ── 水印配置变更 ── */
const handleWatermarkChange = useCallback((config: WatermarkConfig) => {
@@ -1214,9 +1217,11 @@ const EditingPlanner: React.FC = () => {
message.info("取消请求已提交,正在停止...");
// 停止本地轮询,等待服务端状态通过轮询或下一次检查返回 cancelled
// 这里不立即停止,让轮询检测到 cancelled 状态后再收尾,以确保服务端确实处理了
} catch (err: any) {
} catch (err: unknown) {
console.error("[取消生成失败]", err);
const msg = err?.response?.data?.detail || "取消失败,请稍后重试";
const msg =
(err as { response?: { data?: { detail?: string } } })?.response
?.data?.detail || "取消失败,请稍后重试";
message.error(msg);
}
},
@@ -1443,7 +1448,7 @@ const EditingPlanner: React.FC = () => {
if (idx < clips.length - 1) handleClipReorder(idx, idx + 1);
}}
onRemove={handleClipRemove}
onAdd={handleAddClip}
onAdd={() => handleAddClip("pip", 3)}
/>
</div>
)}
+2 -40
View File
@@ -5,46 +5,8 @@
import React from "react";
import { Drawer, Slider, ColorPicker, Select } from "antd";
import type { Color } from "antd/es/color-picker";
/* ──────────── 类型 ──────────── */
export type SubtitleMode = "manual" | "asr";
export interface SubtitleStyleConfig {
/** 是否启用字幕 */
enabled: boolean;
/** 字幕模式:手动输入 / ASR 自动识别 */
mode: SubtitleMode;
/** 字体大小 px */
fontSize: number;
/** 字体颜色 */
fontColor: string;
/** 描边 */
stroke: boolean;
/** 阴影 */
shadow: boolean;
/** 字幕位置 */
position: "top" | "center" | "bottom";
/** 字体 */
font: string;
/** 动画效果 */
animation: string;
/** ASR 语言(仅 ASR 模式) */
asrLanguage: "zh" | "en";
}
export const DEFAULT_SUBTITLE_STYLE: SubtitleStyleConfig = {
enabled: true,
mode: "asr",
fontSize: 16,
fontColor: "#ffffff",
stroke: true,
shadow: false,
position: "bottom",
font: "思源黑体",
animation: "none",
asrLanguage: "zh",
};
import type { SubtitleMode, SubtitleStyleConfig } from "../types/subtitle";
import { DEFAULT_SUBTITLE_STYLE } from "../types/subtitle";
/* ──────────── 选项常量 ──────────── */
+2
View File
@@ -512,6 +512,8 @@ export interface ClipData {
type: ClipType; // 片段类型:voice(口播)或 pip(画中画)
duration: number; // 时长(秒)
startOffset: number; // 仅 voice 类型:在口播素材中的起始时间(秒)
/** 素材库素材 IDmain/pip 类型片段使用) */
media_asset_id?: string;
// 保留兼容字段(后端序列化需要)
template_segment_id?: string;
script_text?: string;
+46
View File
@@ -0,0 +1,46 @@
/**
* 字幕样式相关类型与常量
* 单独抽离以满足 react-refresh/only-export-components 规则
*/
/* ──────────── 类型 ──────────── */
export type SubtitleMode = "manual" | "asr";
export interface SubtitleStyleConfig {
/** 是否启用字幕 */
enabled: boolean;
/** 字幕模式:手动输入 / ASR 自动识别 */
mode: SubtitleMode;
/** 字体大小 px */
fontSize: number;
/** 字体颜色 */
fontColor: string;
/** 描边 */
stroke: boolean;
/** 阴影 */
shadow: boolean;
/** 字幕位置 */
position: "top" | "center" | "bottom";
/** 字体 */
font: string;
/** 动画效果 */
animation: string;
/** ASR 语言(仅 ASR 模式) */
asrLanguage: "zh" | "en";
}
/* ──────────── 默认值 ──────────── */
export const DEFAULT_SUBTITLE_STYLE: SubtitleStyleConfig = {
enabled: true,
mode: "asr",
fontSize: 16,
fontColor: "#ffffff",
stroke: true,
shadow: false,
position: "bottom",
font: "思源黑体",
animation: "none",
asrLanguage: "zh",
};