feat: add remove action to remove task and images for MJ and SD task list page

This commit is contained in:
RockYang 2023-12-18 17:44:52 +08:00
parent aa5a4a9977
commit a0a506a3c4
8 changed files with 162 additions and 15 deletions

View File

@ -5,6 +5,7 @@ import (
"chatplus/core/types" "chatplus/core/types"
"chatplus/service" "chatplus/service"
"chatplus/service/mj" "chatplus/service/mj"
"chatplus/service/oss"
"chatplus/store/model" "chatplus/store/model"
"chatplus/store/vo" "chatplus/store/vo"
"chatplus/utils" "chatplus/utils"
@ -22,13 +23,15 @@ type MidJourneyHandler struct {
db *gorm.DB db *gorm.DB
pool *mj.ServicePool pool *mj.ServicePool
snowflake *service.Snowflake snowflake *service.Snowflake
uploader *oss.UploaderManager
} }
func NewMidJourneyHandler(app *core.AppServer, db *gorm.DB, snowflake *service.Snowflake, pool *mj.ServicePool) *MidJourneyHandler { func NewMidJourneyHandler(app *core.AppServer, db *gorm.DB, snowflake *service.Snowflake, pool *mj.ServicePool, manager *oss.UploaderManager) *MidJourneyHandler {
h := MidJourneyHandler{ h := MidJourneyHandler{
db: db, db: db,
snowflake: snowflake, snowflake: snowflake,
pool: pool, pool: pool,
uploader: manager,
} }
h.App = app h.App = app
return &h return &h
@ -306,3 +309,30 @@ func (h *MidJourneyHandler) JobList(c *gin.Context) {
} }
resp.SUCCESS(c, jobs) resp.SUCCESS(c, jobs)
} }
// Remove remove task image
func (h *MidJourneyHandler) Remove(c *gin.Context) {
var data struct {
Id uint `json:"id"`
ImgURL string `json:"img_url"`
}
if err := c.ShouldBindJSON(&data); err != nil {
resp.ERROR(c, types.InvalidArgs)
return
}
// remove job recode
res := h.db.Delete(&model.MidJourneyJob{Id: data.Id})
if res.Error != nil {
resp.ERROR(c, res.Error.Error())
return
}
// remove image
err := h.uploader.GetUploadHandler().Delete(data.ImgURL)
if err != nil {
logger.Error("remove image failed: ", err)
}
resp.SUCCESS(c)
}

View File

@ -3,6 +3,7 @@ package handler
import ( import (
"chatplus/core" "chatplus/core"
"chatplus/core/types" "chatplus/core/types"
"chatplus/service/oss"
"chatplus/service/sd" "chatplus/service/sd"
"chatplus/store/model" "chatplus/store/model"
"chatplus/store/vo" "chatplus/store/vo"
@ -22,12 +23,14 @@ type SdJobHandler struct {
redis *redis.Client redis *redis.Client
db *gorm.DB db *gorm.DB
pool *sd.ServicePool pool *sd.ServicePool
uploader *oss.UploaderManager
} }
func NewSdJobHandler(app *core.AppServer, db *gorm.DB, pool *sd.ServicePool) *SdJobHandler { func NewSdJobHandler(app *core.AppServer, db *gorm.DB, pool *sd.ServicePool, manager *oss.UploaderManager) *SdJobHandler {
h := SdJobHandler{ h := SdJobHandler{
db: db, db: db,
pool: pool, pool: pool,
uploader: manager,
} }
h.App = app h.App = app
return &h return &h
@ -189,3 +192,30 @@ func (h *SdJobHandler) JobList(c *gin.Context) {
} }
resp.SUCCESS(c, jobs) resp.SUCCESS(c, jobs)
} }
// Remove remove task image
func (h *SdJobHandler) Remove(c *gin.Context) {
var data struct {
Id uint `json:"id"`
ImgURL string `json:"img_url"`
}
if err := c.ShouldBindJSON(&data); err != nil {
resp.ERROR(c, types.InvalidArgs)
return
}
// remove job recode
res := h.db.Delete(&model.SdJob{Id: data.Id})
if res.Error != nil {
resp.ERROR(c, res.Error.Error())
return
}
// remove image
err := h.uploader.GetUploadHandler().Delete(data.ImgURL)
if err != nil {
logger.Error("remove image failed: ", err)
}
resp.SUCCESS(c)
}

View File

@ -233,11 +233,13 @@ func main() {
group.POST("upscale", h.Upscale) group.POST("upscale", h.Upscale)
group.POST("variation", h.Variation) group.POST("variation", h.Variation)
group.GET("jobs", h.JobList) group.GET("jobs", h.JobList)
group.POST("remove", h.Remove)
}), }),
fx.Invoke(func(s *core.AppServer, h *handler.SdJobHandler) { fx.Invoke(func(s *core.AppServer, h *handler.SdJobHandler) {
group := s.Engine.Group("/api/sd") group := s.Engine.Group("/api/sd")
group.POST("image", h.Image) group.POST("image", h.Image)
group.GET("jobs", h.JobList) group.GET("jobs", h.JobList)
group.POST("remove", h.Remove)
}), }),
// 管理后台控制器 // 管理后台控制器

