feat: image wall stable diffusion image list component is ready

This commit is contained in:
RockYang 2023-10-13 15:16:40 +08:00
parent b47ff975b0
commit b59ad521ca
17 changed files with 727 additions and 524 deletions

View File

@ -163,14 +163,26 @@ func (h *SdJobHandler) Image(c *gin.Context) {
// JobList 获取 MJ 任务列表 // JobList 获取 MJ 任务列表
func (h *SdJobHandler) JobList(c *gin.Context) { func (h *SdJobHandler) JobList(c *gin.Context) {
status := h.GetInt(c, "status", 0) status := h.GetInt(c, "status", 0)
var items []model.SdJob userId := h.GetInt(c, "user_id", 0)
var res *gorm.DB page := h.GetInt(c, "page", 0)
userId, _ := c.Get(types.LoginUserID) pageSize := h.GetInt(c, "page_size", 0)
session := h.db.Session(&gorm.Session{})
if status == 1 { if status == 1 {
res = h.db.Where("user_id = ? AND progress = 100", userId).Order("id DESC").Find(&items) session = session.Where("progress = ?", 100).Order("id DESC")
} else { } else {
res = h.db.Where("user_id = ? AND progress < 100", userId).Order("id ASC").Find(&items) session = session.Where("progress < ?", 100).Order("id ASC")
} }
if userId > 0 {
session = session.Where("user_id = ?", userId)
}
if page > 0 && pageSize > 0 {
offset := (page - 1) * pageSize
session = session.Offset(offset).Limit(pageSize)
}
var items []model.SdJob
res := session.Find(&items)
if res.Error != nil { if res.Error != nil {
resp.ERROR(c, types.NoData) resp.ERROR(c, types.NoData)
return return

View File

@ -0,0 +1,13 @@
.custom-scroll ::-webkit-scrollbar {
width: 8px; /* 滚动条宽度 */
}
.custom-scroll ::-webkit-scrollbar-track {
background-color: #282c34;
}
.custom-scroll ::-webkit-scrollbar-thumb {
background-color: #444;
border-radius: 8px;
}
.custom-scroll ::-webkit-scrollbar-thumb:hover {
background-color: #666;
}

View File

@ -0,0 +1,26 @@
.custom-scroll {
/* */
::-webkit-scrollbar {
width: 8px; /* */
}
/* */
::-webkit-scrollbar-track {
background-color: #282C34;
}
/* */
::-webkit-scrollbar-thumb {
background-color: #444444;
border-radius 8px
}
/* */
::-webkit-scrollbar-thumb:hover {
background-color: #666666;
}
}

View File

@ -3,10 +3,6 @@
} }
.page-mj .inner { .page-mj .inner {
display: flex; display: flex;
/* 修改滚动条的颜色 */
/* 修改滚动条轨道的背景颜色 */
/* 修改滚动条的滑块颜色 */
/* 修改滚动条的滑块的悬停颜色 */
} }
.page-mj .inner .mj-box { .page-mj .inner .mj-box {
margin: 10px; margin: 10px;
@ -147,19 +143,6 @@
.page-mj .inner .el-form .el-slider { .page-mj .inner .el-form .el-slider {
width: 180px; width: 180px;
} }
.page-mj .inner ::-webkit-scrollbar {
width: 10px; /* 滚动条宽度 */
}
.page-mj .inner ::-webkit-scrollbar-track {
background-color: #282c34;
}
.page-mj .inner ::-webkit-scrollbar-thumb {
background-color: #444;
border-radius: 10px;
}
.page-mj .inner ::-webkit-scrollbar-thumb:hover {
background-color: #666;
}
.page-mj .inner .task-list-box { .page-mj .inner .task-list-box {
width: 100%; width: 100%;
padding: 10px; padding: 10px;

View File

@ -182,160 +182,7 @@
} }
} }
/* */ @import "task-list.styl"
::-webkit-scrollbar {
width: 10px; /* */
}
/* */
::-webkit-scrollbar-track {
background-color: #282C34;
}
/* */
::-webkit-scrollbar-thumb {
background-color: #444444;
border-radius 10px
}
/* */
::-webkit-scrollbar-thumb:hover {
background-color: #666666;
}
.task-list-box {
width 100%
padding 10px
color #ffffff
overflow-x hidden
.running-job-list {
.job-item {
//border: 1px solid #454545;
width: 100%;
padding 2px
background-color #555555
.job-item-inner {
position relative
height 100%
overflow hidden
.progress {
position absolute
width 100%
height 100%
top 0
left 0
display flex
justify-content center
align-items center
span {
font-size 20px
color #ffffff
}
}
}
}
}
.finish-job-list {
.job-item {
width 100%
height 100%
.opt {
.opt-line {
margin 6px 0
ul {
display flex
flex-flow row
li {
margin-right 10px
a {
padding 3px 0
width 44px
text-align center
border-radius 5px
display block
cursor pointer
background-color #4E5058
color #ffffff
&:hover {
background-color #6D6F78
}
}
}
.show-prompt {
font-size 20px
cursor pointer
}
}
}
}
}
}
.el-image {
width 100%
height 100%
max-height 240px
img {
height 240px
}
.el-image-viewer__wrapper {
img {
width auto
height auto
}
}
.image-slot {
display flex
flex-flow column
justify-content center
align-items center
height 100%
min-height 200px
color #ffffff
.iconfont {
font-size 50px
margin-bottom 10px
}
}
}
.el-image.upscale {
max-height 304px
img {
height 304px
}
.el-image-viewer__wrapper {
img {
width auto
height auto
}
}
}
}
} }
} }

