feat: implement History view
This commit is contained in:
@@ -0,0 +1,21 @@
|
||||
import api from './index'
|
||||
|
||||
export interface HistoryItem {
|
||||
id: string
|
||||
original_prompt: string
|
||||
optimized_prompt: string
|
||||
mode: string
|
||||
model: string
|
||||
image_url: string
|
||||
input_image_url: string | null
|
||||
created_at: string
|
||||
}
|
||||
|
||||
export const historyApi = {
|
||||
getHistory() {
|
||||
return api.get<HistoryItem[]>('/history')
|
||||
},
|
||||
deleteHistory(id: string) {
|
||||
return api.delete(`/history/${id}`)
|
||||
},
|
||||
}
|
||||
@@ -0,0 +1,120 @@
|
||||
<template>
|
||||
<div class="min-h-screen bg-gray-50">
|
||||
<nav class="bg-white shadow">
|
||||
<div class="max-w-7xl mx-auto px-4 py-4 flex justify-between items-center">
|
||||
<h1 class="text-xl font-bold">ImageCreator</h1>
|
||||
<div class="flex gap-4">
|
||||
<router-link to="/" class="text-blue-500">生成</router-link>
|
||||
<router-link to="/history" class="text-blue-500">历史</router-link>
|
||||
<n-button size="small" @click="handleLogout">退出</n-button>
|
||||
</div>
|
||||
</div>
|
||||
</nav>
|
||||
|
||||
<div class="max-w-6xl mx-auto px-4 py-8">
|
||||
<h2 class="text-2xl font-bold mb-6">生成历史</h2>
|
||||
|
||||
<div v-if="loading" class="flex justify-center py-8">
|
||||
<n-spin size="large" />
|
||||
</div>
|
||||
|
||||
<div v-else-if="history.length === 0" class="text-center text-gray-400 py-8">
|
||||
暂无历史记录
|
||||
</div>
|
||||
|
||||
<n-grid v-else :cols="3" :x-gap="16" :y-gap="16">
|
||||
<n-gi v-for="item in history" :key="item.id">
|
||||
<n-card class="h-full">
|
||||
<template #header>
|
||||
<div class="flex justify-between items-center">
|
||||
<span class="text-sm text-gray-500">{{ item.mode === 'text2image' ? '文生图' : '图生图' }}</span>
|
||||
<n-button text type="error" size="small" @click="handleDelete(item.id)">
|
||||
删除
|
||||
</n-button>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<img
|
||||
:src="item.image_url"
|
||||
class="w-full h-48 object-cover rounded"
|
||||
alt="Generated"
|
||||
/>
|
||||
|
||||
<div class="mt-4">
|
||||
<p class="text-sm text-gray-500 mb-1">原始提示词:</p>
|
||||
<p class="text-sm">{{ item.original_prompt }}</p>
|
||||
</div>
|
||||
|
||||
<div class="mt-2">
|
||||
<p class="text-sm text-gray-500 mb-1">优化后:</p>
|
||||
<p class="text-sm">{{ item.optimized_prompt }}</p>
|
||||
</div>
|
||||
|
||||
<template #footer>
|
||||
<div class="text-xs text-gray-400">
|
||||
{{ formatDate(item.created_at) }} | {{ item.model }}
|
||||
</div>
|
||||
</template>
|
||||
</n-card>
|
||||
</n-gi>
|
||||
</n-grid>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref, onMounted } from 'vue'
|
||||
import { useRouter } from 'vue-router'
|
||||
import { NCard, NGrid, NGi, NButton, NSpin, useMessage, useDialog } from 'naive-ui'
|
||||
import { useAuthStore } from '../stores/auth'
|
||||
import { historyApi, HistoryItem } from '../api/history'
|
||||
|
||||
const router = useRouter()
|
||||
const message = useMessage()
|
||||
const dialog = useDialog()
|
||||
const authStore = useAuthStore()
|
||||
|
||||
const history = ref<HistoryItem[]>([])
|
||||
const loading = ref(false)
|
||||
|
||||
const fetchHistory = async () => {
|
||||
loading.value = true
|
||||
try {
|
||||
const response = await historyApi.getHistory()
|
||||
history.value = response.data
|
||||
} catch (error) {
|
||||
message.error('获取历史失败')
|
||||
} finally {
|
||||
loading.value = false
|
||||
}
|
||||
}
|
||||
|
||||
const handleDelete = (id: string) => {
|
||||
dialog.warning({
|
||||
title: '确认删除',
|
||||
content: '确定要删除这条记录吗?',
|
||||
positiveText: '确定',
|
||||
negativeText: '取消',
|
||||
onPositiveClick: async () => {
|
||||
try {
|
||||
await historyApi.deleteHistory(id)
|
||||
message.success('删除成功')
|
||||
fetchHistory()
|
||||
} catch (error) {
|
||||
message.error('删除失败')
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
const formatDate = (dateStr: string) => {
|
||||
return new Date(dateStr).toLocaleString('zh-CN')
|
||||
}
|
||||
|
||||
const handleLogout = () => {
|
||||
authStore.logout()
|
||||
router.push('/login')
|
||||
}
|
||||
|
||||
onMounted(fetchHistory)
|
||||
</script>
|
||||
Reference in New Issue
Block a user