View File

@ -299,6 +299,7 @@
overflow: hidden; overflow: hidden;
border-radius: 6px; border-radius: 6px;
transition: all 0.3s ease; /* 添加过渡效果 */ transition: all 0.3s ease; /* 添加过渡效果 */
position: relative;
} }
.page-mj .inner .task-list-box .finish-job-list .job-item .opt .opt-line { .page-mj .inner .task-list-box .finish-job-list .job-item .opt .opt-line {
margin: 6px 0; margin: 6px 0;
@ -327,6 +328,15 @@
font-size: 20px; font-size: 20px;
cursor: pointer; cursor: pointer;
} }
.page-mj .inner .task-list-box .finish-job-list .job-item .remove {
display: none;
position: absolute;
right: 10px;
top: 10px;
}
.page-mj .inner .task-list-box .finish-job-list .job-item:hover .remove {
display: block;
}
.page-mj .inner .task-list-box .finish-job-list .animate:hover { .page-mj .inner .task-list-box .finish-job-list .animate:hover {
box-shadow: 0 0 10px rgba(71,255,241,0.6); /* 添加阴影效果 */ box-shadow: 0 0 10px rgba(71,255,241,0.6); /* 添加阴影效果 */
transform: translateY(-10px); /* 向上移动10像素 */ transform: translateY(-10px); /* 向上移动10像素 */

View File

@ -184,6 +184,7 @@
overflow: hidden; overflow: hidden;
border-radius: 6px; border-radius: 6px;
transition: all 0.3s ease; /* 添加过渡效果 */ transition: all 0.3s ease; /* 添加过渡效果 */
position: relative;
} }
.page-sd .inner .task-list-box .finish-job-list .job-item .opt .opt-line { .page-sd .inner .task-list-box .finish-job-list .job-item .opt .opt-line {
margin: 6px 0; margin: 6px 0;
@ -212,6 +213,15 @@
font-size: 20px; font-size: 20px;
cursor: pointer; cursor: pointer;
} }
.page-sd .inner .task-list-box .finish-job-list .job-item .remove {
display: none;
position: absolute;
right: 10px;
top: 10px;
}
.page-sd .inner .task-list-box .finish-job-list .job-item:hover .remove {
display: block;
}
.page-sd .inner .task-list-box .finish-job-list .animate:hover { .page-sd .inner .task-list-box .finish-job-list .animate:hover {
box-shadow: 0 0 10px rgba(71,255,241,0.6); /* 添加阴影效果 */ box-shadow: 0 0 10px rgba(71,255,241,0.6); /* 添加阴影效果 */
transform: translateY(-10px); /* 向上移动10像素 */ transform: translateY(-10px); /* 向上移动10像素 */

View File

@ -148,6 +148,7 @@
overflow hidden overflow hidden
border-radius 6px border-radius 6px
transition: all 0.3s ease; /* */ transition: all 0.3s ease; /* */
position relative
.opt { .opt {
.opt-line { .opt-line {
@ -183,6 +184,19 @@
} }
} }
} }
.remove {
display none
position absolute
right 10px
top 10px
}
&:hover{
.remove {
display block
}
}
} }
.animate { .animate {

View File

@ -417,6 +417,10 @@
</ul> </ul>
</div> </div>
</div> </div>
<div class="remove">
<el-button type="danger" :icon="Delete" @click="removeImage(scope.item)" circle/>
</div>
</div> </div>
</template> </template>
</ItemList> </ItemList>
@ -434,7 +438,7 @@
<script setup> <script setup>
import {onMounted, ref} from "vue" import {onMounted, ref} from "vue"
import { import {
ChromeFilled, ChromeFilled, Delete,
DeleteFilled, DeleteFilled,
DocumentCopy, DocumentCopy,
InfoFilled, InfoFilled,
@ -444,7 +448,7 @@ import {
} from "@element-plus/icons-vue"; } from "@element-plus/icons-vue";
import Compressor from "compressorjs"; import Compressor from "compressorjs";
import {httpGet, httpPost} from "@/utils/http"; import {httpGet, httpPost} from "@/utils/http";
import {ElMessage, ElNotification} from "element-plus"; import {ElMessage, ElMessageBox, ElNotification} from "element-plus";
import ItemList from "@/components/ItemList.vue"; import ItemList from "@/components/ItemList.vue";
import Clipboard from "clipboard"; import Clipboard from "clipboard";
import {checkSession} from "@/action/session"; import {checkSession} from "@/action/session";
@ -581,10 +585,11 @@ const fetchRunningJobs = (userId) => {
} }
runningJobs.value = _jobs runningJobs.value = _jobs
setTimeout(() => fetchRunningJobs(userId), 3000) setTimeout(() => fetchRunningJobs(userId), 1000)
}).catch(e => { }).catch(e => {
ElMessage.error("获取任务失败:" + e.message) ElMessage.error("获取任务失败:" + e.message)
setTimeout(() => fetchRunningJobs(userId), 5000)
}) })
} }
@ -592,9 +597,10 @@ const fetchFinishJobs = (userId) => {
// //
httpGet(`/api/mj/jobs?status=1&user_id=${userId}`).then(res => { httpGet(`/api/mj/jobs?status=1&user_id=${userId}`).then(res => {
finishedJobs.value = res.data finishedJobs.value = res.data
setTimeout(() => fetchFinishJobs(userId), 3000) setTimeout(() => fetchFinishJobs(userId), 1000)
}).catch(e => { }).catch(e => {
ElMessage.error("获取任务失败:" + e.message) ElMessage.error("获取任务失败:" + e.message)
setTimeout(() => fetchFinishJobs(userId), 5000)
}) })
} }
@ -674,6 +680,25 @@ const send = (url, index, item) => {
}) })
} }
const removeImage = (item) => {
ElMessageBox.confirm(
'此操作将会删除任务和图片,继续操作码?',
'删除提示',
{
confirmButtonText: '确认',
cancelButtonText: '取消',
type: 'warning',
}
).then(() => {
httpPost("/api/mj/remove", {id: item.id, img_url: item.img_url}).then(() => {
ElMessage.success("任务删除成功")
}).catch(e => {
ElMessage.error("任务删除失败:" + e.message)
})
}).catch(() => {
})
}
</script> </script>
<style lang="stylus"> <style lang="stylus">

