diff --git a/src/components/workflow/Step04TitleTags.vue b/src/components/workflow/Step04TitleTags.vue
index 5ffded8..8c8eb16 100644
--- a/src/components/workflow/Step04TitleTags.vue
+++ b/src/components/workflow/Step04TitleTags.vue
@@ -14,14 +14,22 @@ const {
keywordsEmotion,
titleTagsGenerating,
scriptContent,
+ titleTagPrompt,
} = storeToRefs(workflow);
const feedback = ref({ severity: "", message: "" });
+const promptExpanded = ref(false);
const canGenerate = computed(
() => Boolean(scriptContent.value?.trim()) && !titleTagsGenerating.value,
);
+const titleLineCount = computed(() => {
+ const text = String(titleGenerated.value || "").trim();
+ if (!text) return 0;
+ return text.split("\n").filter((line) => line.trim()).length;
+});
+
function showFeedback(result) {
if (!result?.message) return;
feedback.value = {
@@ -63,11 +71,37 @@ async function onGenerateTitleTags() {
-
生成的标题(可编辑)
+
+
+
+
+
+
+ 生成的标题(可编辑)
+
+ 共 {{ titleLineCount }} 条建议,可选用其一或自行修改
+
+
diff --git a/src/services/titleTagsGenerate.js b/src/services/titleTagsGenerate.js
index c65bb4c..8d169b7 100644
--- a/src/services/titleTagsGenerate.js
+++ b/src/services/titleTagsGenerate.js
@@ -27,6 +27,54 @@ async function loadTitleTagPromptOverride() {
}
}
+/**
+ * @param {string} titleTagsJson
+ */
+function applyTitleTagsJson(store, titleTagsJson) {
+ let payload = titleTagsJson.trim();
+ payload = payload.replace(/```json\s*/gi, "");
+ payload = payload.replace(/```\s*/g, "");
+ payload = payload.trim();
+ const match = payload.match(/\{[\s\S]*\}/);
+ if (match) payload = match[0];
+
+ console.log("[generateTitleTags] 清理后的JSON:", payload);
+ const parsed = JSON.parse(payload);
+
+ const title = parsed.title;
+ store.titleGenerated = Array.isArray(title)
+ ? title.filter(Boolean).join("\n")
+ : String(title || "").trim();
+
+ store.tagsGenerated = Array.isArray(parsed.tags)
+ ? parsed.tags.join(", ")
+ : String(parsed.tags || "").trim();
+
+ const kw = parsed.keywords;
+ if (kw && typeof kw === "object" && !Array.isArray(kw)) {
+ console.log("[generateTitleTags] ✅ 检测到分类关键词格式:", kw);
+ for (const { key, field } of KEYWORD_GROUPS) {
+ const groupVal = kw[key];
+ const text = Array.isArray(groupVal)
+ ? groupVal.filter((w) => w && String(w).trim()).join("\n")
+ : String(groupVal || "").trim();
+ store[field] = text;
+ console.log(`[generateTitleTags] 📝 更新 ${key}: ${text.length} 字符`);
+ }
+ } else if (Array.isArray(kw)) {
+ store.keywordsFocus = kw.filter(Boolean).join("\n");
+ store.keywordsDescribe = "";
+ store.keywordsAction = "";
+ store.keywordsEmotion = "";
+ } else {
+ for (const { field } of KEYWORD_GROUPS) {
+ store[field] = "";
+ }
+ }
+
+ console.log("[generateTitleTags] ✅ 标题标签关键词已写入 store");
+}
+
/**
* 生成标题、标签、关键词(对齐 Electron generateTitleTags)
* @param {ReturnType} store
@@ -47,6 +95,11 @@ export async function executeGenerateTitleTags(store) {
store.titleTagPrompt?.trim() ||
null;
+ console.log("[generateTitleTags] 开始生成", {
+ scriptLength: content.length,
+ hasCustomPrompt: Boolean(titleTagPrompt),
+ });
+
store.titleTagsGenerating = true;
try {
@@ -61,30 +114,47 @@ export async function executeGenerateTitleTags(store) {
if (!result?.success) {
if (result?.rawContent) {
store.titleGenerated = String(result.rawContent).trim();
+ console.error("[generateTitleTags] 解析失败,原始内容:", result.rawContent);
return {
ok: false,
message: String(result.error || "结果解析失败,已将原始内容填入标题框"),
};
}
+ console.error("[generateTitleTags] 生成失败:", result?.error);
return {
ok: false,
message: String(result?.error || "生成失败,请重试"),
};
}
- store.titleGenerated = String(result.title || "").trim();
- store.tagsGenerated = String(result.tags || "").trim();
-
- const kw = result.keywords || {};
- for (const { key, field } of KEYWORD_GROUPS) {
- store[field] = String(kw[key] || "").trim();
+ if (result.titleTags) {
+ try {
+ applyTitleTagsJson(store, result.titleTags);
+ } catch (err) {
+ console.error("[generateTitleTags] JSON解析错误:", err);
+ console.error("[generateTitleTags] 原始内容:", result.titleTags);
+ store.titleGenerated = String(result.title || result.titleTags || "").trim();
+ store.tagsGenerated = String(result.tags || "").trim();
+ return {
+ ok: false,
+ message: "结果解析失败,请检查返回格式",
+ };
+ }
+ } else {
+ store.titleGenerated = String(result.title || "").trim();
+ store.tagsGenerated = String(result.tags || "").trim();
+ const kw = result.keywords || {};
+ for (const { key, field } of KEYWORD_GROUPS) {
+ store[field] = String(kw[key] || "").trim();
+ }
}
return { ok: true, message: "标题、标签和关键词生成完成" };
} catch (err) {
const msg = err instanceof Error ? err.message : String(err || "未知错误");
+ console.error("[generateTitleTags] 网络或调用失败:", err);
return { ok: false, message: `生成失败:${msg}` };
} finally {
store.titleTagsGenerating = false;
}
-}
\ No newline at end of file
+}
diff --git a/src/stores/workflow.js b/src/stores/workflow.js
index 8423e1d..57beaf1 100644
--- a/src/stores/workflow.js
+++ b/src/stores/workflow.js
@@ -105,7 +105,7 @@ export const useWorkflowStore = defineStore("workflow", {
/** 标题标签关键词提示词(对齐 zhenqianba titleTagPrompt) */
titleTagPrompt:
- "你是短视频标题与标签助手。分析文案内容 {{content}},生成吸引人的标题、相关标签,以及四个分组关键词(重点词/成语词、描述词、行动词、情感词,每组 0-2 个词)。",
+ "你是短视频标题与标签助手。分析文案内容 {{content}},生成5个吸引眼球的标题建议、10个相关标签、4个分组关键词(每组:重点词/成语词、描述词、行动词、情感词,每个分组只要0-2个词不要多)。",
videoLinkModalVisible: false,