style: fix prettier formatting in 3 frontend files
CI/CD Pipeline / Build Production Runtime Images (push) Has been skipped
CI/CD Pipeline / Deploy Production (push) Has been skipped
CI/CD Pipeline / Production Browser E2E (push) Has been skipped
CI/CD Pipeline / Staging E2E Tests (push) Failing after 26h54m44s
CI/CD Pipeline / Build & Push Staging (Watchtower auto-deploy) (push) Failing after 27h0m5s
CI/CD Pipeline / Frontend Lint (push) Failing after 27h1m2s
CI/CD Pipeline / Validate Code Quality And Tests (push) Failing after 27h1m2s

- AssetLibrary.tsx
- GeneratePage.tsx
- VoiceLibrary.tsx

This fixes the CI Frontend Lint job failure.
This commit is contained in:
灵应
2026-07-08 09:53:24 +08:00
parent 6057ec18ce
commit 3634167dba
3 changed files with 240 additions and 86 deletions
+10 -5
View File
@@ -220,7 +220,15 @@ const AssetCard: React.FC<{
onDiagnose: () => void;
onPlay: () => void;
onDelete: () => void;
}> = ({ asset, selected, diagnosing, onToggle, onDiagnose, onPlay, onDelete }) => (
}> = ({
asset,
selected,
diagnosing,
onToggle,
onDiagnose,
onPlay,
onDelete,
}) => (
<div
className={`xx-asset-card${selected ? " xx-asset-card-selected" : ""}`}
onClick={onToggle}
@@ -264,10 +272,7 @@ const AssetCard: React.FC<{
cancelText="取消"
okButtonProps={{ danger: true }}
>
<span
className="xx-asset-delete"
onClick={(e) => e.stopPropagation()}
>
<span className="xx-asset-delete" onClick={(e) => e.stopPropagation()}>
<DeleteOutlined />
</span>
</Popconfirm>
+31 -7
View File
@@ -25,7 +25,11 @@ import {
} from "@ant-design/icons";
import type { AssetItem } from "@/api/assets";
import { getAssets, getAssetLibraries } from "@/api/assets";
import { createEditPlan, generateEditPlan, updateEditPlan } from "@/api/editPlans";
import {
createEditPlan,
generateEditPlan,
updateEditPlan,
} from "@/api/editPlans";
import { getEditingTemplates } from "@/api/editingPlanner";
import { getTitles } from "@/api/titles";
import apiClient from "@/api/client";
@@ -655,26 +659,46 @@ const GeneratePage: React.FC = () => {
const translateError = (msg: string): string => {
if (!msg) return "生成失败,请检查网络后重试或联系管理员";
// 状态机相关错误
if (msg.includes("editing") || msg.includes("draft") || msg.includes("状态")) {
if (
msg.includes("editing") ||
msg.includes("draft") ||
msg.includes("状态")
) {
return "正在准备生成,请稍候再试";
}
// 参数校验错误
if (msg.includes("template_id") || msg.includes("not found") || msg.includes("不存在")) {
if (
msg.includes("template_id") ||
msg.includes("not found") ||
msg.includes("不存在")
) {
return "所选模板或素材不可用,请重新选择";
}
if (msg.includes("asset") && (msg.includes("not found") || msg.includes("missing"))) {
if (
msg.includes("asset") &&
(msg.includes("not found") || msg.includes("missing"))
) {
return "素材数据异常,请返回素材库重新检查";
}
// 网络/超时
if (msg.includes("timeout") || msg.includes("network") || msg.includes("ECONN")) {
if (
msg.includes("timeout") ||
msg.includes("network") ||
msg.includes("ECONN")
) {
return "网络连接超时,请检查网络后重试";
}
// 配额/限制
if (msg.includes("quota") || msg.includes("limit") || msg.includes("exceed")) {
if (
msg.includes("quota") ||
msg.includes("limit") ||
msg.includes("exceed")
) {
return "已达到生成次数上限,请稍后再试或联系客服";
}
// 兜底:返回原始消息(如果已经是中文人话)或默认提示
if (msg.length > 0 && msg.length < 100 && !msg.includes("{")) return msg;
if (msg.length > 0 && msg.length < 100 && !msg.includes("{"))
return msg;
return "生成失败,请稍后重试或联系管理员";
};
const finalMsg = translateError(rawError);
+199 -74
View File
@@ -45,11 +45,7 @@ import {
toVoiceClone,
type VoiceClone,
} from "@/api/voiceClone";
import {
synthesizeSpeech,
getTTSJobStatus,
saveTtsToLibrary,
} from "@/api/tts";
import { synthesizeSpeech, getTTSJobStatus, saveTtsToLibrary } from "@/api/tts";
import {
uploadAssetDirect,
getAssetLibraries,
@@ -673,7 +669,9 @@ const VoiceLibrary: React.FC = () => {
const [ttsVoiceId, setTtsVoiceId] = useState<string>("");
const [ttsSpeed, setTtsSpeed] = useState(1.0);
const [ttsJobId, setTtsJobId] = useState<string | null>(null);
const [ttsStatus, setTtsStatus] = useState<"idle" | "synthesizing" | "done" | "error">("idle");
const [ttsStatus, setTtsStatus] = useState<
"idle" | "synthesizing" | "done" | "error"
>("idle");
const [ttsAudioUrl, setTtsAudioUrl] = useState<string | null>(null);
const [ttsError, setTtsError] = useState<string | null>(null);
const ttsTimerRef = useRef<ReturnType<typeof setInterval> | null>(null);
@@ -1222,7 +1220,14 @@ const VoiceLibrary: React.FC = () => {
width={520}
maskClosable={uploadProgress === null}
>
<div style={{ display: "flex", flexDirection: "column", gap: 16, padding: "8px 0" }}>
<div
style={{
display: "flex",
flexDirection: "column",
gap: 16,
padding: "8px 0",
}}
>
{/* 拖拽上传区 */}
<Upload.Dragger
accept="audio/*"
@@ -1239,30 +1244,54 @@ const VoiceLibrary: React.FC = () => {
showUploadList={false}
disabled={uploadProgress !== null}
>
<p style={{ fontSize: 32, color: "var(--primary-color)", marginBottom: 8 }}>
<p
style={{
fontSize: 32,
color: "var(--primary-color)",
marginBottom: 8,
}}
>
<UploadOutlined />
</p>
<p style={{ fontSize: 14, fontWeight: 500, margin: "0 0 4px" }}>
</p>
<p style={{ fontSize: 12, color: "var(--text-secondary)", margin: 0 }}>
<p
style={{
fontSize: 12,
color: "var(--text-secondary)",
margin: 0,
}}
>
MP3WAVAACFLAC 200MB
</p>
</Upload.Dragger>
{/* 已选文件信息 */}
{uploadFile && (
<div style={{
padding: "10px 12px",
background: "var(--bg-secondary)",
borderRadius: 8,
display: "flex",
alignItems: "center",
gap: 10,
}}>
<SoundOutlined style={{ fontSize: 18, color: "var(--primary-color)" }} />
<div
style={{
padding: "10px 12px",
background: "var(--bg-secondary)",
borderRadius: 8,
display: "flex",
alignItems: "center",
gap: 10,
}}
>
<SoundOutlined
style={{ fontSize: 18, color: "var(--primary-color)" }}
/>
<div style={{ flex: 1, minWidth: 0 }}>
<div style={{ fontSize: 13, fontWeight: 500, overflow: "hidden", textOverflow: "ellipsis", whiteSpace: "nowrap" }}>
<div
style={{
fontSize: 13,
fontWeight: 500,
overflow: "hidden",
textOverflow: "ellipsis",
whiteSpace: "nowrap",
}}
>
{uploadFile.name}
</div>
<div style={{ fontSize: 11, color: "var(--text-secondary)" }}>
@@ -1275,33 +1304,49 @@ const VoiceLibrary: React.FC = () => {
{/* 上传进度 */}
{uploadProgress !== null && (
<div style={{ textAlign: "center", padding: "8px 0" }}>
<div style={{ fontSize: 22, fontWeight: 700, color: "var(--primary-color)" }}>
<div
style={{
fontSize: 22,
fontWeight: 700,
color: "var(--primary-color)",
}}
>
{uploadProgress}%
</div>
<div style={{ fontSize: 12, color: "var(--text-secondary)" }}>
{uploadProgress < 100 ? "上传中..." : "处理中..."}
</div>
<div style={{
height: 4,
background: "var(--bg-tertiary)",
borderRadius: 2,
marginTop: 8,
overflow: "hidden",
}}>
<div style={{
height: "100%",
width: `${uploadProgress}%`,
background: "var(--primary-color)",
<div
style={{
height: 4,
background: "var(--bg-tertiary)",
borderRadius: 2,
transition: "width 0.3s ease",
}} />
marginTop: 8,
overflow: "hidden",
}}
>
<div
style={{
height: "100%",
width: `${uploadProgress}%`,
background: "var(--primary-color)",
borderRadius: 2,
transition: "width 0.3s ease",
}}
/>
</div>
</div>
)}
{/* 名称 */}
<div>
<div style={{ fontSize: 13, color: "var(--text-secondary)", marginBottom: 6 }}>
<div
style={{
fontSize: 13,
color: "var(--text-secondary)",
marginBottom: 6,
}}
>
</div>
<input
@@ -1325,7 +1370,13 @@ const VoiceLibrary: React.FC = () => {
{/* 性别选择 */}
<div>
<div style={{ fontSize: 13, color: "var(--text-secondary)", marginBottom: 6 }}>
<div
style={{
fontSize: 13,
color: "var(--text-secondary)",
marginBottom: 6,
}}
>
</div>
<div style={{ display: "flex", gap: 8 }}>
@@ -1340,8 +1391,14 @@ const VoiceLibrary: React.FC = () => {
padding: "6px 0",
borderRadius: 8,
border: `1px solid ${uploadGender === g ? "var(--primary-color)" : "var(--border-color)"}`,
background: uploadGender === g ? "var(--primary-soft)" : "transparent",
color: uploadGender === g ? "var(--primary-color)" : "var(--text-secondary)",
background:
uploadGender === g
? "var(--primary-soft)"
: "transparent",
color:
uploadGender === g
? "var(--primary-color)"
: "var(--text-secondary)",
fontSize: 13,
fontWeight: uploadGender === g ? 600 : 400,
cursor: uploadProgress !== null ? "not-allowed" : "pointer",
@@ -1356,7 +1413,13 @@ const VoiceLibrary: React.FC = () => {
{/* 描述 */}
<div>
<div style={{ fontSize: 13, color: "var(--text-secondary)", marginBottom: 6 }}>
<div
style={{
fontSize: 13,
color: "var(--text-secondary)",
marginBottom: 6,
}}
>
</div>
<textarea
@@ -1382,7 +1445,14 @@ const VoiceLibrary: React.FC = () => {
</div>
{/* 操作按钮 */}
<div style={{ display: "flex", justifyContent: "flex-end", gap: 10, paddingTop: 4 }}>
<div
style={{
display: "flex",
justifyContent: "flex-end",
gap: 10,
paddingTop: 4,
}}
>
<button
type="button"
onClick={() => {
@@ -1422,20 +1492,24 @@ const VoiceLibrary: React.FC = () => {
description: uploadDesc.trim(),
});
}}
disabled={!uploadFile || !uploadName.trim() || uploadProgress !== null}
disabled={
!uploadFile || !uploadName.trim() || uploadProgress !== null
}
style={{
padding: "8px 20px",
borderRadius: 8,
border: "none",
background: (!uploadFile || !uploadName.trim() || uploadProgress !== null)
? "var(--text-tertiary)"
: "var(--primary-color)",
background:
!uploadFile || !uploadName.trim() || uploadProgress !== null
? "var(--text-tertiary)"
: "var(--primary-color)",
color: "#fff",
fontSize: 13,
fontWeight: 600,
cursor: (!uploadFile || !uploadName.trim() || uploadProgress !== null)
? "not-allowed"
: "pointer",
cursor:
!uploadFile || !uploadName.trim() || uploadProgress !== null
? "not-allowed"
: "pointer",
}}
>
{uploadProgress !== null ? "上传中..." : "开始上传"}
@@ -1461,10 +1535,23 @@ const VoiceLibrary: React.FC = () => {
footer={null}
width={560}
>
<div style={{ display: "flex", flexDirection: "column", gap: 16, padding: "8px 0" }}>
<div
style={{
display: "flex",
flexDirection: "column",
gap: 16,
padding: "8px 0",
}}
>
{/* 文本输入 */}
<div>
<div style={{ fontSize: 13, color: "var(--text-secondary)", marginBottom: 6 }}>
<div
style={{
fontSize: 13,
color: "var(--text-secondary)",
marginBottom: 6,
}}
>
</div>
<textarea
@@ -1487,14 +1574,27 @@ const VoiceLibrary: React.FC = () => {
lineHeight: 1.6,
}}
/>
<div style={{ fontSize: 11, color: "var(--text-tertiary)", textAlign: "right", marginTop: 4 }}>
<div
style={{
fontSize: 11,
color: "var(--text-tertiary)",
textAlign: "right",
marginTop: 4,
}}
>
{ttsText.length}/2000
</div>
</div>
{/* 音色选择 */}
<div>
<div style={{ fontSize: 13, color: "var(--text-secondary)", marginBottom: 6 }}>
<div
style={{
fontSize: 13,
color: "var(--text-secondary)",
marginBottom: 6,
}}
>
</div>
<select
@@ -1522,7 +1622,13 @@ const VoiceLibrary: React.FC = () => {
{/* 语速 */}
<div>
<div style={{ fontSize: 13, color: "var(--text-secondary)", marginBottom: 6 }}>
<div
style={{
fontSize: 13,
color: "var(--text-secondary)",
marginBottom: 6,
}}
>
{ttsSpeed.toFixed(1)}x
</div>
<input
@@ -1534,7 +1640,14 @@ const VoiceLibrary: React.FC = () => {
onChange={(e) => setTtsSpeed(parseFloat(e.target.value))}
style={{ width: "100%", accentColor: "var(--primary-color)" }}
/>
<div style={{ display: "flex", justifyContent: "space-between", fontSize: 11, color: "var(--text-tertiary)" }}>
<div
style={{
display: "flex",
justifyContent: "space-between",
fontSize: 11,
color: "var(--text-tertiary)",
}}
>
<span>0.5x</span>
<span>1.0x</span>
<span>2.0x</span>
@@ -1551,15 +1664,17 @@ const VoiceLibrary: React.FC = () => {
padding: "10px 0",
borderRadius: 8,
border: "none",
background: (ttsStatus === "synthesizing" || !ttsText.trim())
? "var(--text-tertiary)"
: "var(--primary-color)",
background:
ttsStatus === "synthesizing" || !ttsText.trim()
? "var(--text-tertiary)"
: "var(--primary-color)",
color: "#fff",
fontSize: 14,
fontWeight: 600,
cursor: (ttsStatus === "synthesizing" || !ttsText.trim())
? "not-allowed"
: "pointer",
cursor:
ttsStatus === "synthesizing" || !ttsText.trim()
? "not-allowed"
: "pointer",
display: "flex",
alignItems: "center",
justifyContent: "center",
@@ -1572,28 +1687,38 @@ const VoiceLibrary: React.FC = () => {
{/* 错误提示 */}
{ttsError && (
<div style={{
padding: "10px 12px",
background: "var(--error-soft, #fff2f0)",
borderRadius: 8,
color: "var(--error-color, #ff4d4f)",
fontSize: 13,
}}>
<div
style={{
padding: "10px 12px",
background: "var(--error-soft, #fff2f0)",
borderRadius: 8,
color: "var(--error-color, #ff4d4f)",
fontSize: 13,
}}
>
{ttsError}
</div>
)}
{/* 合成结果 */}
{ttsStatus === "done" && ttsAudioUrl && (
<div style={{
padding: 12,
background: "var(--bg-secondary)",
borderRadius: 8,
display: "flex",
flexDirection: "column",
gap: 10,
}}>
<div style={{ fontSize: 13, fontWeight: 500, color: "var(--success-color, #52c41a)" }}>
<div
style={{
padding: 12,
background: "var(--bg-secondary)",
borderRadius: 8,
display: "flex",
flexDirection: "column",
gap: 10,
}}
>
<div
style={{
fontSize: 13,
fontWeight: 500,
color: "var(--success-color, #52c41a)",
}}
>
</div>
<audio controls src={ttsAudioUrl} style={{ width: "100%" }} />