Jelajahi Sumber

feat(frontend): 添加本地缓存功能以保存用户输入

- 在 Photography 组件中添加本地缓存功能,用于保存模特选择和场景提示词
- 在 ModelGeneration组件中实现本地缓存读取,用于初始化模特选择
- 在 ScenePromptDialog 组件中实现本地缓存读取,用于初始化场景提示词
- 优化了用户体验,避免用户重复输入相同信息
panqiuyao 3 bulan lalu
induk
melakukan
7fdcf0381d

+ 50 - 0
frontend/src/components/ModelGeneration/index.vue

@@ -111,6 +111,50 @@ const selectedFemaleModel = ref<ModelData | null>(null)
 // 选中的男模特
 const selectedMaleModel = ref<ModelData | null>(null)
 
+// 本地缓存 key
+const MODEL_SELECTION_CACHE_KEY = 'model_selection_cache'
+
+// 从本地缓存读取
+const loadModelSelectionFromCache = () => {
+  try {
+    const cache = localStorage.getItem(MODEL_SELECTION_CACHE_KEY)
+    if (cache) {
+      const parsed = JSON.parse(cache)
+      if (parsed?.female) {
+        selectedFemaleModel.value = parsed.female
+      }
+      if (parsed?.male) {
+        selectedMaleModel.value = parsed.male
+      }
+    }
+  } catch {}
+}
+
+// 写入本地缓存(只保存必要字段)
+const saveModelSelectionToCache = () => {
+  try {
+    const payload = {
+      female: selectedFemaleModel.value ? {
+        id: selectedFemaleModel.value.id,
+        name: selectedFemaleModel.value.name,
+        image_url: selectedFemaleModel.value.image_url,
+        gender: selectedFemaleModel.value.gender,
+        keywords: selectedFemaleModel.value.keywords,
+        status: selectedFemaleModel.value.status
+      } : null,
+      male: selectedMaleModel.value ? {
+        id: selectedMaleModel.value.id,
+        name: selectedMaleModel.value.name,
+        image_url: selectedMaleModel.value.image_url,
+        gender: selectedMaleModel.value.gender,
+        keywords: selectedMaleModel.value.keywords,
+        status: selectedMaleModel.value.status
+      } : null
+    }
+    localStorage.setItem(MODEL_SELECTION_CACHE_KEY, JSON.stringify(payload))
+  } catch {}
+}
+
 // 女模特列表
 const femaleModels = ref<ModelData[]>([])
 
@@ -181,6 +225,7 @@ const handleConfirm = () => {
 
 
   // 通过事件将数据发送给父组件
+  saveModelSelectionToCache()
   emit('confirm', selectedModels)
   dialogVisible.value = false
 }
@@ -242,6 +287,11 @@ watch(dialogVisible, (newValue) => {
         selectedMaleModel.value = props.initialModels.male
       }
     }
+
+    // 如果父组件未传入,尝试读取本地缓存
+    if (!props.initialModels || (!props.initialModels.female && !props.initialModels.male)) {
+      loadModelSelectionFromCache()
+    }
   }
 }, { immediate: true })
 </script>

+ 30 - 2
frontend/src/components/ScenePromptDialog/index.vue

