diff --git a/auto-imports.d.ts b/auto-imports.d.ts index 3815df9..d8af11e 100644 --- a/auto-imports.d.ts +++ b/auto-imports.d.ts @@ -8,6 +8,7 @@ export {} declare global { const EffectScope: typeof import('vue').EffectScope const ElMessage: typeof import('element-plus/es').ElMessage + const ElMessageBox: typeof import('element-plus/es').ElMessageBox const ElNotification: typeof import('element-plus/es').ElNotification const acceptHMRUpdate: typeof import('pinia').acceptHMRUpdate const computed: typeof import('vue').computed diff --git a/components.d.ts b/components.d.ts index 8cefacb..8124057 100644 --- a/components.d.ts +++ b/components.d.ts @@ -11,6 +11,7 @@ export {} /* prettier-ignore */ declare module 'vue' { export interface GlobalComponents { + 2: typeof import('./src/components/virtual-scroller/VirtualScroller copy 2.vue')['default'] Canvas: typeof import('./src/components/canvas/index.vue')['default'] copy: typeof import('./src/components/virtual-scroller/VirtualScroller copy.vue')['default'] DialogBox: typeof import('./src/components/dialogBox/index.vue')['default'] @@ -35,5 +36,7 @@ declare module 'vue' { Select: typeof import('./src/components/Select/index.vue')['default'] Time: typeof import('./src/components/dialogBox/Time/index.vue')['default'] VirtualScroller: typeof import('./src/components/virtual-scroller/VirtualScroller.vue')['default'] + 'VirtualScroller copy': typeof import('./src/components/virtual-scroller/VirtualScroller copy.vue')['default'] + 'VirtualScroller copy 2': typeof import('./src/components/virtual-scroller/VirtualScroller copy 2.vue')['default'] } } diff --git a/src/apis/display/index.js b/src/apis/display/index.js index 68f977e..f60a70d 100644 --- a/src/apis/display/index.js +++ b/src/apis/display/index.js @@ -8,4 +8,9 @@ export function getGenerateHistoryList(query) { // 取消或收藏 export function cancelOrCollect(query) { return service.post('/collect/toggle', null, { params: query }) +} + +// 删除生成历史 +export function deleteGenerateHistory(query) { + return service.delete('/taskRecordHistory/delete', { params: query }) } \ No newline at end of file diff --git a/src/components/dialogBox/index.vue b/src/components/dialogBox/index.vue index a2b2611..5bdc329 100644 --- a/src/components/dialogBox/index.vue +++ b/src/components/dialogBox/index.vue @@ -75,7 +75,6 @@ const props = defineProps({ } }) -const emit = defineEmits(['open-canvas']) const router = useRouter() const useDisplay = useDisplayStore() @@ -122,6 +121,20 @@ const handleStart = async () => { imgs.push({ name: `image_${index + 1}`, url: img.url }) }) console.log('imgs', imgs) + + const result = { + type: props.type, + model: model.value, + modelType: modelType.value, + prompt: prompt.value, + proportion: proportion.value, + referenceImages: referenceImages.value, + quantity: quantity.value, + resolution: resolution.value, + time: time.value, + videoPattern: videoPattern.value + } + const data = { AIGC: 'Painting', platform: 'runninghub', @@ -133,12 +146,32 @@ const handleStart = async () => { { name: 'aspect_ratio', data: proportion.value}, { name: 'resolution', data: resolution.value}, ], - imgs + imgs, + result } await generate(modelType.value, data) console.log('生成中', isgerenate.value) } +const fillParamsFromResult = (resultData) => { + if (!resultData) return + + if (resultData.model !== undefined) model.value = resultData.model + if (resultData.modelType !== undefined) modelType.value = resultData.modelType + if (resultData.prompt !== undefined) prompt.value = resultData.prompt + if (resultData.proportion !== undefined) proportion.value = resultData.proportion + if (resultData.referenceImages !== undefined) referenceImages.value = resultData.referenceImages + if (resultData.quantity !== undefined) quantity.value = resultData.quantity + if (resultData.resolution !== undefined) resolution.value = resultData.resolution + if (resultData.time !== undefined) time.value = resultData.time + if (resultData.videoPattern !== undefined) videoPattern.value = resultData.videoPattern +} + +defineExpose({ + fillParamsFromResult, + handleStart +}) + const handleContainerClick = () => { if (useDisplay.Sender_variant === 'default') { useDisplay.Sender_variant = 'updown' @@ -151,7 +184,7 @@ const handleScrollToBottom = () => { } const handleOpenCanvas = (data) => { - emit('open-canvas', data) + useDisplay.openCanvas(data) } watch(() => useDisplay.isSubGerenate, (newValue) => { diff --git a/src/components/virtual-scroller/VirtualScroller copy 2.vue b/src/components/virtual-scroller/VirtualScroller copy 2.vue new file mode 100644 index 0000000..a708ce2 --- /dev/null +++ b/src/components/virtual-scroller/VirtualScroller copy 2.vue @@ -0,0 +1,486 @@ + + + + + diff --git a/src/components/virtual-scroller/VirtualScroller copy.vue b/src/components/virtual-scroller/VirtualScroller copy.vue new file mode 100644 index 0000000..4ecd85e --- /dev/null +++ b/src/components/virtual-scroller/VirtualScroller copy.vue @@ -0,0 +1,518 @@ + + + + + diff --git a/src/components/virtual-scroller/VirtualScroller.vue b/src/components/virtual-scroller/VirtualScroller.vue index db45316..52b0d7e 100644 --- a/src/components/virtual-scroller/VirtualScroller.vue +++ b/src/components/virtual-scroller/VirtualScroller.vue @@ -1,613 +1,379 @@ - - diff --git a/src/router/index.js b/src/router/index.js index a234598..3949417 100644 --- a/src/router/index.js +++ b/src/router/index.js @@ -29,49 +29,47 @@ const router = createRouter({ routes }) -// router.beforeEach(async (to, from) => { -// if(to.query.token){ -// setToken(to.query.token) -// } else { -// // 检查是否有 token -// const token = getToken() -// if (!token) { -// // 没有 token,重定向到登录页 -// return '/login' -// } -// } +router.beforeEach(async (to, from) => { + if(to.query.token){ + setToken(to.query.token) + } else { + // 检查是否有 token + const token = getToken() + if (!token) { + // 没有 token,重定向到登录页 + return '/login' + } + } -// // 白名单路径(不需要验证 token 的路径) -// const whiteList = ['/login'] -// // 获取用户 store 实例 -// const userStore = useUserStore() -// // 如果访问的是白名单路径,直接放行 -// if (whiteList.includes(to.path)) { -// return true -// } + // 白名单路径(不需要验证 token 的路径) + const whiteList = ['/login'] + // 获取用户 store 实例 + const userStore = useUserStore() + // 如果访问的是白名单路径,直接放行 + if (whiteList.includes(to.path)) { + return true + } -// // 检查 token 是否有效 -// try { -// const isTokenValid = await userStore.checkTokenValid() -// console.log(isTokenValid) -// if (isTokenValid) { -// // token 有效,允许访问 -// if (!userStore.userInfo.id) { -// // 如果用户信息不存在,则从服务器获取 -// await userStore.getInfo() -// } -// return true -// } else { -// // token 无效,重定向到登录页 -// return '/login' -// } -// } catch (error) { -// // 验证过程中出错,重定向到登录页 -// console.error('验证 token 时出错:', error) -// return '/login' -// } -// }) - - router.beforeEach(async (to, from) => {return true}) + // 检查 token 是否有效 + try { + const isTokenValid = await userStore.checkTokenValid() + console.log(isTokenValid) + if (isTokenValid) { + // token 有效,允许访问 + if (!userStore.userInfo.id) { + // 如果用户信息不存在,则从服务器获取 + await userStore.getInfo() + } + return true + } else { + // token 无效,重定向到登录页 + return '/login' + } + } catch (error) { + // 验证过程中出错,重定向到登录页 + console.error('验证 token 时出错:', error) + return '/login' + } +}) export default router diff --git a/src/stores/display.js b/src/stores/display.js index 8016727..9ae44f4 100644 --- a/src/stores/display.js +++ b/src/stores/display.js @@ -6,6 +6,13 @@ const DisplayStoreSetup = () => { const currentPage = ref(0) const hasMoreData = ref(true) const isLoading = ref(false) + const currentResultData = ref(null) + const dialogBoxRef = ref(null) + + const canvasVisible = ref(false) + const canvasImage = ref('') + const canvasReferenceImages = ref([]) + const canvasSource = ref('') const addGeneratingItem = (item) => { const newItem = { @@ -49,6 +56,13 @@ const DisplayStoreSetup = () => { hasMoreData.value = true isLoading.value = false } + + const deleteHistoryItem = (id) => { + const index = tempList.value.findIndex(item => item.id === id) + if (index !== -1) { + tempList.value.splice(index, 1) + } + } const scrollToBottom = async () => { const refValue = scrollerRef.value @@ -80,6 +94,40 @@ const DisplayStoreSetup = () => { console.error('滚动出错:', error) } } + + const setResultData = (data) => { + currentResultData.value = data + } + + const setDialogBoxRef = (ref) => { + dialogBoxRef.value = ref + } + + const triggerGenerateWithResult = async () => { + if (dialogBoxRef.value && currentResultData.value) { + await dialogBoxRef.value.fillParamsFromResult(currentResultData.value) + await dialogBoxRef.value.handleStart() + } + } + + const fillParamsForEdit = () => { + if (dialogBoxRef.value && currentResultData.value) { + dialogBoxRef.value.fillParamsFromResult(currentResultData.value) + } + } + + const openCanvas = (data) => { + if (typeof data === 'string') { + canvasImage.value = data + canvasReferenceImages.value = [] + canvasSource.value = '' + } else { + canvasImage.value = data.mainImage?.url || data.mainImage || '' + canvasReferenceImages.value = data.referenceImages || [] + canvasSource.value = data.source || '' + } + canvasVisible.value = true + } return { Sender_variant, @@ -89,13 +137,25 @@ const DisplayStoreSetup = () => { currentPage, hasMoreData, isLoading, + currentResultData, + dialogBoxRef, + canvasVisible, + canvasImage, + canvasReferenceImages, + canvasSource, addGeneratingItem, updateItemToSuccess, initHistoryList, prependHistoryList, appendHistoryList, resetPagination, - scrollToBottom + scrollToBottom, + deleteHistoryItem, + setResultData, + setDialogBoxRef, + triggerGenerateWithResult, + fillParamsForEdit, + openCanvas } } diff --git a/src/utils/websocket.js b/src/utils/websocket.js index 1e5485e..f34c172 100644 --- a/src/utils/websocket.js +++ b/src/utils/websocket.js @@ -104,7 +104,8 @@ export async function generate(type, data) { taskId: taskId, text: data.prompt || '生成中...', name: data.prompt || '生成中...', - type: type + type: type, + result: data.result }) setTimeout(() => { useDisplay.scrollToBottom() diff --git a/src/views/home/display/components/set.vue b/src/views/home/display/components/set.vue index 541cd02..c03c77a 100644 --- a/src/views/home/display/components/set.vue +++ b/src/views/home/display/components/set.vue @@ -75,7 +75,7 @@
-
+
{{ item.name }}
@@ -94,7 +94,7 @@ import reEditIcon from '@/assets/display/reEdit.svg' import againGenerateIcon from '@/assets/display/againGenerate.svg' import deleteImageIcon from '@/assets/display/deleteImage.svg' import Img from '@/components/Img/index.vue' -import { cancelOrCollect } from '@/apis/display' +import { cancelOrCollect, deleteGenerateHistory } from '@/apis/display' const props = defineProps({ item: { @@ -103,7 +103,7 @@ const props = defineProps({ } }) -const emit = defineEmits(['open-canvas']) +const emit = defineEmits(['open-canvas', 'delete-success']) const useDisplay = useDisplayStore() const useParams = useParamStore() @@ -131,19 +131,45 @@ const AIbrush = (file, index) => { }) } -const reEdit = (url, number) => { - console.log(number) +const reEdit = () => { + useDisplay.setResultData(props.item.result) + useDisplay.fillParamsForEdit() } -const againGenerate = (url, number) => { - console.log(number) +const againGenerate = () => { + useDisplay.setResultData(props.item.result) + useDisplay.triggerGenerateWithResult() } -const deleteImage = (url, number) => { - console.log(number) +const deleteImage = () => { + ElMessageBox.confirm( + '确定要删除该批次图片吗?此操作不可恢复!', + '删除确认', + { + confirmButtonText: '确定删除', + cancelButtonText: '取消', + type: 'warning', + confirmButtonClass: 'el-button--danger' + } + ).then(async () => { + try { + const res = await deleteGenerateHistory({ + id: props.item.id + }) + if (res.success) { + ElMessage.success('删除成功') + emit('delete-success', props.item.id) + } else { + ElMessage.error(res.message || '删除失败') + } + } catch (error) { + console.error('删除操作失败:', error) + ElMessage.error('删除操作失败') + } + }).catch(() => {}) } -const bottomBtnGroup = [ +const bottomBtnGroup = computed(() => [ { name: '重新编辑', icon: reEditIcon, @@ -159,7 +185,7 @@ const bottomBtnGroup = [ icon: deleteImageIcon, click: deleteImage } -] +]) const addCollection = async (url) => { try { diff --git a/src/views/home/display/index.vue b/src/views/home/display/index.vue index 9937b98..74096b1 100644 --- a/src/views/home/display/index.vue +++ b/src/views/home/display/index.vue @@ -45,16 +45,20 @@ +
@@ -96,10 +100,7 @@ const scrollerRef = ref(null) const isLoadingMoreLocked = ref(false) const activeTab = ref('all') const isInitializing = ref(true) -const canvasVisible = ref(false) -const canvasImage = ref('') -const canvasReferenceImages = ref([]) -const canvasSource = ref('') +const { canvasVisible, canvasImage, canvasReferenceImages, canvasSource } = storeToRefs(useDisplay) const chargeType = computed(() => getChargeType(props.type)) console.log(chargeType.value) @@ -137,14 +138,20 @@ const conversion = (newlist) => { const temp = newlist.list.map((item) => { const files = item.fileUrl ? item.fileUrl.split(',').filter(url => url.trim()) : [] return { - id: item.taskId, + id: item.id, + taskId: item.taskId, collection: item.collection, status: 'success', prompt: item.prompt, params: item.params, + result: item.result, time: item.createTime, files: files, - collectStatus: item.collectStatus || {} + collectStatus: item.collectStatus || {}, + model: item.model || '', + proportion: item.proportion || '', + resolution: item.resolution || '', + quantity: item.quantity || 1 } }) return temp @@ -237,12 +244,13 @@ const fetchHistory = async (isLoadMore = false) => { } } -const handleScroll = (event) => { +const handleScroll = (scrollTop, scrollInfo) => { if (isInitializing.value) return - const { distanceToPageTop, distanceToPageBottom, isAtPageTop, isAtPageBottom } = event + if (!scrollInfo) return + const { isAtTop, isAtBottom, distanceToTop, distanceToBottom } = scrollInfo - if (isAtPageTop && !isLoading.value && !isLoadingMoreLocked.value && hasMoreData.value) { + if (isAtTop && !isLoading.value && !isLoadingMoreLocked.value && hasMoreData.value) { isLoadingMoreLocked.value = true fetchHistory(true) setTimeout(() => { @@ -250,24 +258,22 @@ const handleScroll = (event) => { }, 3000) } - if (isAtPageBottom) { + if (isAtBottom) { useDisplay.Sender_variant = 'updown' - } else if (distanceToPageTop >= 350) { + } else if (distanceToTop >= 350) { useDisplay.Sender_variant = 'default' } } +const handleVisibleChange = (startIndex, endIndex) => { +} + +const handleScrollStart = () => {} + +const handleScrollEnd = () => {} + const openCanvas = (data) => { - if (typeof data === 'string') { - canvasImage.value = data - canvasReferenceImages.value = [] - canvasSource.value = '' - } else { - canvasImage.value = data.mainImage?.url || data.mainImage || '' - canvasReferenceImages.value = data.referenceImages || [] - canvasSource.value = data.source || '' - } - canvasVisible.value = true + useDisplay.openCanvas(data) } const handleCanvasSend = (data) => { @@ -285,6 +291,10 @@ const handleExit = () => { } } +const handleDeleteSuccess = (id) => { + useDisplay.deleteHistoryItem(id) +} + onMounted(() => { if (!props.loading) return refreshing.value = true diff --git a/src/views/home/index.vue b/src/views/home/index.vue index ce18fb7..8000649 100644 --- a/src/views/home/index.vue +++ b/src/views/home/index.vue @@ -1,20 +1,27 @@