From ba20717a090779454e4966f35251a9ae305242fb Mon Sep 17 00:00:00 2001 From: RockYang Date: Wed, 9 Oct 2024 18:17:44 +0800 Subject: [PATCH] image task list page for admin console is ready --- CHANGELOG.md | 4 + api/handler/admin/image_handler.go | 174 ++++++++ api/main.go | 7 + api/store/vo/mj_job.go | 36 +- api/store/vo/sd_job.go | 3 +- web/src/components/admin/AdminSidebar.vue | 13 +- web/src/router.js | 6 + web/src/views/admin/ImageList.vue | 510 ++++++++++++++++++++++ 8 files changed, 728 insertions(+), 25 deletions(-) create mode 100644 api/handler/admin/image_handler.go create mode 100644 web/src/views/admin/ImageList.vue diff --git a/CHANGELOG.md b/CHANGELOG.md index c7c93113..d6aaf544 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,4 +1,8 @@ # 更新日志 +## v4.1.6 +* 功能优化:优化MysQL容器配置文档,解决MysQL容器资源占用过高问题 +* 功能新增:管理后台增加AI绘图任务管理,可在管理后台浏览和删除用户的绘图任务 + ## v4.1.5 * 功能优化:重构 websocket 组件,减少 websocket 连接数,全站共享一个 websocket 连接 * Bug修复:兼容手机端原生微信支付和支付宝支付渠道 diff --git a/api/handler/admin/image_handler.go b/api/handler/admin/image_handler.go new file mode 100644 index 00000000..6241d9aa --- /dev/null +++ b/api/handler/admin/image_handler.go @@ -0,0 +1,174 @@ +package admin + +// * +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +// * Copyright 2023 The Geek-AI Authors. All rights reserved. +// * Use of this source code is governed by a Apache-2.0 license +// * that can be found in the LICENSE file. +// * @Author yangjian102621@163.com +// * +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +import ( + "geekai/core" + "geekai/core/types" + "geekai/handler" + "geekai/store/model" + "geekai/store/vo" + "geekai/utils" + "geekai/utils/resp" + "github.com/gin-gonic/gin" + "gorm.io/gorm" +) + +type ImageHandler struct { + handler.BaseHandler +} + +func NewImageHandler(app *core.AppServer, db *gorm.DB) *ImageHandler { + return &ImageHandler{BaseHandler: handler.BaseHandler{App: app, DB: db}} +} + +type query struct { + Prompt string `json:"prompt"` + Username string `json:"username"` + CreatedAt []string `json:"created_time"` + Page int `json:"page"` + PageSize int `json:"page_size"` +} + +// MjList Midjourney 任务列表 +func (h *ImageHandler) MjList(c *gin.Context) { + var data query + if err := c.ShouldBindJSON(&data); err != nil { + resp.ERROR(c, types.InvalidArgs) + return + } + + session := h.DB.Session(&gorm.Session{}) + if data.Username != "" { + var user model.User + err := h.DB.Where("username", data.Username).First(&user).Error + if err == nil { + session = session.Where("user_id", user.Id) + } + } + if data.Prompt != "" { + session = session.Where("prompt LIKE ?", "%"+data.Prompt+"%") + } + if len(data.CreatedAt) == 2 { + start := utils.Str2stamp(data.CreatedAt[0] + " 00:00:00") + end := utils.Str2stamp(data.CreatedAt[1] + " 00:00:00") + session = session.Where("created_at >= ? AND created_at <= ?", start, end) + } + var total int64 + session.Model(&model.MidJourneyJob{}).Count(&total) + var list []model.MidJourneyJob + var items = make([]vo.MidJourneyJob, 0) + offset := (data.Page - 1) * data.PageSize + err := session.Order("id DESC").Offset(offset).Limit(data.PageSize).Find(&list).Error + if err == nil { + // 填充数据 + for _, item := range list { + var job vo.MidJourneyJob + err = utils.CopyObject(item, &job) + if err != nil { + continue + } + job.CreatedAt = item.CreatedAt.Unix() + items = append(items, job) + } + } + + resp.SUCCESS(c, vo.NewPage(total, data.Page, data.PageSize, items)) +} + +// SdList Stable Diffusion 任务列表 +func (h *ImageHandler) SdList(c *gin.Context) { + var data query + if err := c.ShouldBindJSON(&data); err != nil { + resp.ERROR(c, types.InvalidArgs) + return + } + + session := h.DB.Session(&gorm.Session{}) + if data.Username != "" { + var user model.User + err := h.DB.Where("username", data.Username).First(&user).Error + if err == nil { + session = session.Where("user_id", user.Id) + } + } + if data.Prompt != "" { + session = session.Where("prompt LIKE ?", "%"+data.Prompt+"%") + } + if len(data.CreatedAt) == 2 { + start := utils.Str2stamp(data.CreatedAt[0] + " 00:00:00") + end := utils.Str2stamp(data.CreatedAt[1] + " 00:00:00") + session = session.Where("created_at >= ? AND created_at <= ?", start, end) + } + var total int64 + session.Model(&model.SdJob{}).Count(&total) + var list []model.SdJob + var items = make([]vo.SdJob, 0) + offset := (data.Page - 1) * data.PageSize + err := session.Order("id DESC").Offset(offset).Limit(data.PageSize).Find(&list).Error + if err == nil { + // 填充数据 + for _, item := range list { + var job vo.SdJob + err = utils.CopyObject(item, &job) + if err != nil { + continue + } + job.CreatedAt = item.CreatedAt.Unix() + items = append(items, job) + } + } + + resp.SUCCESS(c, vo.NewPage(total, data.Page, data.PageSize, items)) +} + +// DallList DALL-E 任务列表 +func (h *ImageHandler) DallList(c *gin.Context) { + var data query + if err := c.ShouldBindJSON(&data); err != nil { + resp.ERROR(c, types.InvalidArgs) + return + } + + session := h.DB.Session(&gorm.Session{}) + if data.Username != "" { + var user model.User + err := h.DB.Where("username", data.Username).First(&user).Error + if err == nil { + session = session.Where("user_id", user.Id) + } + } + if data.Prompt != "" { + session = session.Where("prompt LIKE ?", "%"+data.Prompt+"%") + } + if len(data.CreatedAt) == 2 { + start := utils.Str2stamp(data.CreatedAt[0] + " 00:00:00") + end := utils.Str2stamp(data.CreatedAt[1] + " 00:00:00") + session = session.Where("created_at >= ? AND created_at <= ?", start, end) + } + var total int64 + session.Model(&model.DallJob{}).Count(&total) + var list []model.DallJob + var items = make([]vo.DallJob, 0) + offset := (data.Page - 1) * data.PageSize + err := session.Order("id DESC").Offset(offset).Limit(data.PageSize).Find(&list).Error + if err == nil { + // 填充数据 + for _, item := range list { + var job vo.DallJob + err = utils.CopyObject(item, &job) + if err != nil { + continue + } + job.CreatedAt = item.CreatedAt.Unix() + items = append(items, job) + } + } + + resp.SUCCESS(c, vo.NewPage(total, data.Page, data.PageSize, items)) +} diff --git a/api/main.go b/api/main.go index 6d1f1058..0810b342 100644 --- a/api/main.go +++ b/api/main.go @@ -539,6 +539,13 @@ func main() { }, }) }), + fx.Provide(admin.NewImageHandler), + fx.Invoke(func(s *core.AppServer, h *admin.ImageHandler) { + group := s.Engine.Group("/api/admin/image") + group.POST("/list/mj", h.MjList) + group.POST("/list/sd", h.SdList) + group.POST("/list/dall", h.DallList) + }), ) // 启动应用程序 go func() { diff --git a/api/store/vo/mj_job.go b/api/store/vo/mj_job.go index 59ec11c6..458e9a2d 100644 --- a/api/store/vo/mj_job.go +++ b/api/store/vo/mj_job.go @@ -1,23 +1,21 @@ package vo -import "time" - type MidJourneyJob struct { - Id uint `json:"id"` - Type string `json:"type"` - UserId int `json:"user_id"` - ChannelId string `json:"channel_id"` - TaskId string `json:"task_id"` - MessageId string `json:"message_id"` - ReferenceId string `json:"reference_id"` - ImgURL string `json:"img_url"` - OrgURL string `json:"org_url"` - Hash string `json:"hash"` - Progress int `json:"progress"` - Prompt string `json:"prompt"` - UseProxy bool `json:"use_proxy"` - Publish bool `json:"publish"` - ErrMsg string `json:"err_msg"` - Power int `json:"power"` - CreatedAt time.Time `json:"created_at"` + Id uint `json:"id"` + Type string `json:"type"` + UserId int `json:"user_id"` + ChannelId string `json:"channel_id"` + TaskId string `json:"task_id"` + MessageId string `json:"message_id"` + ReferenceId string `json:"reference_id"` + ImgURL string `json:"img_url"` + OrgURL string `json:"org_url"` + Hash string `json:"hash"` + Progress int `json:"progress"` + Prompt string `json:"prompt"` + UseProxy bool `json:"use_proxy"` + Publish bool `json:"publish"` + ErrMsg string `json:"err_msg"` + Power int `json:"power"` + CreatedAt int64 `json:"created_at"` } diff --git a/api/store/vo/sd_job.go b/api/store/vo/sd_job.go index 8d521504..dc712dca 100644 --- a/api/store/vo/sd_job.go +++ b/api/store/vo/sd_job.go @@ -2,7 +2,6 @@ package vo import ( "geekai/core/types" - "time" ) type SdJob struct { @@ -17,5 +16,5 @@ type SdJob struct { Publish bool `json:"publish"` ErrMsg string `json:"err_msg"` Power int `json:"power"` - CreatedAt time.Time `json:"created_at"` + CreatedAt int64 `json:"created_at"` } diff --git a/web/src/components/admin/AdminSidebar.vue b/web/src/components/admin/AdminSidebar.vue index 6f420968..61354001 100644 --- a/web/src/components/admin/AdminSidebar.vue +++ b/web/src/components/admin/AdminSidebar.vue @@ -33,7 +33,7 @@ {{ threeItem.title }} - + {{ subItem.title }} @@ -64,8 +64,8 @@ const logo = ref('') // 加载系统配置 httpGet('/api/admin/config/get?key=system').then(res => { - title.value = res.data['admin_title'] - logo.value = res.data['logo'] + title.value = res.data.admin_title + logo.value = res.data.logo }).catch(e => { ElMessage.error("加载系统配置失败: " + e.message) }) @@ -101,7 +101,7 @@ const items = [ }, ], }, - + { icon: 'api-key', index: '/admin/apikey', @@ -137,6 +137,11 @@ const items = [ index: '/admin/chats', title: '对话管理', }, + { + icon: 'image', + index: '/admin/images', + title: '绘图管理', + }, { icon: 'role', index: '/admin/manger', diff --git a/web/src/router.js b/web/src/router.js index 33eef5ad..2ca79100 100644 --- a/web/src/router.js +++ b/web/src/router.js @@ -233,6 +233,12 @@ const routes = [ meta: {title: '对话管理'}, component: () => import('@/views/admin/ChatList.vue'), }, + { + path: '/admin/images', + name: 'admin-images', + meta: {title: '绘图管理'}, + component: () => import('@/views/admin/ImageList.vue'), + }, { path: '/admin/powerLog', name: 'admin-power-log', diff --git a/web/src/views/admin/ImageList.vue b/web/src/views/admin/ImageList.vue new file mode 100644 index 00000000..ca4df89f --- /dev/null +++ b/web/src/views/admin/ImageList.vue @@ -0,0 +1,510 @@ + + + + + \ No newline at end of file