mirror of
https://github.com/yangjian102621/geekai.git
synced 2025-09-19 01:36:38 +08:00
feat: add remove action to remove task and images for MJ and SD task list page
This commit is contained in:
parent
aa5a4a9977
commit
a0a506a3c4
@ -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)
|
||||||
|
}
|
||||||
|
@ -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)
|
||||||
|
}
|
||||||
|
@ -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)
|
||||||
}),
|
}),
|
||||||
|
|
||||||
// 管理后台控制器
|
// 管理后台控制器
|
||||||
|
@ -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像素 */
|
||||||
|
@ -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像素 */
|
||||||
|
@ -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 {
|
||||||
|
@ -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">
|
||||||
|
@ -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">
|
||||||
|
Loading…
Reference in New Issue
Block a user