This commit is contained in:
949036910@qq.com
2026-06-03 22:12:26 +08:00
parent 328ee75be5
commit efed871f57
3 changed files with 119 additions and 20 deletions

View File

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

View File

@@ -1,7 +1,11 @@
import { invoke } from "@tauri-apps/api/core"; import { invoke } from "@tauri-apps/api/core";
import { listen } from "@tauri-apps/api/event";
import { resolveStep4TitleForCover } from "../utils/coverTextSplit.js"; import { resolveStep4TitleForCover } from "../utils/coverTextSplit.js";
const PUBLISH_LOGIN_SCRIPT = "publish_login.js";
const NODEJS_EVENT = "nodejs:event";
export const PUBLISH_PLATFORM_DEFS = [ export const PUBLISH_PLATFORM_DEFS = [
{ key: "douyin", label: "抖音" }, { key: "douyin", label: "抖音" },
{ key: "kuaishou", label: "快手" }, { key: "kuaishou", label: "快手" },
@@ -52,6 +56,46 @@ export async function refreshPublishAccounts(store) {
} }
} }
/**
* @param {ReturnType<typeof import('../stores/workflow.js').useWorkflowStore>} 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<typeof import('../stores/workflow.js').useWorkflowStore>} store * @param {ReturnType<typeof import('../stores/workflow.js').useWorkflowStore>} store
* @param {string} platformKey * @param {string} platformKey
@@ -61,7 +105,33 @@ export async function loginPublishPlatform(store, platformKey, accountId = undef
if (!row) return { ok: false, message: "未知平台" }; if (!row) return { ok: false, message: "未知平台" };
store.publishLoggingIn = platformKey; store.publishLoggingIn = platformKey;
store.publishStatus = "正在准备扫码登录…";
let unlisten = null;
try { 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", { const result = await invoke("publish_login", {
params: { params: {
platform: platformKey, platform: platformKey,
@@ -69,10 +139,11 @@ export async function loginPublishPlatform(store, platformKey, accountId = undef
}, },
}); });
if (!result?.success) { if (!result?.success) {
return { const errMsg = String(
ok: false, result?.error || result?.message || "登录失败,请查看是否已安装 Chrome",
message: String(result?.error || result?.message || "登录失败"), );
}; store.publishStatus = errMsg;
return { ok: false, message: errMsg };
} }
if (result.account) { if (result.account) {
row.accountId = result.account.id; row.accountId = result.account.id;
@@ -80,15 +151,21 @@ export async function loginPublishPlatform(store, platformKey, accountId = undef
row.nickname = result.account.nickname || ""; row.nickname = result.account.nickname || "";
} }
await refreshPublishAccounts(store); await refreshPublishAccounts(store);
return { const okMsg = String(result.message || "登录成功");
ok: true, store.publishStatus = okMsg;
message: String(result.message || "登录成功"), return { ok: true, message: okMsg };
};
} catch (err) { } catch (err) {
const msg = err instanceof Error ? err.message : String(err); const msg = err instanceof Error ? err.message : String(err);
store.publishStatus = `登录失败:${msg}`;
return { ok: false, message: `登录失败:${msg}` }; return { ok: false, message: `登录失败:${msg}` };
} finally { } finally {
if (typeof unlisten === "function") {
unlisten();
}
store.publishLoggingIn = ""; store.publishLoggingIn = "";
if (!store.publishStatus || store.publishStatus.startsWith("正在")) {
store.publishStatus = "";
}
} }
} }

View File

@@ -50,6 +50,7 @@ import {
checkPublishLoginStatus, checkPublishLoginStatus,
openPublishAccount, openPublishAccount,
loginPublishPlatform, loginPublishPlatform,
deletePublishAccount,
refreshPublishAccounts, refreshPublishAccounts,
} from "../services/videoPublish.js"; } from "../services/videoPublish.js";
import { SUBTITLE_TEMPLATES } from "../config/subtitleTemplates.js"; import { SUBTITLE_TEMPLATES } from "../config/subtitleTemplates.js";
@@ -721,6 +722,10 @@ export const useWorkflowStore = defineStore("workflow", {
return loginPublishPlatform(this, platformKey, accountId); return loginPublishPlatform(this, platformKey, accountId);
}, },
async deletePublishAccount(platformKey, accountId) {
return deletePublishAccount(this, platformKey, accountId);
},
async checkPublishLoginStatus(platformKey, accountId = null, checkBrowser = true) { async checkPublishLoginStatus(platformKey, accountId = null, checkBrowser = true) {
return checkPublishLoginStatus(this, platformKey, accountId, checkBrowser); return checkPublishLoginStatus(this, platformKey, accountId, checkBrowser);
}, },