View File

@ -231,16 +231,3 @@
position: relative; position: relative;
top: 2px; top: 2px;
} }
.custom-scroll ::-webkit-scrollbar {
width: 10px; /* 滚动条宽度 */
}
.custom-scroll ::-webkit-scrollbar-track {
background-color: #282c34;
}
.custom-scroll ::-webkit-scrollbar-thumb {
background-color: #444;
border-radius: 10px;
}
.custom-scroll ::-webkit-scrollbar-thumb:hover {
background-color: #666;
}

View File

@ -87,222 +87,11 @@
} }
} }
.task-list-box { @import "task-list.styl"
width 100%
padding 10px
color #ffffff
overflow-x hidden
.running-job-list {
.job-item {
//border: 1px solid #454545;
width: 100%;
padding 2px
background-color #555555
.job-item-inner {
position relative
height 100%
overflow hidden
.progress {
position absolute
width 100%
height 100%
top 0
left 0
display flex
justify-content center
align-items center
span {
font-size 20px
color #ffffff
}
}
}
}
}
.finish-job-list {
.job-item {
width 100%
height 100%
.opt {
.opt-line {
margin 6px 0
ul {
display flex
flex-flow row
li {
margin-right 10px
a {
padding 3px 0
width 44px
text-align center
border-radius 5px
display block
cursor pointer
background-color #4E5058
color #ffffff
&:hover {
background-color #6D6F78
}
}
}
.show-prompt {
font-size 20px
cursor pointer
}
}
}
}
}
}
.el-image {
width 100%
height 100%
max-height 240px
img {
height 240px
}
.el-image-viewer__wrapper {
img {
width auto
height auto
}
}
.image-slot {
display flex
flex-flow column
justify-content center
align-items center
height 100%
min-height 200px
color #ffffff
.iconfont {
font-size 50px
margin-bottom 10px
}
}
}
.el-image.upscale {
max-height 304px
img {
height 304px
}
.el-image-viewer__wrapper {
img {
width auto
height auto
}
}
}
}
} }
.el-overlay-dialog { @import "sd-task-dialog.styl"
.el-dialog {
background-color #1a1b1e
.el-dialog__header {
.el-dialog__title {
color #F5F5F5
}
}
.el-dialog__body {
padding 0 0 0 15px !important
display flex
height 100%
.el-row {
width 100%
.img-container {
display flex
justify-content center
}
.task-info {
background-color #25262b
padding 1rem 1.5rem
.info-line {
width 100%
.prompt {
background-color #35363b
padding 10px
color #999999
overflow auto
max-height 100px
min-height 50px
position relative
.el-icon {
position absolute
right 10px
bottom 10px
cursor pointer
}
}
.wrapper {
margin-top 10px
display flex
label {
display flex
width 100px
color #a5a5a5
}
.item-value {
display flex
width 100%
background-color #35363b
padding 2px 5px
border-radius 5px
color #F5F5F5
}
}
}
.copy-params {
padding 20px 0 10px 0
.el-button {
width 100%
}
}
}
}
// end el-row
}
}
}
.mj-list-item-prompt { .mj-list-item-prompt {
.el-icon { .el-icon {
@ -315,30 +104,3 @@
} }
.custom-scroll {
/* */
::-webkit-scrollbar {
width: 10px; /* */
}
/* */
::-webkit-scrollbar-track {
background-color: #282C34;
}
/* */
::-webkit-scrollbar-thumb {
background-color: #444444;
border-radius 10px
}
/* */
::-webkit-scrollbar-thumb:hover {
background-color: #666666;
}
}

View File

@ -36,6 +36,7 @@
} }
.page-images-wall .inner .waterfall .list-item .image .el-image { .page-images-wall .inner .waterfall .list-item .image .el-image {
transition: transform 0.3s; transition: transform 0.3s;
cursor: pointer;
} }
.page-images-wall .inner .waterfall .list-item .prompt { .page-images-wall .inner .waterfall .list-item .prompt {
display: none; display: none;
@ -68,27 +69,77 @@
.page-images-wall .inner .waterfall .list-item:hover .image .el-image { .page-images-wall .inner .waterfall .list-item:hover .image .el-image {
transform: scale(1.2); /* 放大图像到1.2倍大小 */ transform: scale(1.2); /* 放大图像到1.2倍大小 */
} }
.page-images-wall .inner .waterfall .footer { .page-images-wall .inner .footer {
display: flex; display: flex;
padding: 20px; padding: 20px;
align-items: center; align-items: center;
justify-content: center; justify-content: center;
} }
.page-images-wall .inner .waterfall .footer .iconfont { .page-images-wall .inner .footer .iconfont {
margin-left: 6px; margin-left: 6px;
} }
.page-images-wall .custom-scroll ::-webkit-scrollbar { .page-images-wall .el-overlay-dialog .el-dialog {
width: 10px; /* 滚动条宽度 */ background-color: #1a1b1e;
} }
.page-images-wall .custom-scroll ::-webkit-scrollbar-track { .page-images-wall .el-overlay-dialog .el-dialog .el-dialog__header .el-dialog__title {
background-color: #282c34; color: #f5f5f5;
} }
.page-images-wall .custom-scroll ::-webkit-scrollbar-thumb { .page-images-wall .el-overlay-dialog .el-dialog .el-dialog__body {
background-color: #444; padding: 0 0 0 15px !important;
border-radius: 10px; display: flex;
height: 100%;
} }
.page-images-wall .custom-scroll ::-webkit-scrollbar-thumb:hover { .page-images-wall .el-overlay-dialog .el-dialog .el-dialog__body .el-row {
background-color: #666; width: 100%;
}
.page-images-wall .el-overlay-dialog .el-dialog .el-dialog__body .el-row .img-container {
display: flex;
justify-content: center;
}
.page-images-wall .el-overlay-dialog .el-dialog .el-dialog__body .el-row .task-info {
background-color: #25262b;
padding: 1rem 1.5rem;
}
.page-images-wall .el-overlay-dialog .el-dialog .el-dialog__body .el-row .task-info .info-line {
width: 100%;
}
.page-images-wall .el-overlay-dialog .el-dialog .el-dialog__body .el-row .task-info .info-line .prompt {
background-color: #35363b;
padding: 10px;
color: #999;
overflow: auto;
max-height: 100px;
min-height: 50px;
position: relative;
}
.page-images-wall .el-overlay-dialog .el-dialog .el-dialog__body .el-row .task-info .info-line .prompt .el-icon {
position: absolute;
right: 10px;
bottom: 10px;
cursor: pointer;
}
.page-images-wall .el-overlay-dialog .el-dialog .el-dialog__body .el-row .task-info .info-line .wrapper {
margin-top: 10px;
display: flex;
}
.page-images-wall .el-overlay-dialog .el-dialog .el-dialog__body .el-row .task-info .info-line .wrapper label {
display: flex;
width: 100px;
color: #a5a5a5;
}
.page-images-wall .el-overlay-dialog .el-dialog .el-dialog__body .el-row .task-info .info-line .wrapper .item-value {
display: flex;
width: 100%;
background-color: #35363b;
padding: 2px 5px;
border-radius: 5px;
color: #f5f5f5;
}
.page-images-wall .el-overlay-dialog .el-dialog .el-dialog__body .el-row .task-info .copy-params {
padding: 20px 0 10px 0;
}
.page-images-wall .el-overlay-dialog .el-dialog .el-dialog__body .el-row .task-info .copy-params .el-button {
width: 100%;
} }
@-moz-keyframes expandUp { @-moz-keyframes expandUp {
0% { 0% {

View File

@ -53,6 +53,7 @@
.el-image { .el-image {
transition: transform 0.3s; transition: transform 0.3s;
cursor pointer
} }
} }
@ -97,45 +98,20 @@
} }
} }
}
.footer {
display flex
padding 20px
align-items center
justify-content center
.iconfont { .footer {
margin-left 6px display flex
} padding 20px
align-items center
justify-content center
.iconfont {
margin-left 6px
} }
} }
} }
.custom-scroll { @import "sd-task-dialog.styl"
/* */
::-webkit-scrollbar {
width: 10px; /* */
}
/* */
::-webkit-scrollbar-track {
background-color: #282C34;
}
/* */
::-webkit-scrollbar-thumb {
background-color: #444444;
border-radius 10px
}
/* */
::-webkit-scrollbar-thumb:hover {
background-color: #666666;
}
}
} }

