diff --git a/frontend/src/App.vue b/frontend/src/App.vue index 84d4ac9..15857dc 100644 --- a/frontend/src/App.vue +++ b/frontend/src/App.vue @@ -295,7 +295,7 @@ onMounted(() => { function openDifyAdmin() { // Dify 管理后台运行在 3000 端口 - window.open('http://localhost:3000', '_blank') + window.open('http://150.5.135.143:3000', '_blank') showMobileMenu.value = false } diff --git a/frontend/src/composables/usePosterWorkspace.ts b/frontend/src/composables/usePosterWorkspace.ts index 26db658..7770d3d 100644 --- a/frontend/src/composables/usePosterWorkspace.ts +++ b/frontend/src/composables/usePosterWorkspace.ts @@ -10,6 +10,7 @@ import { ref, computed, watch, onMounted } from 'vue' import { useRouter, useRoute } from 'vue-router' import api from '@/utils/api' +import { useAuth } from '@/composables/useAuth' export interface PosterTheme { primary: string @@ -172,6 +173,7 @@ function normalizeFormat(draft: PosterDraft) { export function usePosterWorkspace() { const router = useRouter() const route = useRoute() + const { user } = useAuth() // ── 核心状态 ────────────────────────────── const recordId = ref(null) @@ -180,9 +182,23 @@ export function usePosterWorkspace() { const restored = ref(false) // ── 持久化 Key ──────────────────────────── - const STORAGE_KEY = computed(() => - recordId.value ? `poster_ws_draft_${recordId.value}` : 'poster_ws_draft_new' - ) + function getStorageKey(targetRecordId: number | null = recordId.value): string { + if (!user.value?.id) return '' + const userId = encodeURIComponent(user.value.id) + return `poster_ws_draft_${userId}_${targetRecordId ?? 'new'}` + } + + const STORAGE_KEY = computed(() => getStorageKey()) + + // 旧版草稿键没有用户维度,无法安全判断归属,直接清理以避免跨账号恢复。 + try { + for (let index = localStorage.length - 1; index >= 0; index--) { + const key = localStorage.key(index) + if (key && /^poster_ws_draft_(?:new|\d+)$/.test(key)) { + localStorage.removeItem(key) + } + } + } catch { /* ignore */ } /** 需要持久化的字段(排除瞬态数据) */ function getPersistableDraft(): Partial { @@ -231,7 +247,9 @@ export function usePosterWorkspace() { // ── 持久化到 localStorage ───────────────── function persistDraft() { try { - localStorage.setItem(STORAGE_KEY.value, JSON.stringify(getPersistableDraft())) + const key = STORAGE_KEY.value + if (!key) return + localStorage.setItem(key, JSON.stringify(getPersistableDraft())) } catch { /* quota exceeded, ignore */ } } @@ -241,7 +259,9 @@ export function usePosterWorkspace() { // ── 从 localStorage 恢复 ───────────────── function tryRestoreLocal(): boolean { try { - const saved = localStorage.getItem(STORAGE_KEY.value) + const key = STORAGE_KEY.value + if (!key) return false + const saved = localStorage.getItem(key) if (saved) { const parsed = JSON.parse(saved) Object.assign(draft.value, parsed) @@ -389,6 +409,12 @@ export function usePosterWorkspace() { } function setRecordId(id: number) { + const previousKey = STORAGE_KEY.value + if (!recordId.value && previousKey) { + try { + localStorage.removeItem(previousKey) + } catch { /* ignore */ } + } recordId.value = id persistDraft() syncUrl() @@ -398,7 +424,8 @@ export function usePosterWorkspace() { function reset() { // 清理 localStorage try { - localStorage.removeItem(STORAGE_KEY.value) + const key = STORAGE_KEY.value + if (key) localStorage.removeItem(key) } catch { /* ignore */ } recordId.value = null