mirror of
https://gitee.com/blackfox/geekai.git
synced 2025-12-07 01:08:24 +08:00
瀑布流样式更改
This commit is contained in:
parent
41e66d85d5
commit
88eaddbd1d
@ -47,6 +47,8 @@
|
|||||||
--hover-deep-color:#30323c;
|
--hover-deep-color:#30323c;
|
||||||
--tab-title-bg:#525777;//顶部tab栏背景切换
|
--tab-title-bg:#525777;//顶部tab栏背景切换
|
||||||
--tab-title-color:#fff;//顶部tab栏文字切换
|
--tab-title-color:#fff;//顶部tab栏文字切换
|
||||||
|
//深黑色
|
||||||
|
--bg-deep-color:rgba(255,255,255,0.8);
|
||||||
//layout
|
//layout
|
||||||
.more-menus li.moreTitle,
|
.more-menus li.moreTitle,
|
||||||
.twoTittle .title,
|
.twoTittle .title,
|
||||||
|
|||||||
BIN
web/src/assets/img/failed.png
Normal file
BIN
web/src/assets/img/failed.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 4.4 KiB |
@ -332,11 +332,13 @@
|
|||||||
<h2 class="record-title pt">创作记录</h2>
|
<h2 class="record-title pt">创作记录</h2>
|
||||||
<!-- 已完成的任务 -->
|
<!-- 已完成的任务 -->
|
||||||
<v3-waterfall
|
<v3-waterfall
|
||||||
|
:virtual-time="200"
|
||||||
|
:distance-to-scroll="150"
|
||||||
:key="waterfallKey"
|
:key="waterfallKey"
|
||||||
:list="finishedTasks"
|
:list="finishedTasks"
|
||||||
@scrollReachBottom="fetchTasks"
|
@scrollReachBottom="fetchTasks"
|
||||||
:gap="20"
|
:gap="8"
|
||||||
:bottomGap="20"
|
:bottomGap="8"
|
||||||
:colWidth="300"
|
:colWidth="300"
|
||||||
:distanceToScroll="100"
|
:distanceToScroll="100"
|
||||||
:isLoading="loading"
|
:isLoading="loading"
|
||||||
@ -344,6 +346,7 @@
|
|||||||
class="task-waterfall"
|
class="task-waterfall"
|
||||||
>
|
>
|
||||||
<template #default="slotProp">
|
<template #default="slotProp">
|
||||||
|
<!-- 视频成功渲染部分 -->
|
||||||
<div
|
<div
|
||||||
class="job-item-box"
|
class="job-item-box"
|
||||||
:class="{
|
:class="{
|
||||||
@ -352,20 +355,38 @@
|
|||||||
}"
|
}"
|
||||||
>
|
>
|
||||||
<video
|
<video
|
||||||
v-if="slotProp.item.progress >= 100"
|
v-if="
|
||||||
|
slotProp.item.progress >= 100 && slotProp.item.video_url
|
||||||
|
"
|
||||||
class="preview"
|
class="preview"
|
||||||
:src="slotProp.item.video_url"
|
:src="slotProp.item.video_url"
|
||||||
@click="previewVideo(slotProp.item)"
|
@click="previewVideo(slotProp.item)"
|
||||||
controls
|
controls
|
||||||
|
:style="{
|
||||||
|
width: '100%',
|
||||||
|
height: `${slotProp.item.height || 400}px`
|
||||||
|
}"
|
||||||
></video>
|
></video>
|
||||||
|
|
||||||
<div v-else class="status-overlay">
|
<!-- 失败/无图状态 -->
|
||||||
|
<div
|
||||||
|
v-else
|
||||||
|
class="error-container"
|
||||||
|
:style="{
|
||||||
|
width: '100%',
|
||||||
|
height: `${slotProp.item.height || 300}px`,
|
||||||
|
objectFit: 'cover'
|
||||||
|
}"
|
||||||
|
>
|
||||||
<div
|
<div
|
||||||
v-if="slotProp.item.progress === 101"
|
v-if="
|
||||||
|
slotProp.item.progress >= 100 &&
|
||||||
|
!slotProp.item.video_url
|
||||||
|
"
|
||||||
class="error-status"
|
class="error-status"
|
||||||
>
|
>
|
||||||
<el-icon><CloseBold /></el-icon>
|
<img :src="failed" />
|
||||||
任务失败
|
生成失败
|
||||||
</div>
|
</div>
|
||||||
<div v-else class="processing-status">
|
<div v-else class="processing-status">
|
||||||
<el-progress
|
<el-progress
|
||||||
@ -375,42 +396,89 @@
|
|||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="tools-box">
|
||||||
<div class="tools">
|
<div class="tools">
|
||||||
<el-button
|
<el-button
|
||||||
v-if="slotProp.item.progress >= 100"
|
type="primary"
|
||||||
@click="downloadVideo(slotProp.item)"
|
v-if="
|
||||||
>
|
slotProp.item.progress >= 100 &&
|
||||||
<el-icon><Download /></el-icon>
|
slotProp.item.video_url
|
||||||
</el-button>
|
"
|
||||||
<el-button type="danger" @click="deleteTask(slotProp.item)">
|
@click="downloadVideo(slotProp.item)"
|
||||||
<el-icon><Delete /></el-icon>
|
|
||||||
</el-button>
|
|
||||||
<div class="show-prompt">
|
|
||||||
<el-popover
|
|
||||||
placement="left"
|
|
||||||
title="提示词"
|
|
||||||
:width="240"
|
|
||||||
trigger="hover"
|
|
||||||
>
|
>
|
||||||
<template #reference>
|
<el-icon><Download /></el-icon>
|
||||||
<el-icon class="chromefilled">
|
</el-button>
|
||||||
<ChromeFilled />
|
|
||||||
</el-icon>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<template #default>
|
<div
|
||||||
<div class="mj-list-item-prompt">
|
class="show-prompt"
|
||||||
<span>{{ slotProp.item.prompt }}</span>
|
v-if="
|
||||||
<el-icon
|
slotProp.item.progress >= 100 &&
|
||||||
class="copy-prompt-mj"
|
!slotProp.item.video_url &&
|
||||||
:data-clipboard-text="slotProp.item.prompt"
|
slotProp.item.err_msg
|
||||||
>
|
"
|
||||||
<DocumentCopy />
|
>
|
||||||
|
<el-popover
|
||||||
|
placement="left"
|
||||||
|
:width="240"
|
||||||
|
trigger="hover"
|
||||||
|
>
|
||||||
|
<template #reference>
|
||||||
|
<el-icon class="chromefilled error-txt"
|
||||||
|
><WarnTriangleFilled
|
||||||
|
/></el-icon>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<template #default>
|
||||||
|
<div class="top-tips">
|
||||||
|
<span>错误详细信息</span
|
||||||
|
><el-icon
|
||||||
|
class="copy-prompt-kl"
|
||||||
|
:data-clipboard-text="slotProp.item.prompt"
|
||||||
|
>
|
||||||
|
<DocumentCopy />
|
||||||
|
</el-icon>
|
||||||
|
</div>
|
||||||
|
<div class="mj-list-item-prompt">
|
||||||
|
<span>{{ slotProp.item.prompt }}</span>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
</el-popover>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<el-button
|
||||||
|
type="danger"
|
||||||
|
@click="deleteTask(slotProp.item)"
|
||||||
|
>
|
||||||
|
<el-icon><Delete /></el-icon>
|
||||||
|
</el-button>
|
||||||
|
<div class="show-prompt">
|
||||||
|
<el-popover
|
||||||
|
placement="left"
|
||||||
|
:width="240"
|
||||||
|
trigger="hover"
|
||||||
|
>
|
||||||
|
<template #reference>
|
||||||
|
<el-icon class="chromefilled">
|
||||||
|
<ChromeFilled />
|
||||||
</el-icon>
|
</el-icon>
|
||||||
</div>
|
</template>
|
||||||
</template>
|
|
||||||
</el-popover>
|
<template #default>
|
||||||
|
<div class="top-tips">
|
||||||
|
<span>提示词</span
|
||||||
|
><el-icon
|
||||||
|
class="copy-prompt-kl"
|
||||||
|
:data-clipboard-text="slotProp.item.prompt"
|
||||||
|
>
|
||||||
|
<DocumentCopy />
|
||||||
|
</el-icon>
|
||||||
|
</div>
|
||||||
|
<div class="mj-list-item-prompt">
|
||||||
|
<span>{{ slotProp.item.prompt }}</span>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
</el-popover>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -440,6 +508,7 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
|
import failed from "@/assets/img/failed.png";
|
||||||
import TaskList from "@/components/TaskList.vue";
|
import TaskList from "@/components/TaskList.vue";
|
||||||
import { ref, reactive, onMounted, onUnmounted, watch, computed } from "vue";
|
import { ref, reactive, onMounted, onUnmounted, watch, computed } from "vue";
|
||||||
import {
|
import {
|
||||||
@ -448,11 +517,13 @@ import {
|
|||||||
InfoFilled,
|
InfoFilled,
|
||||||
ChromeFilled,
|
ChromeFilled,
|
||||||
DocumentCopy,
|
DocumentCopy,
|
||||||
Download
|
Download,
|
||||||
|
WarnTriangleFilled
|
||||||
} from "@element-plus/icons-vue";
|
} from "@element-plus/icons-vue";
|
||||||
import { httpGet, httpPost, httpDownload } from "@/utils/http";
|
import { httpGet, httpPost, httpDownload } from "@/utils/http";
|
||||||
import { ElMessage, ElMessageBox } from "element-plus";
|
import { ElMessage, ElMessageBox } from "element-plus";
|
||||||
import { getClientId, checkSession } from "@/store/cache";
|
import { getClientId, checkSession } from "@/store/cache";
|
||||||
|
import Clipboard from "clipboard";
|
||||||
|
|
||||||
import {
|
import {
|
||||||
closeLoading,
|
closeLoading,
|
||||||
@ -620,7 +691,12 @@ const fetchTasks = async () => {
|
|||||||
runningTasks.value = [...runningTasks.value, ...newRunning];
|
runningTasks.value = [...runningTasks.value, ...newRunning];
|
||||||
|
|
||||||
const newfinished = data.items.filter((task) => task.progress >= 100);
|
const newfinished = data.items.filter((task) => task.progress >= 100);
|
||||||
finishedTasks.value = [...finishedTasks.value, ...newfinished];
|
const finishedList = [...finishedTasks.value, ...newfinished];
|
||||||
|
finishedTasks.value = finishedList.map((item) => ({
|
||||||
|
...item,
|
||||||
|
height: 300 * (Math.random() * 0.4 + 0.6) // 生成300~420px随机高度
|
||||||
|
}));
|
||||||
|
console.log("finishedTasks: " + finishedList);
|
||||||
|
|
||||||
// // 强制刷新瀑布流
|
// // 强制刷新瀑布流
|
||||||
waterfallKey.value = Date.now();
|
waterfallKey.value = Date.now();
|
||||||
@ -693,6 +769,8 @@ const deleteTask = async (task) => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
fetchTasks();
|
fetchTasks();
|
||||||
|
const clipboard = ref(null);
|
||||||
|
|
||||||
// 生命周期钩子
|
// 生命周期钩子
|
||||||
onMounted(async () => {
|
onMounted(async () => {
|
||||||
checkSession()
|
checkSession()
|
||||||
@ -704,8 +782,18 @@ onMounted(async () => {
|
|||||||
.catch(() => {});
|
.catch(() => {});
|
||||||
|
|
||||||
// fetchTasks();
|
// fetchTasks();
|
||||||
|
clipboard.value = new Clipboard(".copy-prompt-kl");
|
||||||
|
clipboard.value.on("success", () => {
|
||||||
|
ElMessage.success("复制成功!");
|
||||||
|
});
|
||||||
|
|
||||||
|
clipboard.value.on("error", () => {
|
||||||
|
ElMessage.error("复制失败!");
|
||||||
|
});
|
||||||
|
});
|
||||||
|
onUnmounted(() => {
|
||||||
|
clipboard.value.destroy();
|
||||||
});
|
});
|
||||||
onUnmounted(() => {});
|
|
||||||
// 监听任务状态变化
|
// 监听任务状态变化
|
||||||
watch([runningTasks, finishedTasks], () => {
|
watch([runningTasks, finishedTasks], () => {
|
||||||
if (checkAllCompleted()) {
|
if (checkAllCompleted()) {
|
||||||
@ -717,6 +805,20 @@ watch([runningTasks, finishedTasks], () => {
|
|||||||
<style lang="stylus" scoped>
|
<style lang="stylus" scoped>
|
||||||
@import "@/assets/css/image-keling.styl"
|
@import "@/assets/css/image-keling.styl"
|
||||||
@import "@/assets/css/custom-scroll.styl"
|
@import "@/assets/css/custom-scroll.styl"
|
||||||
|
.copy-prompt-kl{
|
||||||
|
cursor pointer
|
||||||
|
}
|
||||||
|
.top-tips{
|
||||||
|
height: 30px
|
||||||
|
font-size: 18px
|
||||||
|
line-height: 30px
|
||||||
|
display: flex
|
||||||
|
align-items: center;
|
||||||
|
span{
|
||||||
|
margin-right: 10px
|
||||||
|
color:#000
|
||||||
|
}
|
||||||
|
}
|
||||||
.mj-list-item-prompt{
|
.mj-list-item-prompt{
|
||||||
max-height: 600px;
|
max-height: 600px;
|
||||||
overflow: auto;
|
overflow: auto;
|
||||||
@ -735,7 +837,7 @@ watch([runningTasks, finishedTasks], () => {
|
|||||||
width: 200px;
|
width: 200px;
|
||||||
height: 200px;
|
height: 200px;
|
||||||
.iconfont{
|
.iconfont{
|
||||||
font-size: 45px
|
font-size: 45px;
|
||||||
|
|
||||||
}
|
}
|
||||||
span{
|
span{
|
||||||
@ -754,57 +856,78 @@ watch([runningTasks, finishedTasks], () => {
|
|||||||
|
|
||||||
.job-item-box
|
.job-item-box
|
||||||
position: relative
|
position: relative
|
||||||
transition: transform 0.3s ease
|
background: #f5f5f5;
|
||||||
|
transition: height 0.3s ease;
|
||||||
overflow: hidden
|
overflow: hidden
|
||||||
margin: 10px
|
// margin: 10px
|
||||||
border: 1px solid #666;
|
// border: 1px solid #666;
|
||||||
padding: 6px;
|
// padding: 6px;
|
||||||
border-radius: 6px;
|
border-radius: 6px;
|
||||||
break-inside: avoid
|
break-inside: avoid
|
||||||
video
|
video
|
||||||
min-height: 200px;
|
min-height: 200px;
|
||||||
|
width: 100%;
|
||||||
|
object-fit: cover;
|
||||||
|
|
||||||
.chromefilled
|
.chromefilled
|
||||||
font-size: 24px;
|
font-size: 24px;
|
||||||
|
color: #fff;
|
||||||
|
&.error-txt{
|
||||||
|
color: #ffff54;
|
||||||
|
cursor:pointer;
|
||||||
|
}
|
||||||
.show-prompt
|
.show-prompt
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
&:hover
|
&:hover
|
||||||
transform: translateY(-3px)
|
// transform: translateY(-3px)
|
||||||
|
.tools-box{
|
||||||
|
display:block
|
||||||
|
background:rgba(0, 0, 0, 0.3)
|
||||||
|
width : 100%;
|
||||||
|
}
|
||||||
|
|
||||||
.status-overlay
|
.error-container
|
||||||
position: absolute
|
position: relative
|
||||||
top: 0
|
background: var(--bg-deep-color)
|
||||||
left: 0
|
|
||||||
right: 0
|
|
||||||
bottom: 0
|
|
||||||
background: rgba(0, 0, 0, 0.7)
|
|
||||||
display: flex
|
display: flex
|
||||||
align-items: center
|
align-items: center
|
||||||
justify-content: center
|
justify-content: center
|
||||||
|
img{
|
||||||
|
width: 66%;
|
||||||
|
height: 66%;
|
||||||
|
object-fit: cover;
|
||||||
|
margin: 0 auto;
|
||||||
|
}
|
||||||
|
|
||||||
.error-status
|
.error-status
|
||||||
color: #ff4d4f
|
color: #c2c6cc
|
||||||
text-align: center
|
text-align: center
|
||||||
.el-icon
|
font-size: 24px
|
||||||
font-size: 24px
|
|
||||||
display: block
|
|
||||||
margin-bottom: 8px
|
|
||||||
|
|
||||||
.processing-status
|
.processing-status
|
||||||
width: 80%
|
width: 80%
|
||||||
.el-progress
|
.el-progress
|
||||||
margin: 0 auto
|
margin: 0 auto
|
||||||
|
.tools-box{
|
||||||
|
display:none
|
||||||
|
position:absolute;
|
||||||
|
top: 0;
|
||||||
|
right: 0;
|
||||||
|
}
|
||||||
.tools
|
.tools
|
||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: flex-end;
|
justify-content: flex-end;
|
||||||
display: flex
|
display: flex
|
||||||
gap: 8px
|
gap: 5px
|
||||||
margin:5px 0 0
|
margin: 5px 5px 5px 0;
|
||||||
|
|
||||||
|
|
||||||
.el-button+.el-button
|
.el-button+.el-button
|
||||||
margin-left: 0px;
|
margin-left: 0px;
|
||||||
|
|
||||||
.el-button
|
.el-button
|
||||||
padding: 6px
|
padding: 3px
|
||||||
border-radius: 50%
|
border-radius: 50%
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user