View File

@ -0,0 +1,63 @@
.el-overlay-dialog .el-dialog {
background-color: #1a1b1e;
}
.el-overlay-dialog .el-dialog .el-dialog__header .el-dialog__title {
color: #f5f5f5;
}
.el-overlay-dialog .el-dialog .el-dialog__body {
padding: 0 0 0 15px !important;
display: flex;
height: 100%;
}
.el-overlay-dialog .el-dialog .el-dialog__body .el-row {
width: 100%;
}
.el-overlay-dialog .el-dialog .el-dialog__body .el-row .img-container {
display: flex;
justify-content: center;
}
.el-overlay-dialog .el-dialog .el-dialog__body .el-row .task-info {
background-color: #25262b;
padding: 1rem 1.5rem;
}
.el-overlay-dialog .el-dialog .el-dialog__body .el-row .task-info .info-line {
width: 100%;
}
.el-overlay-dialog .el-dialog .el-dialog__body .el-row .task-info .info-line .prompt {
background-color: #35363b;
padding: 10px;
color: #999;
overflow: auto;
max-height: 100px;
min-height: 50px;
position: relative;
}
.el-overlay-dialog .el-dialog .el-dialog__body .el-row .task-info .info-line .prompt .el-icon {
position: absolute;
right: 10px;
bottom: 10px;
cursor: pointer;
}
.el-overlay-dialog .el-dialog .el-dialog__body .el-row .task-info .info-line .wrapper {
margin-top: 10px;
display: flex;
}
.el-overlay-dialog .el-dialog .el-dialog__body .el-row .task-info .info-line .wrapper label {
display: flex;
width: 100px;
color: #a5a5a5;
}
.el-overlay-dialog .el-dialog .el-dialog__body .el-row .task-info .info-line .wrapper .item-value {
display: flex;
width: 100%;
background-color: #35363b;
padding: 2px 5px;
border-radius: 5px;
color: #f5f5f5;
}
.el-overlay-dialog .el-dialog .el-dialog__body .el-row .task-info .copy-params {
padding: 20px 0 10px 0;
}
.el-overlay-dialog .el-dialog .el-dialog__body .el-row .task-info .copy-params .el-button {
width: 100%;
}