View File

@ -371,6 +371,10 @@
</div> </div>
</template> </template>
</el-image> </el-image>
<div class="remove">
<el-button type="danger" :icon="Delete" @click="removeImage($event,scope.item)" circle/>
</div>
</div> </div>
</template> </template>
</ItemList> </ItemList>
@ -498,9 +502,9 @@
<script setup> <script setup>
import {onMounted, ref} from "vue" import {onMounted, ref} from "vue"
import {DocumentCopy, InfoFilled, Orange, Picture, Refresh} from "@element-plus/icons-vue"; import {Delete, DocumentCopy, InfoFilled, Orange, Picture, Refresh} from "@element-plus/icons-vue";
import {httpGet, httpPost} from "@/utils/http"; import {httpGet, httpPost} from "@/utils/http";
import {ElMessage, ElNotification} from "element-plus"; import {ElMessage, ElMessageBox, ElNotification} from "element-plus";
import ItemList from "@/components/ItemList.vue"; import ItemList from "@/components/ItemList.vue";
import Clipboard from "clipboard"; import Clipboard from "clipboard";
import {checkSession} from "@/action/session"; import {checkSession} from "@/action/session";
@ -598,9 +602,10 @@ onMounted(() => {
} }
runningJobs.value = _jobs runningJobs.value = _jobs
setTimeout(() => fetchRunningJobs(userId), 3000) setTimeout(() => fetchRunningJobs(userId), 1000)
}).catch(e => { }).catch(e => {
ElMessage.error("获取任务失败:" + e.message) ElMessage.error("获取任务失败:" + e.message)
setTimeout(() => fetchRunningJobs(userId), 5000)
}) })
} }
@ -608,9 +613,10 @@ onMounted(() => {
const fetchFinishJobs = (userId) => { const fetchFinishJobs = (userId) => {
httpGet(`/api/sd/jobs?status=1&user_id=${userId}`).then(res => { httpGet(`/api/sd/jobs?status=1&user_id=${userId}`).then(res => {
finishedJobs.value = res.data finishedJobs.value = res.data
setTimeout(() => fetchFinishJobs(userId), 3000) setTimeout(() => fetchFinishJobs(userId), 1000)
}).catch(e => { }).catch(e => {
ElMessage.error("获取任务失败:" + e.message) ElMessage.error("获取任务失败:" + e.message)
setTimeout(() => fetchFinishJobs(userId), 5000)
}) })
} }
@ -654,6 +660,26 @@ const copyParams = (row) => {
showTaskDialog.value = false showTaskDialog.value = false
} }
const removeImage = (event, item) => {
event.stopPropagation()
ElMessageBox.confirm(
'此操作将会删除任务和图片,继续操作码?',
'删除提示',
{
confirmButtonText: '确认',
cancelButtonText: '取消',
type: 'warning',
}
).then(() => {
httpPost("/api/sd/remove", {id: item.id, img_url: item.img_url}).then(() => {
ElMessage.success("任务删除成功")
}).catch(e => {
ElMessage.error("任务删除失败:" + e.message)
})
}).catch(() => {
})
}
</script> </script>
<style lang="stylus"> <style lang="stylus">