From a1d7e81859f554f3a53680cc35f0f49bf1f77098 Mon Sep 17 00:00:00 2001
From: wwf <1971391498@qq.com>
Date: 星期四, 14 五月 2026 14:37:02 +0800
Subject: [PATCH] 导入项目
---
src/views/ai/image/index/components/ImageList.vue | 208 ++++++++++++++++++++++++++++++++++++++++++++++++++++
1 files changed, 208 insertions(+), 0 deletions(-)
diff --git a/src/views/ai/image/index/components/ImageList.vue b/src/views/ai/image/index/components/ImageList.vue
new file mode 100644
index 0000000..5169e45
--- /dev/null
+++ b/src/views/ai/image/index/components/ImageList.vue
@@ -0,0 +1,208 @@
+<template>
+ <el-card
+ class="wh-full"
+ :body-style="{ margin: 0, padding: 0, height: '100%', position: 'relative' }"
+ shadow="never"
+ >
+ <template #header>
+ 缁樼敾浠诲姟
+ <!-- TODO @fan锛氱湅鐪嬶紝鎬庝箞浼樺寲涓嬭繖涓牱瀛愬搱銆� -->
+ <el-button @click="handleViewPublic">缁樼敾浣滃搧</el-button>
+ </template>
+ <!-- 鍥剧墖鍒楄〃 -->
+ <div
+ class="relative flex flex-row flex-wrap content-start h-full overflow-auto p-5 pb-[140px] box-border [&>div]:mr-5 [&>div]:mb-5"
+ ref="imageListRef"
+ >
+ <ImageCard
+ v-for="image in imageList"
+ :key="image.id"
+ :detail="image"
+ @on-btn-click="handleImageButtonClick"
+ @on-mj-btn-click="handleImageMidjourneyButtonClick"
+ />
+ </div>
+ <div
+ class="absolute bottom-[60px] h-[50px] leading-[90px] w-full z-[999] bg-white flex flex-row justify-center items-center"
+ >
+ <Pagination
+ :total="pageTotal"
+ v-model:page="queryParams.pageNo"
+ v-model:limit="queryParams.pageSize"
+ @pagination="getImageList"
+ />
+ </div>
+ </el-card>
+
+ <!-- 鍥剧墖璇︽儏 -->
+ <ImageDetail
+ :show="isShowImageDetail"
+ :id="showImageDetailId"
+ @handle-drawer-close="handleDetailClose"
+ />
+</template>
+<script setup lang="ts">
+import {
+ ImageApi,
+ ImageVO,
+ ImageMidjourneyActionVO,
+ ImageMidjourneyButtonsVO
+} from '@/api/ai/image'
+import ImageDetail from './ImageDetail.vue'
+import ImageCard from './ImageCard.vue'
+import { ElLoading, LoadingOptionsResolved } from 'element-plus'
+import { AiImageStatusEnum } from '@/views/ai/utils/constants'
+import download from '@/utils/download'
+
+const message = useMessage() // 娑堟伅寮圭獥
+const router = useRouter() // 璺敱
+
+// 鍥剧墖鍒嗛〉鐩稿叧鐨勫弬鏁�
+const queryParams = reactive({
+ pageNo: 1,
+ pageSize: 10
+})
+const pageTotal = ref<number>(0) // page size
+const imageList = ref<ImageVO[]>([]) // image 鍒楄〃
+const imageListLoadingInstance = ref<any>() // image 鍒楄〃鏄惁姝e湪鍔犺浇涓�
+const imageListRef = ref<any>() // ref
+// 鍥剧墖杞鐩稿叧鐨勫弬鏁帮紙姝e湪鐢熸垚涓殑锛�
+const inProgressImageMap = ref<{}>({}) // 鐩戝惉鐨� image 鏄犲皠锛屼竴鑸槸鐢熸垚涓紙闇�瑕佽疆璇級锛宬ey 涓� image 缂栧彿锛寁alue 涓� image
+const inProgressTimer = ref<any>() // 鐢熸垚涓殑 image 瀹氭椂鍣紝杞鐢熸垚杩涘睍
+// 鍥剧墖璇︽儏鐩稿叧鐨勫弬鏁�
+const isShowImageDetail = ref<boolean>(false) // 鍥剧墖璇︽儏鏄惁灞曠ず
+const showImageDetailId = ref<number>(0) // 鍥剧墖璇︽儏鐨勫浘鐗囩紪鍙�
+
+/** 澶勭悊鏌ョ湅缁樺浘浣滃搧 */
+const handleViewPublic = () => {
+ router.push({
+ name: 'AiImageSquare'
+ })
+}
+
+/** 鏌ョ湅鍥剧墖鐨勮鎯� */
+const handleDetailOpen = async () => {
+ isShowImageDetail.value = true
+}
+
+/** 鍏抽棴鍥剧墖鐨勮鎯� */
+const handleDetailClose = async () => {
+ isShowImageDetail.value = false
+}
+
+/** 鑾峰緱 image 鍥剧墖鍒楄〃 */
+const getImageList = async () => {
+ try {
+ // 1. 鍔犺浇鍥剧墖鍒楄〃
+ imageListLoadingInstance.value = ElLoading.service({
+ target: imageListRef.value,
+ text: '鍔犺浇涓�...'
+ } as LoadingOptionsResolved)
+ const { list, total } = await ImageApi.getImagePageMy(queryParams)
+ imageList.value = list
+ pageTotal.value = total
+
+ // 2. 璁$畻闇�瑕佽疆璇㈢殑鍥剧墖
+ const newWatImages = {}
+ imageList.value.forEach((item) => {
+ if (item.status === AiImageStatusEnum.IN_PROGRESS) {
+ newWatImages[item.id] = item
+ }
+ })
+ inProgressImageMap.value = newWatImages
+ } finally {
+ // 鍏抽棴姝e湪鈥滃姞杞戒腑鈥濈殑 Loading
+ if (imageListLoadingInstance.value) {
+ imageListLoadingInstance.value.close()
+ imageListLoadingInstance.value = null
+ }
+ }
+}
+
+/** 杞鐢熸垚涓殑 image 鍒楄〃 */
+const refreshWatchImages = async () => {
+ const imageIds = Object.keys(inProgressImageMap.value).map(Number)
+ if (imageIds.length == 0) {
+ return
+ }
+ const list = (await ImageApi.getImageListMyByIds(imageIds)) as ImageVO[]
+ const newWatchImages = {}
+ list.forEach((image) => {
+ if (image.status === AiImageStatusEnum.IN_PROGRESS) {
+ newWatchImages[image.id] = image
+ } else {
+ const index = imageList.value.findIndex((oldImage) => image.id === oldImage.id)
+ if (index >= 0) {
+ // 鏇存柊 imageList
+ imageList.value[index] = image
+ }
+ }
+ })
+ inProgressImageMap.value = newWatchImages
+}
+
+/** 鍥剧墖鐨勭偣鍑讳簨浠� */
+const handleImageButtonClick = async (type: string, imageDetail: ImageVO) => {
+ // 璇︽儏
+ if (type === 'more') {
+ showImageDetailId.value = imageDetail.id
+ await handleDetailOpen()
+ return
+ }
+ // 鍒犻櫎
+ if (type === 'delete') {
+ await message.confirm(`鏄惁鍒犻櫎鐓х墖?`)
+ await ImageApi.deleteImageMy(imageDetail.id)
+ await getImageList()
+ message.success('鍒犻櫎鎴愬姛!')
+ return
+ }
+ // 涓嬭浇
+ if (type === 'download') {
+ download.image({ url: imageDetail.picUrl })
+ return
+ }
+ // 閲嶆柊鐢熸垚
+ if (type === 'regeneration') {
+ emits('onRegeneration', imageDetail)
+ return
+ }
+}
+
+/** 澶勭悊 Midjourney 鎸夐挳鐐瑰嚮浜嬩欢 */
+const handleImageMidjourneyButtonClick = async (
+ button: ImageMidjourneyButtonsVO,
+ imageDetail: ImageVO
+) => {
+ // 1. 鏋勫缓 params 鍙傛暟
+ const data = {
+ id: imageDetail.id,
+ customId: button.customId
+ } as ImageMidjourneyActionVO
+ // 2. 鍙戦�� action
+ await ImageApi.midjourneyAction(data)
+ // 3. 鍒锋柊鍒楄〃
+ await getImageList()
+}
+
+defineExpose({ getImageList }) // 鏆撮湶缁勪欢鏂规硶
+
+const emits = defineEmits(['onRegeneration'])
+
+/** 缁勪欢鎸傚湪鐨勬椂鍊� */
+onMounted(async () => {
+ // 鑾峰彇 image 鍒楄〃
+ await getImageList()
+ // 鑷姩鍒锋柊 image 鍒楄〃
+ inProgressTimer.value = setInterval(async () => {
+ await refreshWatchImages()
+ }, 1000 * 3)
+})
+
+/** 缁勪欢鍙栨秷鎸傚湪鐨勬椂鍊� */
+onUnmounted(async () => {
+ if (inProgressTimer.value) {
+ clearInterval(inProgressTimer.value)
+ }
+})
+</script>
--
Gitblit v1.8.0