View File

@ -0,0 +1,85 @@
.el-overlay-dialog {
.el-dialog {
background-color #1a1b1e
.el-dialog__header {
.el-dialog__title {
color #F5F5F5
}
}
.el-dialog__body {
padding 0 0 0 15px !important
display flex
height 100%
.el-row {
width 100%
.img-container {
display flex
justify-content center
}
.task-info {
background-color #25262b
padding 1rem 1.5rem
.info-line {
width 100%
.prompt {
background-color #35363b
padding 10px
color #999999
overflow auto
max-height 100px
min-height 50px
position relative
.el-icon {
position absolute
right 10px
bottom 10px
cursor pointer
}
}
.wrapper {
margin-top 10px
display flex
label {
display flex
width 100px
color #a5a5a5
}
.item-value {
display flex
width 100%
background-color #35363b
padding 2px 5px
border-radius 5px
color #F5F5F5
}
}
}
.copy-params {
padding 20px 0 10px 0
.el-button {
width 100%
}
}
}
}
// end el-row
}
}
}

View File

@ -0,0 +1,96 @@
.task-list-box {
width: 100%;
padding: 10px;
color: #fff;
overflow-x: hidden;
}
.task-list-box .running-job-list .job-item {
width: 100%;
padding: 2px;
background-color: #555;
}
.task-list-box .running-job-list .job-item .job-item-inner {
position: relative;
height: 100%;
overflow: hidden;
}
.task-list-box .running-job-list .job-item .job-item-inner .progress {
position: absolute;
width: 100%;
height: 100%;
top: 0;
left: 0;
display: flex;
justify-content: center;
align-items: center;
}
.task-list-box .running-job-list .job-item .job-item-inner .progress span {
font-size: 20px;
color: #fff;
}
.task-list-box .finish-job-list .job-item {
width: 100%;
height: 100%;
}
.task-list-box .finish-job-list .job-item .opt .opt-line {
margin: 6px 0;
}
.task-list-box .finish-job-list .job-item .opt .opt-line ul {
display: flex;
flex-flow: row;
}
.task-list-box .finish-job-list .job-item .opt .opt-line ul li {
margin-right: 10px;
}
.task-list-box .finish-job-list .job-item .opt .opt-line ul li a {
padding: 3px 0;
width: 44px;
text-align: center;
border-radius: 5px;
display: block;
cursor: pointer;
background-color: #4e5058;
color: #fff;
}
.task-list-box .finish-job-list .job-item .opt .opt-line ul li a:hover {
background-color: #6d6f78;
}
.task-list-box .finish-job-list .job-item .opt .opt-line ul .show-prompt {
font-size: 20px;
cursor: pointer;
}
.task-list-box .el-image {
width: 100%;
height: 100%;
max-height: 240px;
}
.task-list-box .el-image img {
height: 240px;
}
.task-list-box .el-image .el-image-viewer__wrapper img {
width: auto;
height: auto;
}
.task-list-box .el-image .image-slot {
display: flex;
flex-flow: column;
justify-content: center;
align-items: center;
height: 100%;
min-height: 200px;
color: #fff;
}
.task-list-box .el-image .image-slot .iconfont {
font-size: 50px;
margin-bottom: 10px;
}
.task-list-box .el-image.upscale {
max-height: 304px;
}
.task-list-box .el-image.upscale img {
height: 304px;
}
.task-list-box .el-image.upscale .el-image-viewer__wrapper img {
width: auto;
height: auto;
}

