mirror of
https://github.com/yangjian102621/geekai.git
synced 2025-09-17 08:46:38 +08:00
feat: image wall stable diffusion image list component is ready
This commit is contained in:
parent
b47ff975b0
commit
b59ad521ca
@ -163,14 +163,26 @@ func (h *SdJobHandler) Image(c *gin.Context) {
|
||||
// JobList 获取 MJ 任务列表
|
||||
func (h *SdJobHandler) JobList(c *gin.Context) {
|
||||
status := h.GetInt(c, "status", 0)
|
||||
var items []model.SdJob
|
||||
var res *gorm.DB
|
||||
userId, _ := c.Get(types.LoginUserID)
|
||||
userId := h.GetInt(c, "user_id", 0)
|
||||
page := h.GetInt(c, "page", 0)
|
||||
pageSize := h.GetInt(c, "page_size", 0)
|
||||
|
||||
session := h.db.Session(&gorm.Session{})
|
||||
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 {
|
||||
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 {
|
||||
resp.ERROR(c, types.NoData)
|
||||
return
|
||||
|
13
web/src/assets/css/custom-scroll.css
Normal file
13
web/src/assets/css/custom-scroll.css
Normal 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;
|
||||
}
|
26
web/src/assets/css/custom-scroll.styl
Normal file
26
web/src/assets/css/custom-scroll.styl
Normal 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;
|
||||
}
|
||||
}
|
@ -3,10 +3,6 @@
|
||||
}
|
||||
.page-mj .inner {
|
||||
display: flex;
|
||||
/* 修改滚动条的颜色 */
|
||||
/* 修改滚动条轨道的背景颜色 */
|
||||
/* 修改滚动条的滑块颜色 */
|
||||
/* 修改滚动条的滑块的悬停颜色 */
|
||||
}
|
||||
.page-mj .inner .mj-box {
|
||||
margin: 10px;
|
||||
@ -147,19 +143,6 @@
|
||||
.page-mj .inner .el-form .el-slider {
|
||||
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 {
|
||||
width: 100%;
|
||||
padding: 10px;
|
||||
|
@ -182,160 +182,7 @@
|
||||
}
|
||||
}
|
||||
|
||||
/* 修改滚动条的颜色 */
|
||||
|
||||
::-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
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@import "task-list.styl"
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -231,16 +231,3 @@
|
||||
position: relative;
|
||||
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;
|
||||
}
|
||||
|
@ -87,222 +87,11 @@
|
||||
}
|
||||
}
|
||||
|
||||
.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
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@import "task-list.styl"
|
||||
}
|
||||
|
||||
.el-overlay-dialog {
|
||||
.el-dialog {
|
||||
background-color #1a1b1e
|
||||
@import "sd-task-dialog.styl"
|
||||
|
||||
.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 {
|
||||
.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;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -36,6 +36,7 @@
|
||||
}
|
||||
.page-images-wall .inner .waterfall .list-item .image .el-image {
|
||||
transition: transform 0.3s;
|
||||
cursor: pointer;
|
||||
}
|
||||
.page-images-wall .inner .waterfall .list-item .prompt {
|
||||
display: none;
|
||||
@ -68,27 +69,77 @@
|
||||
.page-images-wall .inner .waterfall .list-item:hover .image .el-image {
|
||||
transform: scale(1.2); /* 放大图像到1.2倍大小 */
|
||||
}
|
||||
.page-images-wall .inner .waterfall .footer {
|
||||
.page-images-wall .inner .footer {
|
||||
display: flex;
|
||||
padding: 20px;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
.page-images-wall .inner .waterfall .footer .iconfont {
|
||||
.page-images-wall .inner .footer .iconfont {
|
||||
margin-left: 6px;
|
||||
}
|
||||
.page-images-wall .custom-scroll ::-webkit-scrollbar {
|
||||
width: 10px; /* 滚动条宽度 */
|
||||
.page-images-wall .el-overlay-dialog .el-dialog {
|
||||
background-color: #1a1b1e;
|
||||
}
|
||||
.page-images-wall .custom-scroll ::-webkit-scrollbar-track {
|
||||
background-color: #282c34;
|
||||
.page-images-wall .el-overlay-dialog .el-dialog .el-dialog__header .el-dialog__title {
|
||||
color: #f5f5f5;
|
||||
}
|
||||
.page-images-wall .custom-scroll ::-webkit-scrollbar-thumb {
|
||||
background-color: #444;
|
||||
border-radius: 10px;
|
||||
.page-images-wall .el-overlay-dialog .el-dialog .el-dialog__body {
|
||||
padding: 0 0 0 15px !important;
|
||||
display: flex;
|
||||
height: 100%;
|
||||
}
|
||||
.page-images-wall .custom-scroll ::-webkit-scrollbar-thumb:hover {
|
||||
background-color: #666;
|
||||
.page-images-wall .el-overlay-dialog .el-dialog .el-dialog__body .el-row {
|
||||
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 {
|
||||
0% {
|
||||
|
@ -53,6 +53,7 @@
|
||||
|
||||
.el-image {
|
||||
transition: transform 0.3s;
|
||||
cursor pointer
|
||||
}
|
||||
}
|
||||
|
||||
@ -97,45 +98,20 @@
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
.footer {
|
||||
display flex
|
||||
padding 20px
|
||||
align-items center
|
||||
justify-content center
|
||||
|
||||
.iconfont {
|
||||
margin-left 6px
|
||||
}
|
||||
.footer {
|
||||
display flex
|
||||
padding 20px
|
||||
align-items center
|
||||
justify-content center
|
||||
|
||||
.iconfont {
|
||||
margin-left 6px
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
.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;
|
||||
}
|
||||
}
|
||||
@import "sd-task-dialog.styl"
|
||||
}
|
63
web/src/assets/css/sd-task-dialog.css
Normal file
63
web/src/assets/css/sd-task-dialog.css
Normal 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%;
|
||||
}
|
85
web/src/assets/css/sd-task-dialog.styl
Normal file
85
web/src/assets/css/sd-task-dialog.styl
Normal 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
|
||||
|
||||
}
|
||||
}
|
||||
}
|
96
web/src/assets/css/task-list.css
Normal file
96
web/src/assets/css/task-list.css
Normal 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;
|
||||
}
|
129
web/src/assets/css/task-list.styl
Normal file
129
web/src/assets/css/task-list.styl
Normal 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
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -22,7 +22,7 @@ const routes = [
|
||||
},
|
||||
{
|
||||
name: 'image-sd',
|
||||
path: '/sd',
|
||||
path: '/sd/',
|
||||
meta: {title: 'Stable Diffusion 绘画中心'},
|
||||
component: () => import('@/views/ImageSd.vue'),
|
||||
},
|
||||
|
@ -1,6 +1,6 @@
|
||||
<template>
|
||||
<div class="page-mj">
|
||||
<div class="inner">
|
||||
<div class="inner custom-scroll">
|
||||
<div class="mj-box">
|
||||
<h2>MidJourney 创作中心</h2>
|
||||
|
||||
@ -600,4 +600,5 @@ const send = (url, index, item) => {
|
||||
|
||||
<style lang="stylus">
|
||||
@import "@/assets/css/image-mj.styl"
|
||||
@import "@/assets/css/custom-scroll.styl"
|
||||
</style>
|
||||
|
@ -539,6 +539,11 @@ const runningJobs = ref([])
|
||||
const finishedJobs = ref([])
|
||||
const previewImgList = ref([])
|
||||
const router = useRouter()
|
||||
// 检查是否有画同款的参数
|
||||
const _params = router.currentRoute.value.params["copyParams"]
|
||||
if (_params) {
|
||||
params.value = JSON.parse(_params)
|
||||
}
|
||||
|
||||
const socket = ref(null)
|
||||
const imgCalls = ref(0)
|
||||
@ -681,4 +686,5 @@ const copyParams = (row) => {
|
||||
|
||||
<style lang="stylus">
|
||||
@import "@/assets/css/image-sd.styl"
|
||||
@import "@/assets/css/custom-scroll.styl"
|
||||
</style>
|
||||
|
@ -4,73 +4,213 @@
|
||||
<div class="header">
|
||||
<h2>AI 绘画作品墙</h2>
|
||||
<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="sd" size="large">Stable Diffusion</el-radio>
|
||||
</el-radio-group>
|
||||
</div>
|
||||
</div>
|
||||
<v3-waterfall class="waterfall" id="waterfall" :list="list" srcKey="img_url" :gap="12" :colWidth="colWidth"
|
||||
:style="{ height:listBoxHeight + 'px' }"
|
||||
:distanceToScroll="200" :isLoading="loading" :isOver="over" @scrollReachBottom="getNext">
|
||||
<template #default="slotProp">
|
||||
<div class="list-item">
|
||||
<div class="image">
|
||||
<el-image :src="slotProp.item['img_url']+'?imageView2/4/w/300/q/75'"
|
||||
:zoom-rate="1.2"
|
||||
:preview-src-list="[slotProp.item['img_url']]"
|
||||
:preview-teleported="true"
|
||||
:initial-index="10"
|
||||
loading="lazy">
|
||||
<template #placeholder>
|
||||
<div class="image-slot">
|
||||
正在加载图片
|
||||
</div>
|
||||
</template>
|
||||
<div class="waterfall" :style="{ height:listBoxHeight + 'px' }" id="waterfall-box">
|
||||
<v3-waterfall id="waterfall" :list="list" srcKey="img_url"
|
||||
:gap="12"
|
||||
:bottomGap="-5"
|
||||
:colWidth="colWidth"
|
||||
:distanceToScroll="100"
|
||||
:isLoading="loading"
|
||||
:isOver="false"
|
||||
@scrollReachBottom="getNext">
|
||||
<template #default="slotProp">
|
||||
<div class="list-item">
|
||||
<div class="image" v-if="imgType === 'mj'">
|
||||
<el-image :src="slotProp.item['img_url']+'?imageView2/4/w/300/q/75'"
|
||||
:zoom-rate="1.2"
|
||||
:preview-src-list="[slotProp.item['img_url']]"
|
||||
:preview-teleported="true"
|
||||
:initial-index="10"
|
||||
loading="lazy">
|
||||
<template #placeholder>
|
||||
<div class="image-slot">
|
||||
正在加载图片
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<template #error>
|
||||
<div class="image-slot">
|
||||
<el-icon v-if="slotProp.item['img'] !== ''">
|
||||
<Picture/>
|
||||
</el-icon>
|
||||
</div>
|
||||
</template>
|
||||
</el-image>
|
||||
<template #error>
|
||||
<div class="image-slot">
|
||||
<el-icon>
|
||||
<Picture/>
|
||||
</el-icon>
|
||||
</div>
|
||||
</template>
|
||||
</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>
|
||||
</template>
|
||||
</v3-waterfall>
|
||||
|
||||
<div class="prompt">
|
||||
<span>{{ slotProp.item.prompt }}</span>
|
||||
<el-icon class="copy-prompt" :data-clipboard-text="slotProp.item.prompt">
|
||||
<DocumentCopy/>
|
||||
</el-icon>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<div class="footer" v-if="isOver">
|
||||
<span>没有更多数据了</span>
|
||||
<i class="iconfont icon-face"></i>
|
||||
</div>
|
||||
|
||||
<template #footer>
|
||||
<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>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import {onMounted, ref} from "vue"
|
||||
import {nextTick, onMounted, ref} from "vue"
|
||||
import {DocumentCopy, Picture} from "@element-plus/icons-vue";
|
||||
import {httpGet} from "@/utils/http";
|
||||
import {ElMessage} from "element-plus";
|
||||
import Clipboard from "clipboard";
|
||||
import {useRouter} from "vue-router";
|
||||
|
||||
const list = ref([])
|
||||
const loading = ref(true)
|
||||
const over = ref(false)
|
||||
const isOver = ref(false)
|
||||
const imgType = ref("mj") // 图片类别
|
||||
const listBoxHeight = window.innerHeight - 71
|
||||
const colWidth = ref(240)
|
||||
const fullImgHeight = ref(window.innerHeight - 60)
|
||||
const showTaskDialog = ref(false)
|
||||
const item = ref({})
|
||||
|
||||
// 计算瀑布流列宽度
|
||||
const calcColWidth = () => {
|
||||
@ -87,18 +227,24 @@ const page = ref(0)
|
||||
const pageSize = ref(20)
|
||||
// 获取下一页数据
|
||||
const getNext = () => {
|
||||
if (isOver.value) {
|
||||
return
|
||||
}
|
||||
|
||||
loading.value = true
|
||||
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
|
||||
if (list.value.length === 0) {
|
||||
list.value = res.data
|
||||
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)
|
||||
|
||||
}).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>
|
||||
|
||||
<style lang="stylus" scoped>
|
||||
<style lang="stylus">
|
||||
@import "@/assets/css/images-wall.styl"
|
||||
@import "@/assets/css/custom-scroll.styl"
|
||||
</style>
|
||||
|
Loading…
Reference in New Issue
Block a user