diff --git a/src/components/workflow/Step07Publish.vue b/src/components/workflow/Step07Publish.vue index 20116a6..cc0864a 100644 --- a/src/components/workflow/Step07Publish.vue +++ b/src/components/workflow/Step07Publish.vue @@ -8,6 +8,7 @@ const { publishPlatforms, publishing, publishLoggingIn, + publishStatus, titleGenerated, coverImagePath, generatedVideoPath, @@ -17,6 +18,8 @@ const { } = storeToRefs(workflow); const feedback = ref({ severity: "", message: "" }); +/** 账号管理弹窗内提示(避免被 Dialog 挡住主卡片 feedback) */ +const accountFeedback = ref({ severity: "", message: "" }); const scheduleDialogVisible = ref(false); const scheduleDate = ref(null); const accountDialogVisible = ref(false); @@ -60,11 +63,13 @@ const activePlatform = computed( ); function showFeedback(result) { - if (!result?.message) return; + const message = String(result?.message || result?.error || "").trim(); + if (!message) return; feedback.value = { severity: result.ok ? "success" : "error", - message: result.message, + message, }; + accountFeedback.value = feedback.value; } onMounted(async () => { @@ -75,6 +80,7 @@ function openAccountManager() { if (publishPlatforms.value.length && !activePlatform.value) { activePlatformKey.value = publishPlatforms.value[0].key; } + accountFeedback.value = { severity: "", message: "" }; accountDialogVisible.value = true; } @@ -117,6 +123,7 @@ function cancelSchedule() { async function onLogin(platform, accountId = undefined) { feedback.value = { severity: "", message: "" }; + accountFeedback.value = { severity: "", message: "" }; showFeedback(await workflow.loginPublishPlatform(platform.key, accountId)); } @@ -142,16 +149,11 @@ async function onOpenAccount(platform, account) { showFeedback(result); } -function onDeleteAccount(platform, account) { - platform.accounts = (platform.accounts || []).filter((a) => a.id !== account.id); - if (platform.accountId === account.id) { - platform.accountId = null; - } - if (!platform.accounts.length) { - platform.loggedIn = false; - platform.nickname = ""; - } - feedback.value = { severity: "success", message: "已从本地列表移除账号,刷新后可重新获取" }; +async function onDeleteAccount(platform, account) { + accountFeedback.value = { severity: "", message: "" }; + showFeedback( + await workflow.deletePublishAccount(platform.key, account.id), + ); } function formatAccountStatus(account) { @@ -294,6 +296,21 @@ function formatUpdateTime(account) { modal :style="{ width: '640px' }" > +

+ {{ publishStatus }} +

+

+ {{ accountFeedback.message }} +

} store + * @param {string} platformKey + * @param {number} accountId + */ +export async function deletePublishAccount(store, platformKey, accountId) { + const row = store.publishPlatforms.find((p) => p.key === platformKey); + if (!row) return { ok: false, message: "未知平台" }; + + const id = Number(accountId); + if (!Number.isFinite(id) || id <= 0) { + return { ok: false, message: "无效的账号 ID" }; + } + + try { + await invoke("publish_delete_account", { accountId: id }); + row.accounts = (row.accounts || []).filter((a) => a.id !== id); + if (row.accountId === id) { + row.accountId = null; + row.loggedIn = false; + row.nickname = ""; + } else { + const active = row.accounts.find( + (a) => a.loginStatus === "active" && a.hasCookies, + ); + if (active) { + row.loggedIn = true; + row.nickname = active.nickname || ""; + } else if (!row.accounts.length) { + row.loggedIn = false; + row.nickname = ""; + } + } + return { ok: true, message: "账号已删除" }; + } catch (err) { + const msg = err instanceof Error ? err.message : String(err); + return { ok: false, message: `删除失败:${msg}` }; + } +} + /** * @param {ReturnType} store * @param {string} platformKey @@ -61,7 +105,33 @@ export async function loginPublishPlatform(store, platformKey, accountId = undef if (!row) return { ok: false, message: "未知平台" }; store.publishLoggingIn = platformKey; + store.publishStatus = "正在准备扫码登录…"; + + let unlisten = null; try { + try { + unlisten = await listen(NODEJS_EVENT, (e) => { + const p = e.payload; + const forLogin = + !p?.scriptName || p.scriptName === PUBLISH_LOGIN_SCRIPT; + if (!forLogin) return; + if (p?.type === "progress" && typeof p.status === "string") { + store.publishStatus = p.status; + } else if (p?.type === "log") { + const text = + p.fields != null ? `${p.msg} ${JSON.stringify(p.fields)}` : p.msg; + if (p.level === "error") { + store.publishStatus = text; + console.error(`[nodejs/${PUBLISH_LOGIN_SCRIPT}]`, text); + } else { + console.info(`[nodejs/${PUBLISH_LOGIN_SCRIPT}]`, text); + } + } + }); + } catch { + /* 非 Tauri 环境 */ + } + const result = await invoke("publish_login", { params: { platform: platformKey, @@ -69,10 +139,11 @@ export async function loginPublishPlatform(store, platformKey, accountId = undef }, }); if (!result?.success) { - return { - ok: false, - message: String(result?.error || result?.message || "登录失败"), - }; + const errMsg = String( + result?.error || result?.message || "登录失败,请查看是否已安装 Chrome", + ); + store.publishStatus = errMsg; + return { ok: false, message: errMsg }; } if (result.account) { row.accountId = result.account.id; @@ -80,15 +151,21 @@ export async function loginPublishPlatform(store, platformKey, accountId = undef row.nickname = result.account.nickname || ""; } await refreshPublishAccounts(store); - return { - ok: true, - message: String(result.message || "登录成功"), - }; + const okMsg = String(result.message || "登录成功"); + store.publishStatus = okMsg; + return { ok: true, message: okMsg }; } catch (err) { const msg = err instanceof Error ? err.message : String(err); + store.publishStatus = `登录失败:${msg}`; return { ok: false, message: `登录失败:${msg}` }; } finally { + if (typeof unlisten === "function") { + unlisten(); + } store.publishLoggingIn = ""; + if (!store.publishStatus || store.publishStatus.startsWith("正在")) { + store.publishStatus = ""; + } } } diff --git a/src/stores/workflow.js b/src/stores/workflow.js index 4b3ea13..c5dd6d7 100644 --- a/src/stores/workflow.js +++ b/src/stores/workflow.js @@ -50,6 +50,7 @@ import { checkPublishLoginStatus, openPublishAccount, loginPublishPlatform, + deletePublishAccount, refreshPublishAccounts, } from "../services/videoPublish.js"; import { SUBTITLE_TEMPLATES } from "../config/subtitleTemplates.js"; @@ -721,6 +722,10 @@ export const useWorkflowStore = defineStore("workflow", { return loginPublishPlatform(this, platformKey, accountId); }, + async deletePublishAccount(platformKey, accountId) { + return deletePublishAccount(this, platformKey, accountId); + }, + async checkPublishLoginStatus(platformKey, accountId = null, checkBrowser = true) { return checkPublishLoginStatus(this, platformKey, accountId, checkBrowser); },