View File

@ -0,0 +1,129 @@
.task-list-box {
width 100%
padding 10px
color #ffffff
overflow-x hidden
.running-job-list {
.job-item {
//border: 1px solid #454545;
width: 100%;
padding 2px
background-color #555555
.job-item-inner {
position relative
height 100%
overflow hidden
.progress {
position absolute
width 100%
height 100%
top 0
left 0
display flex
justify-content center
align-items center
span {
font-size 20px
color #ffffff
}
}
}
}
}
.finish-job-list {
.job-item {
width 100%
height 100%
.opt {
.opt-line {
margin 6px 0
ul {
display flex
flex-flow row
li {
margin-right 10px
a {
padding 3px 0
width 44px
text-align center
border-radius 5px
display block
cursor pointer
background-color #4E5058
color #ffffff
&:hover {
background-color #6D6F78
}
}
}
.show-prompt {
font-size 20px
cursor pointer
}
}
}
}
}
}
.el-image {
width 100%
height 100%
max-height 240px
img {
height 240px
}
.el-image-viewer__wrapper {
img {
width auto
height auto
}
}
.image-slot {
display flex
flex-flow column
justify-content center
align-items center
height 100%
min-height 200px
color #ffffff
.iconfont {
font-size 50px
margin-bottom 10px
}
}
}
.el-image.upscale {
max-height 304px
img {
height 304px
}
.el-image-viewer__wrapper {
img {
width auto
height auto
}
}
}
}