@@ -56,6 +56,29 @@ const dialogVisible = computed({
 // 场景提示词
 const scenePrompt = ref('')
 
+// 本地缓存 key
+const SCENE_PROMPT_CACHE_KEY = 'scene_prompt_cache'
+
+// 从本地缓存读取
+const loadScenePromptFromCache = () => {
+  try {
+    const cache = localStorage.getItem(SCENE_PROMPT_CACHE_KEY)
+    if (cache && !props.initialPrompt) {
+      scenePrompt.value = cache
+    }
+  } catch {}
+}
+
+// 写入本地缓存
+const saveScenePromptToCache = () => {
+  try {
+    const value = (scenePrompt.value || '').trim()
+    if (value) {
+      localStorage.setItem(SCENE_PROMPT_CACHE_KEY, value)
+    }
+  } catch {}
+}
+
 // AI 加载状态
 const aiLoading = ref(false)
 
@@ -91,6 +114,7 @@ const handleAIHelp = async () => {
 const handleConfirm = () => {
   if (!canConfirm.value) return
 
+  saveScenePromptToCache()
   emit('confirm', scenePrompt.value.trim())
   dialogVisible.value = false
   resetForm()
@@ -109,8 +133,12 @@ const resetForm = () => {
 
 // 监听弹窗显示状态变化,初始化场景提示词
 watch(dialogVisible, (newValue) => {
-  if (newValue && props.initialPrompt) {
-    scenePrompt.value = props.initialPrompt
+  if (newValue) {
+    if (props.initialPrompt) {
+      scenePrompt.value = props.initialPrompt
+    } else {
+      loadScenePromptFromCache()
+    }
   }
 }, { immediate: true })
 </script>

+ 63 - 0
frontend/src/views/Photography/detail.vue

@@ -453,6 +453,8 @@ onMounted(() => {
   goods_art_nos.value = Array.isArray(goods_art_data) ? goods_art_data : [goods_art_data]
   getCompanyTemplates()
   getLogolist()
+
+  loadDetailCache()
 })
 
 // 页面卸载时清理监听器
@@ -529,6 +531,65 @@ const scenePromptDialogVisible = ref(false)
 const selectedModels = ref<{ female: any; male: any } | null>(null)
 const scenePrompt = ref('')
 
+// 本地缓存键(与弹窗组件保持一致)
+const DETAIL_MODEL_CACHE_KEY = 'model_selection_cache'
+const DETAIL_SCENE_PROMPT_CACHE_KEY = 'scene_prompt_cache'
+
+// 读取本地缓存
+const loadDetailCache = () => {
+  console.log('loadDetailCache');
+  try {
+    const m = localStorage.getItem(DETAIL_MODEL_CACHE_KEY)
+    if (m) {
+      const parsed = JSON.parse(m)
+      if (parsed && (parsed.female || parsed.male)) {
+        selectedModels.value = parsed
+        console.log('loadDetailCache');
+        console.log(selectedModels.value);
+      }
+    }
+  } catch {}
+  try {
+    const p = localStorage.getItem(DETAIL_SCENE_PROMPT_CACHE_KEY)
+    if (p) {
+      console.log('scenePrompt');
+      scenePrompt.value = p
+      console.log(scenePrompt.value);
+    }
+  } catch {}
+}
+
+// 保存到本地缓存(仅保存必要字段)
+const saveModelsToCache = (models: { female: any; male: any }) => {
+  try {
+    const payload = {
+      female: models?.female ? {
+        id: models.female.id,
+        name: models.female.name,
+        image_url: models.female.image_url,
+        gender: models.female.gender,
+        keywords: models.female.keywords,
+        status: models.female.status
+      } : null,
+      male: models?.male ? {
+        id: models.male.id,
+        name: models.male.name,
+        image_url: models.male.image_url,
+        gender: models.male.gender,
+        keywords: models.male.keywords,
+        status: models.male.status
+      } : null
+    }
+    localStorage.setItem(DETAIL_MODEL_CACHE_KEY, JSON.stringify(payload))
+  } catch {}
+}
+const saveScenePromptToCache = (prompt: string) => {
+  try {
+    const v = (prompt || '').trim()
+    if (v) localStorage.setItem(DETAIL_SCENE_PROMPT_CACHE_KEY, v)
+  } catch {}
+}
+
 const openModelDialog = () => {
   modelDialogVisible.value = true
 }
@@ -537,11 +598,13 @@ const openScenePromptDialog = () => {
 }
 const handleModelSelection = (models: { female: any; male: any }) => {
   selectedModels.value = models
+  saveModelsToCache(models)
   modelDialogVisible.value = false
   ElMessage.success('模特选择完成!')
 }
 const handleScenePromptConfirm = (prompt: string) => {
   scenePrompt.value = prompt
+  saveScenePromptToCache(prompt)
 }