diff --git a/CHANGELOG.md b/CHANGELOG.md index e96a7755..07c6188d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,4 +1,8 @@ # 更新日志 + +## v4.1.2 +* Bug修复:修复思维导图页面获取模型失败的问题 + ## v4.1.1 * Bug修复:修复 GPT 模型 function call 调用后没有输出的问题 * 功能新增:允许获取 License 授权用户可以自定义版权信息 diff --git a/api/core/app_server.go b/api/core/app_server.go index 3fb32096..84bc89a8 100644 --- a/api/core/app_server.go +++ b/api/core/app_server.go @@ -225,7 +225,7 @@ func needLogin(c *gin.Context) bool { c.Request.URL.Path == "/api/payment/doPay" || c.Request.URL.Path == "/api/payment/payWays" || c.Request.URL.Path == "/api/suno/client" || - c.Request.URL.Path == "/api/suno/Detail" || + c.Request.URL.Path == "/api/suno/detail" || c.Request.URL.Path == "/api/suno/play" || strings.HasPrefix(c.Request.URL.Path, "/api/test") || strings.HasPrefix(c.Request.URL.Path, "/api/user/clogin") || diff --git a/api/core/types/chat.go b/api/core/types/chat.go index cdf418b6..ccaf0a9c 100644 --- a/api/core/types/chat.go +++ b/api/core/types/chat.go @@ -61,7 +61,6 @@ type ChatSession struct { type ChatModel struct { Id uint `json:"id"` - Platform string `json:"platform"` Name string `json:"name"` Value string `json:"value"` Power int `json:"power"` diff --git a/api/handler/chatimpl/chat_handler.go b/api/handler/chatimpl/chat_handler.go index a8c12362..6b1e9f8e 100644 --- a/api/handler/chatimpl/chat_handler.go +++ b/api/handler/chatimpl/chat_handler.go @@ -468,7 +468,7 @@ func (h *ChatHandler) doRequest(ctx context.Context, req types.ApiRequest, sessi } else { client = http.DefaultClient } - logger.Debugf("Sending %s request, Channel:%s, API KEY:%s, PROXY: %s, Model: %s", session.Model.Platform, apiKey.ApiURL, apiURL, apiKey.ProxyURL, req.Model) + logger.Debugf("Sending %s request, API KEY:%s, PROXY: %s, Model: %s", apiKey.ApiURL, apiURL, apiKey.ProxyURL, req.Model) request.Header.Set("Authorization", fmt.Sprintf("Bearer %s", apiKey.Value)) // 更新API KEY 最后使用时间 h.DB.Model(&model.ApiKey{}).Where("id", apiKey.Id).UpdateColumn("last_used_at", time.Now().Unix()) diff --git a/api/handler/dalle_handler.go b/api/handler/dalle_handler.go index 89226638..65d631fb 100644 --- a/api/handler/dalle_handler.go +++ b/api/handler/dalle_handler.go @@ -8,6 +8,7 @@ package handler // * +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ import ( + "fmt" "geekai/core" "geekai/core/types" "geekai/service/dalle" @@ -16,9 +17,9 @@ import ( "geekai/store/vo" "geekai/utils" "geekai/utils/resp" - "net/http" - "github.com/gorilla/websocket" + "net/http" + "time" "github.com/gin-gonic/gin" "github.com/go-redis/redis/v8" @@ -178,7 +179,7 @@ func (h *DallJobHandler) getData(finish bool, userId uint, page int, pageSize in session := h.DB.Session(&gorm.Session{}) if finish { - session = session.Where("progress = ?", 100).Order("id DESC") + session = session.Where("progress >= ?", 100).Order("id DESC") } else { session = session.Where("progress < ?", 100).Order("id ASC") } @@ -215,20 +216,51 @@ func (h *DallJobHandler) getData(finish bool, userId uint, page int, pageSize in // Remove remove task image func (h *DallJobHandler) Remove(c *gin.Context) { id := h.GetInt(c, "id", 0) - userId := h.GetInt(c, "user_id", 0) + userId := h.GetLoginUserId(c) var job model.DallJob if res := h.DB.Where("id = ? AND user_id = ?", id, userId).First(&job); res.Error != nil { resp.ERROR(c, "记录不存在") return } - // remove job recode - res := h.DB.Delete(&model.DallJob{Id: job.Id}) - if res.Error != nil { - resp.ERROR(c, res.Error.Error()) + // 删除任务 + tx := h.DB.Begin() + if err := tx.Delete(&job).Error; err != nil { + tx.Rollback() + resp.ERROR(c, err.Error()) return } + // 如果任务未完成,或者任务失败,则恢复用户算力 + if job.Progress != 100 { + err := tx.Model(&model.User{}).Where("id = ?", job.UserId).UpdateColumn("power", gorm.Expr("power + ?", job.Power)).Error + if err != nil { + tx.Rollback() + resp.ERROR(c, err.Error()) + return + } + + var user model.User + h.DB.Where("id = ?", job.UserId).First(&user) + err = tx.Create(&model.PowerLog{ + UserId: user.Id, + Username: user.Username, + Type: types.PowerConsume, + Amount: job.Power, + Balance: user.Power, + Mark: types.PowerAdd, + Model: "dall-e-3", + Remark: fmt.Sprintf("任务失败,退回算力。任务ID:%d,Err: %s", job.Id, job.ErrMsg), + CreatedAt: time.Now(), + }).Error + if err != nil { + tx.Rollback() + resp.ERROR(c, err.Error()) + return + } + } + tx.Commit() + // remove image err := h.uploader.GetUploadHandler().Delete(job.ImgURL) if err != nil { @@ -241,10 +273,10 @@ func (h *DallJobHandler) Remove(c *gin.Context) { // Publish 发布/取消发布图片到画廊显示 func (h *DallJobHandler) Publish(c *gin.Context) { id := h.GetInt(c, "id", 0) - userId := h.GetInt(c, "user_id", 0) + userId := h.GetLoginUserId(c) action := h.GetBool(c, "action") // 发布动作,true => 发布,false => 取消分享 - res := h.DB.Model(&model.DallJob{Id: uint(id), UserId: uint(userId)}).UpdateColumn("publish", action) + res := h.DB.Model(&model.DallJob{Id: uint(id), UserId: userId}).UpdateColumn("publish", action) if res.Error != nil { logger.Error("error with update database:", res.Error) resp.ERROR(c, "更新数据库失败") diff --git a/api/handler/markmap_handler.go b/api/handler/markmap_handler.go index e6926f07..8196a81e 100644 --- a/api/handler/markmap_handler.go +++ b/api/handler/markmap_handler.go @@ -101,17 +101,13 @@ func (h *MarkMapHandler) sendMessage(client *types.WsClient, prompt string, mode return fmt.Errorf("error with query chat model: %v", res.Error) } - if user.Status == false { - return errors.New("当前用户被禁用") - } - if user.Power < chatModel.Power { return fmt.Errorf("您当前剩余算力(%d)已不足以支付当前模型算力(%d)!", user.Power, chatModel.Power) } messages := make([]interface{}, 0) messages = append(messages, types.Message{Role: "system", Content: ` -你是一位非常优秀的思维导图助手,你会把用户的所有提问都总结成思维导图,然后以 Markdown 格式输出。markdown 只需要输出一级标题,二级标题,三级标题,四级标题,最多输出四级,除此之外不要输出任何其他 markdown 标记。下面是一个合格的例子: +你是一位非常优秀的思维导图助手, 你能帮助用户整理思路,根据用户提供的主题或内容,快速生成结构清晰,有条理的思维导图,然后以 Markdown 格式输出。markdown 只需要输出一级标题,二级标题,三级标题,四级标题,最多输出四级,除此之外不要输出任何其他 markdown 标记。下面是一个合格的例子: # Geek-AI 助手 ## 完整的开源系统 @@ -130,7 +126,7 @@ func (h *MarkMapHandler) sendMessage(client *types.WsClient, prompt string, mode 另外,除此之外不要任何解释性语句。 `}) - messages = append(messages, types.Message{Role: "user", Content: prompt}) + messages = append(messages, types.Message{Role: "user", Content: fmt.Sprintf("请生成一份有关【%s】一份思维导图,要求结构清晰,有条理", prompt)}) var req = types.ApiRequest{ Model: chatModel.Value, Stream: true, @@ -253,5 +249,6 @@ func (h *MarkMapHandler) doRequest(req types.ApiRequest, chatModel model.ChatMod client = http.DefaultClient } request.Header.Set("Authorization", fmt.Sprintf("Bearer %s", apiKey.Value)) + logger.Debugf("Sending %s request, API KEY:%s, PROXY: %s, Model: %s", apiKey.ApiURL, apiURL, apiKey.ProxyURL, req.Model) return client.Do(request) } diff --git a/api/handler/mj_handler.go b/api/handler/mj_handler.go index 5b49f51a..049af981 100644 --- a/api/handler/mj_handler.go +++ b/api/handler/mj_handler.go @@ -465,35 +465,37 @@ func (h *MidJourneyHandler) Remove(c *gin.Context) { return } - // refund power - err := tx.Model(&model.User{}).Where("id = ?", job.UserId).UpdateColumn("power", gorm.Expr("power + ?", job.Power)).Error - if err != nil { - tx.Rollback() - resp.ERROR(c, err.Error()) - return - } - var user model.User - h.DB.Where("id = ?", job.UserId).First(&user) - err = tx.Create(&model.PowerLog{ - UserId: user.Id, - Username: user.Username, - Type: types.PowerConsume, - Amount: job.Power, - Balance: user.Power + job.Power, - Mark: types.PowerAdd, - Model: "mid-journey", - Remark: fmt.Sprintf("绘画任务失败,退回算力。任务ID:%s", job.TaskId), - CreatedAt: time.Now(), - }).Error - if err != nil { - tx.Rollback() - resp.ERROR(c, err.Error()) - return + // 如果任务未完成,或者任务失败,则恢复用户算力 + if job.Progress != 100 { + err := tx.Model(&model.User{}).Where("id = ?", job.UserId).UpdateColumn("power", gorm.Expr("power + ?", job.Power)).Error + if err != nil { + tx.Rollback() + resp.ERROR(c, err.Error()) + return + } + var user model.User + h.DB.Where("id = ?", job.UserId).First(&user) + err = tx.Create(&model.PowerLog{ + UserId: user.Id, + Username: user.Username, + Type: types.PowerConsume, + Amount: job.Power, + Balance: user.Power, + Mark: types.PowerAdd, + Model: "mid-journey", + Remark: fmt.Sprintf("绘画任务失败,退回算力。任务ID:%s,Err: %s", job.TaskId, job.ErrMsg), + CreatedAt: time.Now(), + }).Error + if err != nil { + tx.Rollback() + resp.ERROR(c, err.Error()) + return + } } tx.Commit() // remove image - err = h.uploader.GetUploadHandler().Delete(job.ImgURL) + err := h.uploader.GetUploadHandler().Delete(job.ImgURL) if err != nil { logger.Error("remove image failed: ", err) } diff --git a/api/handler/sd_handler.go b/api/handler/sd_handler.go index c99d2f9b..18710358 100644 --- a/api/handler/sd_handler.go +++ b/api/handler/sd_handler.go @@ -232,7 +232,7 @@ func (h *SdJobHandler) getData(finish bool, userId uint, page int, pageSize int, session := h.DB.Session(&gorm.Session{}) if finish { - session = session.Where("progress = ?", 100).Order("id DESC") + session = session.Where("progress >= ?", 100).Order("id DESC") } else { session = session.Where("progress < ?", 100).Order("id ASC") } @@ -278,20 +278,50 @@ func (h *SdJobHandler) getData(finish bool, userId uint, page int, pageSize int, // Remove remove task image func (h *SdJobHandler) Remove(c *gin.Context) { id := h.GetInt(c, "id", 0) - userId := h.GetInt(c, "user_id", 0) + userId := h.GetLoginUserId(c) var job model.SdJob if res := h.DB.Where("id = ? AND user_id = ?", id, userId).First(&job); res.Error != nil { resp.ERROR(c, "记录不存在") return } - // remove job recode - res := h.DB.Delete(&model.SdJob{Id: job.Id}) - if res.Error != nil { - resp.ERROR(c, res.Error.Error()) + // 删除任务 + tx := h.DB.Begin() + if err := tx.Delete(&job).Error; err != nil { + tx.Rollback() + resp.ERROR(c, err.Error()) return } + // 如果任务未完成,或者任务失败,则恢复用户算力 + if job.Progress != 100 { + err := tx.Model(&model.User{}).Where("id = ?", job.UserId).UpdateColumn("power", gorm.Expr("power + ?", job.Power)).Error + if err != nil { + tx.Rollback() + resp.ERROR(c, err.Error()) + return + } + var user model.User + h.DB.Where("id = ?", job.UserId).First(&user) + err = tx.Create(&model.PowerLog{ + UserId: user.Id, + Username: user.Username, + Type: types.PowerConsume, + Amount: job.Power, + Balance: user.Power, + Mark: types.PowerAdd, + Model: "stable-diffusion", + Remark: fmt.Sprintf("任务失败,退回算力。任务ID:%s, Err: %s", job.TaskId, job.ErrMsg), + CreatedAt: time.Now(), + }).Error + if err != nil { + tx.Rollback() + resp.ERROR(c, err.Error()) + return + } + } + tx.Commit() + // remove image err := h.uploader.GetUploadHandler().Delete(job.ImgURL) if err != nil { @@ -309,10 +339,10 @@ func (h *SdJobHandler) Remove(c *gin.Context) { // Publish 发布/取消发布图片到画廊显示 func (h *SdJobHandler) Publish(c *gin.Context) { id := h.GetInt(c, "id", 0) - userId := h.GetInt(c, "user_id", 0) + userId := h.GetLoginUserId(c) action := h.GetBool(c, "action") // 发布动作,true => 发布,false => 取消分享 - res := h.DB.Model(&model.SdJob{Id: uint(id), UserId: userId}).UpdateColumn("publish", action) + res := h.DB.Model(&model.SdJob{Id: uint(id), UserId: int(userId)}).UpdateColumn("publish", action) if res.Error != nil { logger.Error("error with update database:", res.Error) resp.ERROR(c, "更新数据库失败") diff --git a/api/handler/suno_handler.go b/api/handler/suno_handler.go index 4fbf031a..b2fba821 100644 --- a/api/handler/suno_handler.go +++ b/api/handler/suno_handler.go @@ -210,7 +210,42 @@ func (h *SunoHandler) Remove(c *gin.Context) { return } // 删除任务 - h.DB.Delete(&job) + tx := h.DB.Begin() + if err := tx.Delete(&job).Error; err != nil { + tx.Rollback() + resp.ERROR(c, err.Error()) + return + } + + // 如果任务未完成,或者任务失败,则恢复用户算力 + if job.Progress != 100 { + err := tx.Model(&model.User{}).Where("id = ?", job.UserId).UpdateColumn("power", gorm.Expr("power + ?", job.Power)).Error + if err != nil { + tx.Rollback() + resp.ERROR(c, err.Error()) + return + } + var user model.User + h.DB.Where("id = ?", job.UserId).First(&user) + err = tx.Create(&model.PowerLog{ + UserId: user.Id, + Username: user.Username, + Type: types.PowerConsume, + Amount: job.Power, + Balance: user.Power, + Mark: types.PowerAdd, + Model: job.ModelName, + Remark: fmt.Sprintf("Suno 任务失败,退回算力。任务ID:%s,Err:%s", job.TaskId, job.ErrMsg), + CreatedAt: time.Now(), + }).Error + if err != nil { + tx.Rollback() + resp.ERROR(c, err.Error()) + return + } + } + tx.Commit() + // 删除文件 _ = h.uploader.GetUploadHandler().Delete(job.CoverURL) _ = h.uploader.GetUploadHandler().Delete(job.AudioURL) diff --git a/api/service/dalle/service.go b/api/service/dalle/service.go index 20d136c7..5c5a1929 100644 --- a/api/service/dalle/service.go +++ b/api/service/dalle/service.go @@ -70,7 +70,7 @@ func (s *Service) Run() { if err != nil { logger.Errorf("error with image task: %v", err) s.db.Model(&model.DallJob{Id: task.JobId}).UpdateColumns(map[string]interface{}{ - "progress": -1, + "progress": 101, "err_msg": err.Error(), }) s.notifyQueue.RPush(sd.NotifyMessage{UserId: int(task.UserId), JobId: int(task.JobId), Message: sd.Failed}) @@ -148,7 +148,7 @@ func (s *Service) Image(task types.DallTask, sync bool) (string, error) { Where("enabled", true). Order("last_used_at ASC").First(&apiKey) if tx.Error != nil { - return "", fmt.Errorf("no available IMG api key: %v", tx.Error) + return "", fmt.Errorf("no available DALL-E api key: %v", tx.Error) } var res imgRes @@ -225,6 +225,30 @@ func (s *Service) CheckTaskNotify() { }() } +func (s *Service) CheckTaskStatus() { + go func() { + logger.Info("Running DALL-E task status checking ...") + for { + var jobs []model.DallJob + res := s.db.Where("progress < ?", 100).Find(&jobs) + if res.Error != nil { + time.Sleep(5 * time.Second) + continue + } + + for _, job := range jobs { + // 超时的任务标记为失败 + if time.Now().Sub(job.CreatedAt) > time.Minute*10 { + job.Progress = 101 + job.ErrMsg = "任务超时" + s.db.Updates(&job) + } + } + time.Sleep(time.Second * 10) + } + }() +} + func (s *Service) DownloadImages() { go func() { var items []model.DallJob @@ -271,44 +295,3 @@ func (s *Service) downloadImage(jobId uint, userId int, orgURL string) (string, s.notifyQueue.RPush(sd.NotifyMessage{UserId: userId, JobId: int(jobId), Message: sd.Finished}) return imgURL, nil } - -// CheckTaskStatus 检查任务状态,自动删除过期或者失败的任务 -func (s *Service) CheckTaskStatus() { - go func() { - logger.Info("Running Stable-Diffusion task status checking ...") - for { - var jobs []model.DallJob - res := s.db.Where("progress < ?", 100).Find(&jobs) - if res.Error != nil { - time.Sleep(5 * time.Second) - continue - } - - for _, job := range jobs { - // 5 分钟还没完成的任务直接删除 - if time.Now().Sub(job.CreatedAt) > time.Minute*5 || job.Progress == -1 { - s.db.Delete(&job) - var user model.User - s.db.Where("id = ?", job.UserId).First(&user) - // 退回绘图次数 - res = s.db.Model(&model.User{}).Where("id = ?", job.UserId).UpdateColumn("power", gorm.Expr("power + ?", job.Power)) - if res.Error == nil && res.RowsAffected > 0 { - s.db.Create(&model.PowerLog{ - UserId: user.Id, - Username: user.Username, - Type: types.PowerConsume, - Amount: job.Power, - Balance: user.Power + job.Power, - Mark: types.PowerAdd, - Model: "dall-e-3", - Remark: fmt.Sprintf("任务失败,退回算力。任务ID:%d", job.Id), - CreatedAt: time.Now(), - }) - } - continue - } - } - time.Sleep(time.Second * 10) - } - }() -} diff --git a/api/service/mj/pool.go b/api/service/mj/pool.go index 80ed6067..0e319fe6 100644 --- a/api/service/mj/pool.go +++ b/api/service/mj/pool.go @@ -187,6 +187,14 @@ func (p *ServicePool) SyncTaskProgress() { } for _, job := range jobs { + // 5 分钟还没完成的任务标记为失败 + if time.Now().Sub(job.CreatedAt) > time.Minute*5 { + job.Progress = 101 + job.ErrMsg = "任务超时" + p.db.Updates(&job) + continue + } + if servicePlus := p.getService(job.ChannelId); servicePlus != nil { _ = servicePlus.Notify(job) } diff --git a/api/service/sd/pool.go b/api/service/sd/pool.go index 548875ec..1d70a64a 100644 --- a/api/service/sd/pool.go +++ b/api/service/sd/pool.go @@ -109,27 +109,11 @@ func (p *ServicePool) CheckTaskStatus() { } for _, job := range jobs { - // 5 分钟还没完成的任务直接删除 - if time.Now().Sub(job.CreatedAt) > time.Minute*5 || job.Progress == -1 { - p.db.Delete(&job) - var user model.User - p.db.Where("id = ?", job.UserId).First(&user) - // 退回绘图次数 - res = p.db.Model(&model.User{}).Where("id = ?", job.UserId).UpdateColumn("power", gorm.Expr("power + ?", job.Power)) - if res.Error == nil && res.RowsAffected > 0 { - p.db.Create(&model.PowerLog{ - UserId: user.Id, - Username: user.Username, - Type: types.PowerConsume, - Amount: job.Power, - Balance: user.Power + job.Power, - Mark: types.PowerAdd, - Model: "stable-diffusion", - Remark: fmt.Sprintf("任务失败,退回算力。任务ID:%s", job.TaskId), - CreatedAt: time.Now(), - }) - } - continue + // 5 分钟还没完成的任务标记为失败 + if time.Now().Sub(job.CreatedAt) > time.Minute*5 { + job.Progress = 101 + job.ErrMsg = "任务超时" + p.db.Updates(&job) } } time.Sleep(time.Second * 5) diff --git a/api/service/sd/service.go b/api/service/sd/service.go index dbb3a3c0..a9d707c7 100644 --- a/api/service/sd/service.go +++ b/api/service/sd/service.go @@ -87,7 +87,7 @@ func (s *Service) Run() { logger.Error("绘画任务执行失败:", err.Error()) // update the task progress s.db.Model(&model.SdJob{Id: uint(task.Id)}).UpdateColumns(map[string]interface{}{ - "progress": -1, + "progress": 101, "err_msg": err.Error(), }) // 通知前端,任务失败 diff --git a/web/.env.development b/web/.env.development index 27102ba0..f3eb9e14 100644 --- a/web/.env.development +++ b/web/.env.development @@ -4,8 +4,8 @@ VUE_APP_USER=18575670125 VUE_APP_PASS=12345678 VUE_APP_ADMIN_USER=admin VUE_APP_ADMIN_PASS=admin123 -VUE_APP_KEY_PREFIX=ChatPLUS_DEV_ +VUE_APP_KEY_PREFIX=GeekAI_DEV_ VUE_APP_TITLE="Geek-AI 创作系统" -VUE_APP_VERSION=v4.1.1 +VUE_APP_VERSION=v4.1.2 VUE_APP_DOCS_URL=https://docs.geekai.me VUE_APP_GIT_URL=https://github.com/yangjian102621/geekai diff --git a/web/.env.production b/web/.env.production index 6e3a7049..eb506d0f 100644 --- a/web/.env.production +++ b/web/.env.production @@ -1,6 +1,6 @@ VUE_APP_API_HOST= VUE_APP_WS_HOST= -VUE_APP_KEY_PREFIX=ChatPLUS_ -VUE_APP_VERSION=v4.1.1 +VUE_APP_KEY_PREFIX=GeekAI_ +VUE_APP_VERSION=v4.1.2 VUE_APP_DOCS_URL=https://docs.geekai.me VUE_APP_GIT_URL=https://github.com/yangjian102621/geekai diff --git a/web/src/assets/css/image-dall.styl b/web/src/assets/css/image-dall.styl index 57d222ce..331d4f7a 100644 --- a/web/src/assets/css/image-dall.styl +++ b/web/src/assets/css/image-dall.styl @@ -221,134 +221,7 @@ // 任务列表 - - .job-list-box { - - @import "running-job-list.styl" - - .finish-job-list { - #waterfall { - display flex - justify-content center - padding-top 20px - flex-flow column - - - .job-item { - width 100% - height 100% - border 1px solid #666666 - padding 6px - overflow hidden - border-radius 6px - transition: all 0.3s ease; /* 添加过渡效果 */ - position relative - - .opt { - .opt-line { - margin 6px 0 - - ul { - display flex - flex-flow row - - li { - margin-right 6px - - a { - padding 3px 0 - width 40px - 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 - } - } - } - } - - - .remove { - display none - position absolute - right 10px - top 10px - } - - &:hover { - .remove { - display block - } - } - } - - - .animate { - &:hover { - box-shadow: 0 0 10px rgba(71, 255, 241, 0.6); /* 添加阴影效果 */ - transform: translateY(-10px); /* 向上移动10像素 */ - } - } - } - } - - - .el-image { - width 100% - height 100% - overflow visible - - .el-image-viewer__wrapper { - img { - width auto - height auto - } - } - - .image-slot { - display flex - flex-flow column - justify-content center - align-items center - min-height 200px - color #ffffff - - .iconfont { - font-size 50px - margin-bottom 10px - } - } - } - - .el-image.upscale { - img { - height 310px - } - - .image-slot { - height 310px - } - - .el-image-viewer__wrapper { - img { - width auto - height auto - } - } - } - } + @import "waterfall-list.styl" } .no-more-data { diff --git a/web/src/assets/css/image-sd.styl b/web/src/assets/css/image-sd.styl index 2008f562..90594e59 100644 --- a/web/src/assets/css/image-sd.styl +++ b/web/src/assets/css/image-sd.styl @@ -220,136 +220,8 @@ } } - // 任务列表 - - .job-list-box { - - @import "running-job-list.styl" - - .finish-job-list { - #waterfall { - display flex - justify-content center - padding-top 20px - flex-flow column - - - .job-item { - width 100% - height 100% - border 1px solid #666666 - padding 6px - overflow hidden - border-radius 6px - transition: all 0.3s ease; /* 添加过渡效果 */ - position relative - - .opt { - .opt-line { - margin 6px 0 - - ul { - display flex - flex-flow row - - li { - margin-right 6px - - a { - padding 3px 0 - width 40px - 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 - } - } - } - } - - - .remove { - display none - position absolute - right 10px - top 10px - } - - &:hover { - .remove { - display block - } - } - } - - - .animate { - &:hover { - box-shadow: 0 0 10px rgba(71, 255, 241, 0.6); /* 添加阴影效果 */ - transform: translateY(-10px); /* 向上移动10像素 */ - } - } - } - } - - - .el-image { - width 100% - height 100% - overflow visible - - .el-image-viewer__wrapper { - img { - width auto - height auto - } - } - - .image-slot { - display flex - flex-flow column - justify-content center - align-items center - min-height 200px - color #ffffff - - .iconfont { - font-size 50px - margin-bottom 10px - } - } - } - - .el-image.upscale { - img { - height 310px - } - - .image-slot { - height 310px - } - - .el-image-viewer__wrapper { - img { - width auto - height auto - } - } - } - } + @import "waterfall-list.styl" } .no-more-data { diff --git a/web/src/assets/css/waterfall-list.styl b/web/src/assets/css/waterfall-list.styl new file mode 100644 index 00000000..071c5302 --- /dev/null +++ b/web/src/assets/css/waterfall-list.styl @@ -0,0 +1,146 @@ +.job-list-box { + + @import "running-job-list.styl" + + .finish-job-list { + #waterfall { + display flex + justify-content center + padding-top 20px + flex-flow column + + + .job-item { + width 100% + height 100% + border 1px solid #666666 + padding 6px + overflow hidden + border-radius 6px + transition: all 0.3s ease; /* 添加过渡效果 */ + position relative + + .opt { + .opt-line { + margin 6px 0 + + ul { + display flex + flex-flow row + + li { + margin-right 6px + + a { + padding 3px 0 + width 40px + 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 + } + } + } + } + + + .remove { + display none + position absolute + right 10px + top 10px + } + + &:hover { + .remove { + display block + } + } + } + + + .animate { + &:hover { + box-shadow: 0 0 10px rgba(71, 255, 241, 0.6); /* 添加阴影效果 */ + transform: translateY(-10px); /* 向上移动10像素 */ + } + } + } + } + + + .el-image { + width 100% + height 100% + overflow visible + + .el-image-viewer__wrapper { + img { + width auto + height auto + } + } + + .image-slot { + display flex + flex-flow column + justify-content center + align-items center + min-height 220px + color #ffffff + + .err-msg-container { + overflow hidden + word-break break-all + padding 15px + .title { + font-size 20px + text-align center + font-weight bold + color #f56c6c + margin-bottom 30px + } + + .opt { + display flex + justify-content center + } + } + .iconfont { + font-size 50px + margin-bottom 10px + } + + + } + } + + .el-image.upscale { + img { + height 310px + } + + .image-slot { + height 310px + } + + .el-image-viewer__wrapper { + img { + width auto + height auto + } + } + } +} \ No newline at end of file diff --git a/web/src/views/ChatPlus.vue b/web/src/views/ChatPlus.vue index 80769552..c895be3f 100644 --- a/web/src/views/ChatPlus.vue +++ b/web/src/views/ChatPlus.vue @@ -367,7 +367,6 @@ const initData = () => { inputRef.value.addEventListener('paste', (event) => { const items = (event.clipboardData || window.clipboardData).items; let fileFound = false; - loading.value = true for (let item of items) { if (item.kind === 'file') { @@ -376,6 +375,7 @@ const initData = () => { const formData = new FormData(); formData.append('file', file); + loading.value = true // 执行上传操作 httpPost('/api/upload', formData).then((res) => { files.value.push(res.data) @@ -389,7 +389,7 @@ const initData = () => { break; } } - + if (!fileFound) { document.getElementById('status').innerText = 'No file found in paste data.'; } diff --git a/web/src/views/Dalle.vue b/web/src/views/Dalle.vue index fb243a3d..e610522b 100644 --- a/web/src/views/Dalle.vue +++ b/web/src/views/Dalle.vue @@ -125,6 +125,24 @@ + + + + + 任务失败 + + + + 详情 + + + 删除 + + + + + + @@ -136,17 +154,17 @@ - + - + @@ -185,7 +203,7 @@