View File

@ -22,7 +22,7 @@ const routes = [
}, },
{ {
name: 'image-sd', name: 'image-sd',
path: '/sd', path: '/sd/',
meta: {title: 'Stable Diffusion 绘画中心'}, meta: {title: 'Stable Diffusion 绘画中心'},
component: () => import('@/views/ImageSd.vue'), component: () => import('@/views/ImageSd.vue'),
}, },

View File

@ -1,6 +1,6 @@
<template> <template>
<div class="page-mj"> <div class="page-mj">
<div class="inner"> <div class="inner custom-scroll">
<div class="mj-box"> <div class="mj-box">
<h2>MidJourney 创作中心</h2> <h2>MidJourney 创作中心</h2>
@ -600,4 +600,5 @@ const send = (url, index, item) => {
<style lang="stylus"> <style lang="stylus">
@import "@/assets/css/image-mj.styl" @import "@/assets/css/image-mj.styl"
@import "@/assets/css/custom-scroll.styl"
</style> </style>

View File

@ -539,6 +539,11 @@ const runningJobs = ref([])
const finishedJobs = ref([]) const finishedJobs = ref([])
const previewImgList = ref([]) const previewImgList = ref([])
const router = useRouter() const router = useRouter()
//
const _params = router.currentRoute.value.params["copyParams"]
if (_params) {
params.value = JSON.parse(_params)
}
const socket = ref(null) const socket = ref(null)
const imgCalls = ref(0) const imgCalls = ref(0)
@ -681,4 +686,5 @@ const copyParams = (row) => {
<style lang="stylus"> <style lang="stylus">
@import "@/assets/css/image-sd.styl" @import "@/assets/css/image-sd.styl"
@import "@/assets/css/custom-scroll.styl"
</style> </style>

View File

@ -4,73 +4,213 @@
<div class="header"> <div class="header">
<h2>AI 绘画作品墙</h2> <h2>AI 绘画作品墙</h2>
<div class="settings"> <div class="settings">
<el-radio-group v-model="imgType"> <el-radio-group v-model="imgType" @change="changeImgType">
<el-radio label="mj" size="large">MidJourney</el-radio> <el-radio label="mj" size="large">MidJourney</el-radio>
<el-radio label="sd" size="large">Stable Diffusion</el-radio> <el-radio label="sd" size="large">Stable Diffusion</el-radio>
</el-radio-group> </el-radio-group>
</div> </div>
</div> </div>
<v3-waterfall class="waterfall" id="waterfall" :list="list" srcKey="img_url" :gap="12" :colWidth="colWidth" <div class="waterfall" :style="{ height:listBoxHeight + 'px' }" id="waterfall-box">
:style="{ height:listBoxHeight + 'px' }" <v3-waterfall id="waterfall" :list="list" srcKey="img_url"
:distanceToScroll="200" :isLoading="loading" :isOver="over" @scrollReachBottom="getNext"> :gap="12"
<template #default="slotProp"> :bottomGap="-5"
<div class="list-item"> :colWidth="colWidth"
<div class="image"> :distanceToScroll="100"
<el-image :src="slotProp.item['img_url']+'?imageView2/4/w/300/q/75'" :isLoading="loading"
:zoom-rate="1.2" :isOver="false"
:preview-src-list="[slotProp.item['img_url']]" @scrollReachBottom="getNext">
:preview-teleported="true" <template #default="slotProp">
:initial-index="10" <div class="list-item">
loading="lazy"> <div class="image" v-if="imgType === 'mj'">
<template #placeholder> <el-image :src="slotProp.item['img_url']+'?imageView2/4/w/300/q/75'"
<div class="image-slot"> :zoom-rate="1.2"
正在加载图片 :preview-src-list="[slotProp.item['img_url']]"
</div> :preview-teleported="true"
</template> :initial-index="10"
loading="lazy">
<template #placeholder>
<div class="image-slot">
正在加载图片
</div>
</template>
<template #error> <template #error>
<div class="image-slot"> <div class="image-slot">
<el-icon v-if="slotProp.item['img'] !== ''"> <el-icon>
<Picture/> <Picture/>
</el-icon> </el-icon>
</div> </div>
</template> </template>
</el-image> </el-image>
</div>
<div class="image" v-else>
<el-image :src="slotProp.item['img_url']+'?imageView2/4/w/300/q/75'" loading="lazy"
@click="showTask(slotProp.item)">
<template #placeholder>
<div class="image-slot">
正在加载图片
</div>
</template>
<template #error>
<div class="image-slot">
<el-icon>
<Picture/>
</el-icon>
</div>
</template>
</el-image>
</div>
<div class="prompt">
<span>{{ slotProp.item.prompt }}</span>
<el-icon class="copy-prompt" :data-clipboard-text="slotProp.item.prompt">
<DocumentCopy/>
</el-icon>
</div>
</div> </div>
</template>
</v3-waterfall>
<div class="prompt"> <div class="footer" v-if="isOver">
<span>{{ slotProp.item.prompt }}</span> <span>没有更多数据了</span>
<el-icon class="copy-prompt" :data-clipboard-text="slotProp.item.prompt"> <i class="iconfont icon-face"></i>
<DocumentCopy/> </div>
</el-icon>
</div>
</div>
</template>
<template #footer> </div>
<div class="footer">
<span>没有更多数据了</span>
<i class="iconfont icon-face"></i>
</div>
</template>
</v3-waterfall>
</div> </div>
<!-- 任务详情弹框 -->
<el-dialog v-model="showTaskDialog" title="绘画任务详情" :fullscreen="true">
<el-row :gutter="20">
<el-col :span="16">
<div class="img-container" :style="{maxHeight: fullImgHeight+'px'}">
<el-image :src="item['img_url']" fit="contain"/>
</div>
</el-col>
<el-col :span="8">
<div class="task-info">
<div class="info-line">
<el-divider>
正向提示词
</el-divider>
<div class="prompt">
<span>{{ item.prompt }}</span>
<el-icon class="copy-prompt" :data-clipboard-text="item.prompt">
<DocumentCopy/>
</el-icon>
</div>
</div>
<div class="info-line">
<el-divider>
反向提示词
</el-divider>
<div class="prompt">
<span>{{ item.params.negative_prompt }}</span>
<el-icon class="copy-prompt" :data-clipboard-text="item.params.negative_prompt">
<DocumentCopy/>
</el-icon>
</div>
</div>
<div class="info-line">
<div class="wrapper">
<label>采样方法</label>
<div class="item-value">{{ item.params.sampler }}</div>
</div>
</div>
<div class="info-line">
<div class="wrapper">
<label>图片尺寸</label>
<div class="item-value">{{ item.params.width }} x {{ item.params.height }}</div>
</div>
</div>
<div class="info-line">
<div class="wrapper">
<label>迭代步数</label>
<div class="item-value">{{ item.params.steps }}</div>
</div>
</div>
<div class="info-line">
<div class="wrapper">
<label>引导系数</label>
<div class="item-value">{{ item.params.cfg_scale }}</div>
</div>
</div>
<div class="info-line">
<div class="wrapper">
<label>随机因子</label>
<div class="item-value">{{ item.params.seed }}</div>
</div>
</div>
<div v-if="item.params.hd_fix">
<el-divider>
高清修复
</el-divider>
<div class="info-line">
<div class="wrapper">
<label>重绘幅度</label>
<div class="item-value">{{ item.params.hd_redraw_rate }}</div>
</div>
</div>
<div class="info-line">
<div class="wrapper">
<label>放大算法</label>
<div class="item-value">{{ item.params.hd_scale_alg }}</div>
</div>
</div>
<div class="info-line">
<div class="wrapper">
<label>放大倍数</label>
<div class="item-value">{{ item.params.hd_scale }}</div>
</div>
</div>
<div class="info-line">
<div class="wrapper">
<label>迭代步数</label>
<div class="item-value">{{ item.params.hd_steps }}</div>
</div>
</div>
</div>
<div class="copy-params">
<el-button type="primary" round @click="copyParams(item)">画一张同款的</el-button>
</div>
</div>
</el-col>
</el-row>
</el-dialog>
</div> </div>
</template> </template>
<script setup> <script setup>
import {onMounted, ref} from "vue" import {nextTick, onMounted, ref} from "vue"
import {DocumentCopy, Picture} from "@element-plus/icons-vue"; import {DocumentCopy, Picture} from "@element-plus/icons-vue";
import {httpGet} from "@/utils/http"; import {httpGet} from "@/utils/http";
import {ElMessage} from "element-plus"; import {ElMessage} from "element-plus";
import Clipboard from "clipboard"; import Clipboard from "clipboard";
import {useRouter} from "vue-router";
const list = ref([]) const list = ref([])
const loading = ref(true) const loading = ref(true)
const over = ref(false) const isOver = ref(false)
const imgType = ref("mj") // const imgType = ref("mj") //
const listBoxHeight = window.innerHeight - 71 const listBoxHeight = window.innerHeight - 71
const colWidth = ref(240) const colWidth = ref(240)
const fullImgHeight = ref(window.innerHeight - 60)
const showTaskDialog = ref(false)
const item = ref({})
// //
const calcColWidth = () => { const calcColWidth = () => {
@ -87,18 +227,24 @@ const page = ref(0)
const pageSize = ref(20) const pageSize = ref(20)
// //
const getNext = () => { const getNext = () => {
if (isOver.value) {
return
}
loading.value = true loading.value = true
page.value = page.value + 1 page.value = page.value + 1
const url = imgType.value === "mj" ? "/api/mj/jobs" : "/api/sd/jobs"
// //
httpGet(`/api/mj/jobs?status=1&page=${page.value}&page_size=${pageSize.value}`).then(res => { httpGet(`${url}?status=1&page=${page.value}&page_size=${pageSize.value}`).then(res => {
loading.value = false loading.value = false
if (list.value.length === 0) { if (list.value.length === 0) {
list.value = res.data list.value = res.data
return return
} else if (res.data.length < pageSize.value) {
over.value = true
} }
if (res.data.length < pageSize.value) {
isOver.value = true
}
list.value = list.value.concat(res.data) list.value = list.value.concat(res.data)
}).catch(e => { }).catch(e => {
@ -119,8 +265,28 @@ onMounted(() => {
}) })
}) })
const changeImgType = () => {
document.getElementById('waterfall-box').scrollTo(0, 0)
page.value = 0
list.value = []
isOver.value = false
nextTick(() => getNext())
}
const showTask = (row) => {
item.value = row
showTaskDialog.value = true
}
const router = useRouter()
const copyParams = (row) => {
router.push({name: "image-sd", params: {copyParams: JSON.stringify(row.params)}})
}
</script> </script>
<style lang="stylus" scoped> <style lang="stylus">
@import "@/assets/css/images-wall.styl" @import "@/assets/css/images-wall.styl"
@import "@/assets/css/custom-scroll.styl"
</style> </style>