diff --git a/CHANGELOG.md b/CHANGELOG.md index 19ca3d92..d5c4a124 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,4 +1,12 @@ # 更新日志 +## v4.2.3 + +- 功能优化:增加模型分组与模型描述,采用卡片展示模式改进模型选择功能体验 +- 功能优化:化思维导图下载图片的清晰度以及解决拖动、缩放操作后下载图片内容不全问题 +- Bug 修复:修复MJ画图页面已画出的图,点复制指令无效问题 +- 功能优化:MJ画图的分辨率支持自定义,优先使用prompt中--ar参数 +- Bug修复:修复MJ绘画U1-V1,拼写错误 + ## v4.2.2 diff --git a/api/core/app_server.go b/api/core/app_server.go index 82472a1c..14188562 100644 --- a/api/core/app_server.go +++ b/api/core/app_server.go @@ -70,6 +70,37 @@ func (s *AppServer) Run(db *gorm.DB) error { if err != nil { return fmt.Errorf("failed to decode system config: %v", err) } + + // 迁移数据表 + logger.Info("Migrating database tables...") + db.AutoMigrate( + &model.ChatItem{}, + &model.ChatMessage{}, + &model.ChatRole{}, + &model.ChatModel{}, + &model.InviteCode{}, + &model.InviteLog{}, + &model.Menu{}, + &model.Order{}, + &model.Product{}, + &model.User{}, + &model.Function{}, + &model.File{}, + &model.Redeem{}, + &model.Config{}, + &model.ApiKey{}, + &model.AdminUser{}, + &model.AppType{}, + &model.SdJob{}, + &model.SunoJob{}, + &model.PowerLog{}, + &model.VideoJob{}, + &model.MidJourneyJob{}, + &model.UserLoginLog{}, + &model.DallJob{}, + ) + logger.Info("Database tables migrated successfully") + // 统计安装信息 go func() { info, err := host.Info() diff --git a/api/core/types/chat.go b/api/core/types/chat.go index f6ff64c7..aa8ac01f 100644 --- a/api/core/types/chat.go +++ b/api/core/types/chat.go @@ -70,6 +70,8 @@ type ChatModel struct { Power int `json:"power"` MaxTokens int `json:"max_tokens"` // 最大响应长度 MaxContext int `json:"max_context"` // 最大上下文长度 + Description string `json:"description"` //模型描述 + Category string `json:"category"` //模型类别 Temperature float32 `json:"temperature"` // 模型温度 KeyId int `json:"key_id"` // 绑定 API KEY } diff --git a/api/handler/admin/chat_app_handler.go b/api/handler/admin/chat_app_handler.go index e068c645..4bdda9d6 100644 --- a/api/handler/admin/chat_app_handler.go +++ b/api/handler/admin/chat_app_handler.go @@ -78,10 +78,10 @@ func (h *ChatAppHandler) List(c *gin.Context) { typeIds := make([]int, 0) for _, v := range items { if v.ModelId > 0 { - modelIds = append(modelIds, v.ModelId) + modelIds = append(modelIds, int(v.ModelId)) } if v.Tid > 0 { - typeIds = append(typeIds, v.Tid) + typeIds = append(typeIds, int(v.Tid)) } } diff --git a/api/handler/admin/chat_handler.go b/api/handler/admin/chat_handler.go index 675df38d..a97eacc2 100644 --- a/api/handler/admin/chat_handler.go +++ b/api/handler/admin/chat_handler.go @@ -15,6 +15,7 @@ import ( "geekai/store/vo" "geekai/utils" "geekai/utils/resp" + "github.com/gin-gonic/gin" "gorm.io/gorm" ) @@ -189,7 +190,7 @@ func (h *ChatHandler) Messages(c *gin.Context) { } for _, item := range items { list = append(list, chatMessageVo{ - Id: item.Id, + Id: uint(item.Id), UserId: item.UserId, Username: userMap[item.UserId], Content: item.Content, diff --git a/api/handler/admin/chat_model_handler.go b/api/handler/admin/chat_model_handler.go index 2c92089b..5ad9f182 100644 --- a/api/handler/admin/chat_model_handler.go +++ b/api/handler/admin/chat_model_handler.go @@ -40,6 +40,8 @@ func (h *ChatModelHandler) Save(c *gin.Context) { Power int `json:"power"` MaxTokens int `json:"max_tokens"` // 最大响应长度 MaxContext int `json:"max_context"` // 最大上下文长度 + Description string `json:"description"` //模型描述 + Category string `json:"category"` //模型类别 Temperature float32 `json:"temperature"` // 模型温度 KeyId int `json:"key_id,omitempty"` CreatedAt int64 `json:"created_at"` @@ -64,8 +66,10 @@ func (h *ChatModelHandler) Save(c *gin.Context) { item.Power = data.Power item.MaxTokens = data.MaxTokens item.MaxContext = data.MaxContext + item.Description = data.Description + item.Category = data.Category item.Temperature = data.Temperature - item.KeyId = data.KeyId + item.KeyId = uint(data.KeyId) item.Type = data.Type item.Options = utils.JsonEncode(data.Options) var res *gorm.DB @@ -113,7 +117,7 @@ func (h *ChatModelHandler) List(c *gin.Context) { // initialize key name keyIds := make([]int, 0) for _, v := range items { - keyIds = append(keyIds, v.KeyId) + keyIds = append(keyIds, int(v.KeyId)) } var keys []model.ApiKey keyMap := make(map[uint]string) diff --git a/api/handler/admin/image_handler.go b/api/handler/admin/image_handler.go index 3685042a..966192cd 100644 --- a/api/handler/admin/image_handler.go +++ b/api/handler/admin/image_handler.go @@ -18,6 +18,7 @@ import ( "geekai/store/vo" "geekai/utils" "geekai/utils/resp" + "github.com/gin-gonic/gin" "gorm.io/gorm" ) @@ -189,7 +190,7 @@ func (h *ImageHandler) Remove(c *gin.Context) { tx.Delete(&job) md = "mid-journey" power = job.Power - userId = job.UserId + userId = int(job.UserId) remark = fmt.Sprintf("任务失败,退回算力。任务ID:%d,Err: %s", job.Id, job.ErrMsg) progress = job.Progress imgURL = job.ImgURL @@ -205,7 +206,7 @@ func (h *ImageHandler) Remove(c *gin.Context) { tx.Delete(&job) md = "stable-diffusion" power = job.Power - userId = job.UserId + userId = int(job.UserId) remark = fmt.Sprintf("任务失败,退回算力。任务ID:%d,Err: %s", job.Id, job.ErrMsg) progress = job.Progress imgURL = job.ImgURL @@ -232,7 +233,7 @@ func (h *ImageHandler) Remove(c *gin.Context) { } if progress != 100 { - err := h.userService.IncreasePower(userId, power, model.PowerLog{ + err := h.userService.IncreasePower(uint(userId), power, model.PowerLog{ Type: types.PowerRefund, Model: md, Remark: remark, diff --git a/api/handler/admin/media_handler.go b/api/handler/admin/media_handler.go index 72924010..d1347038 100644 --- a/api/handler/admin/media_handler.go +++ b/api/handler/admin/media_handler.go @@ -150,7 +150,7 @@ func (h *MediaHandler) Remove(c *gin.Context) { tx.Delete(&job) md = "suno" power = job.Power - userId = job.UserId + userId = int(job.UserId) remark = fmt.Sprintf("SUNO 任务失败,退回算力。任务ID:%d,Err: %s", job.Id, job.ErrMsg) progress = job.Progress fileURL = job.AudioURL @@ -167,7 +167,7 @@ func (h *MediaHandler) Remove(c *gin.Context) { tx.Delete(&job) md = job.Type power = job.Power - userId = job.UserId + userId = int(job.UserId) remark = fmt.Sprintf("LUMA 任务失败,退回算力。任务ID:%d,Err: %s", job.Id, job.ErrMsg) progress = job.Progress fileURL = job.VideoURL @@ -181,7 +181,7 @@ func (h *MediaHandler) Remove(c *gin.Context) { } if progress != 100 { - err := h.userService.IncreasePower(userId, power, model.PowerLog{ + err := h.userService.IncreasePower(uint(userId), power, model.PowerLog{ Type: types.PowerRefund, Model: md, Remark: remark, diff --git a/api/handler/admin/upload_handler.go b/api/handler/admin/upload_handler.go index 76719c34..0f959eba 100644 --- a/api/handler/admin/upload_handler.go +++ b/api/handler/admin/upload_handler.go @@ -49,7 +49,7 @@ func (h *UploadHandler) Upload(c *gin.Context) { userId := 0 res := h.DB.Create(&model.File{ - UserId: userId, + UserId: uint(userId), Name: file.Name, ObjKey: file.ObjKey, URL: file.URL, diff --git a/api/handler/chat_handler.go b/api/handler/chat_handler.go index 7405f9d3..fc7172c7 100644 --- a/api/handler/chat_handler.go +++ b/api/handler/chat_handler.go @@ -387,7 +387,7 @@ func (h *ChatHandler) subUserPower(userVo vo.User, session *types.ChatSession, p power = session.Model.Power } - err := h.userService.DecreasePower(int(userVo.Id), power, model.PowerLog{ + err := h.userService.DecreasePower(userVo.Id, power, model.PowerLog{ Type: types.PowerConsume, Model: session.Model.Value, Remark: fmt.Sprintf("模型名称:%s, 提问长度:%d,回复长度:%d", session.Model.Name, promptTokens, replyTokens), diff --git a/api/handler/chat_role_handler.go b/api/handler/chat_role_handler.go index aa579a51..f2e78d1f 100644 --- a/api/handler/chat_role_handler.go +++ b/api/handler/chat_role_handler.go @@ -64,10 +64,12 @@ func (h *ChatRoleHandler) ListByUser(c *gin.Context) { var user model.User h.DB.First(&user, userId) var roleKeys []string - err := utils.JsonDecode(user.ChatRoles, &roleKeys) - if err != nil { - resp.ERROR(c, "角色解析失败!") - return + if user.ChatRoles != "" { + err := utils.JsonDecode(user.ChatRoles, &roleKeys) + if err != nil { + resp.ERROR(c, "角色解析失败!") + return + } } // 保证用户至少有一个角色可用 if len(roleKeys) > 0 { diff --git a/api/handler/dalle_handler.go b/api/handler/dalle_handler.go index 2333e5fa..256bd07a 100644 --- a/api/handler/dalle_handler.go +++ b/api/handler/dalle_handler.go @@ -96,7 +96,7 @@ func (h *DallJobHandler) Image(c *gin.Context) { h.dallService.PushTask(task) // 扣减算力 - err = h.userService.DecreasePower(int(user.Id), chatModel.Power, model.PowerLog{ + err = h.userService.DecreasePower(user.Id, chatModel.Power, model.PowerLog{ Type: types.PowerConsume, Model: chatModel.Value, Remark: fmt.Sprintf("绘画提示词:%s", utils.CutWords(task.Prompt, 10)), diff --git a/api/handler/function_handler.go b/api/handler/function_handler.go index 8902cb50..9cf59a8a 100644 --- a/api/handler/function_handler.go +++ b/api/handler/function_handler.go @@ -240,7 +240,7 @@ func (h *FunctionHandler) Dall3(c *gin.Context) { } // 扣减算力 - err = h.userService.DecreasePower(int(user.Id), job.Power, model.PowerLog{ + err = h.userService.DecreasePower(user.Id, job.Power, model.PowerLog{ Type: types.PowerConsume, Model: task.ModelName, Remark: fmt.Sprintf("绘画提示词:%s", utils.CutWords(job.Prompt, 10)), @@ -309,7 +309,7 @@ func (h *FunctionHandler) WebSearch(c *gin.Context) { } // 扣减用户算力 - err = h.userService.DecreasePower(int(user.Id), searchPower, model.PowerLog{ + err = h.userService.DecreasePower(user.Id, searchPower, model.PowerLog{ Type: types.PowerConsume, Model: "web_search", Remark: fmt.Sprintf("网络搜索:%s", utils.CutWords(keyword, 10)), diff --git a/api/handler/markmap_handler.go b/api/handler/markmap_handler.go index 3d7a7b14..85b2147f 100644 --- a/api/handler/markmap_handler.go +++ b/api/handler/markmap_handler.go @@ -15,6 +15,7 @@ import ( "geekai/store/model" "geekai/utils" "geekai/utils/resp" + "github.com/gin-gonic/gin" "gorm.io/gorm" ) @@ -95,7 +96,7 @@ func (h *MarkMapHandler) Generate(c *gin.Context) { // 扣减算力 if chatModel.Power > 0 { - err = h.userService.DecreasePower(int(userId), chatModel.Power, model.PowerLog{ + err = h.userService.DecreasePower(userId, chatModel.Power, model.PowerLog{ Type: types.PowerConsume, Model: chatModel.Value, Remark: fmt.Sprintf("AI绘制思维导图,模型名称:%s, ", chatModel.Value), diff --git a/api/handler/mj_handler.go b/api/handler/mj_handler.go index 3c56e902..b1f9fe96 100644 --- a/api/handler/mj_handler.go +++ b/api/handler/mj_handler.go @@ -164,7 +164,7 @@ func (h *MidJourneyHandler) Image(c *gin.Context) { } job := model.MidJourneyJob{ Type: data.TaskType, - UserId: userId, + UserId: uint(userId), TaskId: taskId, TaskInfo: utils.JsonEncode(task), Progress: 0, @@ -236,7 +236,7 @@ func (h *MidJourneyHandler) Upscale(c *gin.Context) { } job := model.MidJourneyJob{ Type: types.TaskUpscale.String(), - UserId: userId, + UserId: uint(userId), TaskId: taskId, TaskInfo: utils.JsonEncode(task), Progress: 0, @@ -292,7 +292,7 @@ func (h *MidJourneyHandler) Variation(c *gin.Context) { job := model.MidJourneyJob{ Type: types.TaskVariation.String(), ChannelId: data.ChannelId, - UserId: userId, + UserId: uint(userId), TaskId: taskId, TaskInfo: utils.JsonEncode(task), Progress: 0, @@ -422,7 +422,7 @@ func (h *MidJourneyHandler) Publish(c *gin.Context) { id := h.GetInt(c, "id", 0) userId := h.GetInt(c, "user_id", 0) action := h.GetBool(c, "action") // 发布动作,true => 发布,false => 取消分享 - err := h.DB.Model(&model.MidJourneyJob{Id: uint(id), UserId: userId}).UpdateColumn("publish", action).Error + err := h.DB.Model(&model.MidJourneyJob{Id: uint(id), UserId: uint(userId)}).UpdateColumn("publish", action).Error if err != nil { resp.ERROR(c, err.Error()) return diff --git a/api/handler/net_handler.go b/api/handler/net_handler.go index 2020b873..8602bba3 100644 --- a/api/handler/net_handler.go +++ b/api/handler/net_handler.go @@ -15,11 +15,12 @@ import ( "geekai/store/vo" "geekai/utils" "geekai/utils/resp" - "github.com/gin-gonic/gin" - "gorm.io/gorm" "io" "net/http" "time" + + "github.com/gin-gonic/gin" + "gorm.io/gorm" ) type NetHandler struct { @@ -46,7 +47,7 @@ func (h *NetHandler) Upload(c *gin.Context) { userId := h.GetLoginUserId(c) res := h.DB.Create(&model.File{ - UserId: int(userId), + UserId: uint(userId), Name: file.Name, ObjKey: file.ObjKey, URL: file.URL, diff --git a/api/handler/payment_handler.go b/api/handler/payment_handler.go index ef450c5e..686351d9 100644 --- a/api/handler/payment_handler.go +++ b/api/handler/payment_handler.go @@ -289,7 +289,7 @@ func (h *PaymentHandler) notify(orderNo string, tradeNo string) error { } // 增加用户算力 - err = h.userService.IncreasePower(int(order.UserId), remark.Power, model.PowerLog{ + err = h.userService.IncreasePower(order.UserId, remark.Power, model.PowerLog{ Type: types.PowerRecharge, Model: order.PayWay, Remark: fmt.Sprintf("充值算力,金额:%f,订单号:%s", order.Amount, order.OrderNo), diff --git a/api/handler/prompt_handler.go b/api/handler/prompt_handler.go index 7c062ffe..31fecc9a 100644 --- a/api/handler/prompt_handler.go +++ b/api/handler/prompt_handler.go @@ -56,7 +56,7 @@ func (h *PromptHandler) Lyric(c *gin.Context) { if h.App.SysConfig.PromptPower > 0 { userId := h.GetLoginUserId(c) - err = h.userService.DecreasePower(int(userId), h.App.SysConfig.PromptPower, model.PowerLog{ + err = h.userService.DecreasePower(userId, h.App.SysConfig.PromptPower, model.PowerLog{ Type: types.PowerConsume, Model: h.getPromptModel(), Remark: "生成歌词", @@ -86,7 +86,7 @@ func (h *PromptHandler) Image(c *gin.Context) { } if h.App.SysConfig.PromptPower > 0 { userId := h.GetLoginUserId(c) - err = h.userService.DecreasePower(int(userId), h.App.SysConfig.PromptPower, model.PowerLog{ + err = h.userService.DecreasePower(userId, h.App.SysConfig.PromptPower, model.PowerLog{ Type: types.PowerConsume, Model: h.getPromptModel(), Remark: "生成绘画提示词", @@ -116,7 +116,7 @@ func (h *PromptHandler) Video(c *gin.Context) { if h.App.SysConfig.PromptPower > 0 { userId := h.GetLoginUserId(c) - err = h.userService.DecreasePower(int(userId), h.App.SysConfig.PromptPower, model.PowerLog{ + err = h.userService.DecreasePower(userId, h.App.SysConfig.PromptPower, model.PowerLog{ Type: types.PowerConsume, Model: h.getPromptModel(), Remark: "生成视频脚本", diff --git a/api/handler/realtime_handler.go b/api/handler/realtime_handler.go index 4a5789c1..5880260e 100644 --- a/api/handler/realtime_handler.go +++ b/api/handler/realtime_handler.go @@ -198,7 +198,7 @@ func (h *RealtimeHandler) VoiceChat(c *gin.Context) { h.DB.Model(&apiKey).UpdateColumn("last_used_at", time.Now().Unix()) // 扣减算力 - err = h.userService.DecreasePower(int(userId), h.App.SysConfig.AdvanceVoicePower, model.PowerLog{ + err = h.userService.DecreasePower(userId, h.App.SysConfig.AdvanceVoicePower, model.PowerLog{ Type: types.PowerConsume, Model: "advanced-voice", Remark: "实时语音通话", diff --git a/api/handler/redeem_handler.go b/api/handler/redeem_handler.go index b6759ffd..706ac010 100644 --- a/api/handler/redeem_handler.go +++ b/api/handler/redeem_handler.go @@ -61,7 +61,7 @@ func (h *RedeemHandler) Verify(c *gin.Context) { } tx := h.DB.Begin() - err := h.userService.IncreasePower(int(userId), item.Power, model.PowerLog{ + err := h.userService.IncreasePower(userId, item.Power, model.PowerLog{ Type: types.PowerRedeem, Model: "兑换码", Remark: fmt.Sprintf("兑换码核销,算力:%d,兑换码:%s...", item.Power, item.Code[:10]), diff --git a/api/handler/sd_handler.go b/api/handler/sd_handler.go index 6801a3b3..c8358d08 100644 --- a/api/handler/sd_handler.go +++ b/api/handler/sd_handler.go @@ -135,7 +135,7 @@ func (h *SdJobHandler) Image(c *gin.Context) { } job := model.SdJob{ - UserId: userId, + UserId: uint(userId), Type: types.TaskImage.String(), TaskId: taskId, Params: utils.JsonEncode(task.Params), @@ -273,7 +273,7 @@ func (h *SdJobHandler) Publish(c *gin.Context) { userId := h.GetLoginUserId(c) action := h.GetBool(c, "action") // 发布动作,true => 发布,false => 取消分享 - err := h.DB.Model(&model.SdJob{Id: uint(id), UserId: int(userId)}).UpdateColumn("publish", action).Error + err := h.DB.Model(&model.SdJob{Id: uint(id), UserId: uint(userId)}).UpdateColumn("publish", action).Error if err != nil { resp.ERROR(c, err.Error()) return diff --git a/api/handler/suno_handler.go b/api/handler/suno_handler.go index 53ee507d..274986fd 100644 --- a/api/handler/suno_handler.go +++ b/api/handler/suno_handler.go @@ -107,7 +107,7 @@ func (h *SunoHandler) Create(c *gin.Context) { // 插入数据库 job := model.SunoJob{ - UserId: task.UserId, + UserId: uint(task.UserId), Prompt: data.Prompt, Instrumental: data.Instrumental, ModelName: data.Model, diff --git a/api/handler/user_handler.go b/api/handler/user_handler.go index 070345d0..dee60047 100644 --- a/api/handler/user_handler.go +++ b/api/handler/user_handler.go @@ -187,7 +187,7 @@ func (h *UserHandler) Register(c *gin.Context) { // 增加邀请数量 h.DB.Model(&model.InviteCode{}).Where("code = ?", data.InviteCode).UpdateColumn("reg_num", gorm.Expr("reg_num + ?", 1)) if h.App.SysConfig.InvitePower > 0 { - err := h.userService.IncreasePower(int(inviteCode.UserId), h.App.SysConfig.InvitePower, model.PowerLog{ + err := h.userService.IncreasePower(inviteCode.UserId, h.App.SysConfig.InvitePower, model.PowerLog{ Type: types.PowerInvite, Model: "Invite", Remark: fmt.Sprintf("邀请用户注册奖励,金额:%d,邀请码:%s,新用户:%s", h.App.SysConfig.InvitePower, inviteCode.Code, user.Username), @@ -736,7 +736,7 @@ func (h *UserHandler) SignIn(c *gin.Context) { // 签到 h.levelDB.Put(key, true) if h.App.SysConfig.DailyPower > 0 { - h.userService.IncreasePower(int(userId), h.App.SysConfig.DailyPower, model.PowerLog{ + h.userService.IncreasePower(userId, h.App.SysConfig.DailyPower, model.PowerLog{ Type: types.PowerSignIn, Model: "SignIn", Remark: fmt.Sprintf("每日签到奖励,金额:%d", h.App.SysConfig.DailyPower), diff --git a/api/handler/video_handler.go b/api/handler/video_handler.go index 3a8d43cd..a3aff209 100644 --- a/api/handler/video_handler.go +++ b/api/handler/video_handler.go @@ -89,7 +89,7 @@ func (h *VideoHandler) LumaCreate(c *gin.Context) { } // 插入数据库 job := model.VideoJob{ - UserId: userId, + UserId: uint(userId), Type: types.VideoLuma, Prompt: data.Prompt, Power: h.App.SysConfig.LumaPower, @@ -186,7 +186,7 @@ func (h *VideoHandler) KeLingCreate(c *gin.Context) { } // 插入数据库 job := model.VideoJob{ - UserId: userId, + UserId: uint(userId), Type: types.VideoKeLing, Prompt: data.Prompt, Power: power, diff --git a/api/handler/ws_handler.go b/api/handler/ws_handler.go index 95fe87bb..77e9636e 100644 --- a/api/handler/ws_handler.go +++ b/api/handler/ws_handler.go @@ -14,11 +14,12 @@ import ( "geekai/service" "geekai/store/model" "geekai/utils" + "net/http" + "strings" + "github.com/gin-gonic/gin" "github.com/gorilla/websocket" "gorm.io/gorm" - "net/http" - "strings" ) // Websocket 连接处理 handler @@ -103,7 +104,7 @@ func (h *WebsocketHandler) Client(c *gin.Context) { } // if the role bind a model_id, use role's bind model_id if chatRole.ModelId > 0 { - chatMessage.RoleId = chatRole.ModelId + chatMessage.RoleId = int(chatRole.ModelId) } // get model info var chatModel model.ChatModel diff --git a/api/service/dalle/service.go b/api/service/dalle/service.go index ba716bdc..a38cde36 100644 --- a/api/service/dalle/service.go +++ b/api/service/dalle/service.go @@ -246,7 +246,7 @@ func (s *Service) CheckTaskStatus() { if err != nil { continue } - err = s.userService.IncreasePower(int(job.UserId), job.Power, model.PowerLog{ + err = s.userService.IncreasePower(job.UserId, job.Power, model.PowerLog{ Type: types.PowerRefund, Model: task.ModelName, Remark: fmt.Sprintf("任务失败,退回算力。任务ID:%d,Err: %s", job.Id, job.ErrMsg), diff --git a/api/service/user_service.go b/api/service/user_service.go index ea086d01..50018ea5 100644 --- a/api/service/user_service.go +++ b/api/service/user_service.go @@ -4,9 +4,10 @@ import ( "fmt" "geekai/core/types" "geekai/store/model" - "gorm.io/gorm" "sync" "time" + + "gorm.io/gorm" ) type UserService struct { @@ -19,7 +20,7 @@ func NewUserService(db *gorm.DB) *UserService { } // IncreasePower 增加用户算力 -func (s *UserService) IncreasePower(userId int, power int, log model.PowerLog) error { +func (s *UserService) IncreasePower(userId uint, power int, log model.PowerLog) error { s.lock.Lock() defer s.lock.Unlock() @@ -51,7 +52,7 @@ func (s *UserService) IncreasePower(userId int, power int, log model.PowerLog) e } // DecreasePower 减少用户算力 -func (s *UserService) DecreasePower(userId int, power int, log model.PowerLog) error { +func (s *UserService) DecreasePower(userId uint, power int, log model.PowerLog) error { s.lock.Lock() defer s.lock.Unlock() diff --git a/api/service/xxl_job_service.go b/api/service/xxl_job_service.go index ef701730..6fae6fad 100644 --- a/api/service/xxl_job_service.go +++ b/api/service/xxl_job_service.go @@ -9,14 +9,11 @@ package service import ( "context" - "fmt" "geekai/core/types" logger2 "geekai/logger" - "geekai/store/model" - "geekai/utils" + "github.com/xxl-job/xxl-job-executor-go" "gorm.io/gorm" - "time" ) var logger = logger2.GetLogger() @@ -46,97 +43,13 @@ func NewXXLJobExecutor(config *types.AppConfig, db *gorm.DB) *XXLJobExecutor { func (e *XXLJobExecutor) Run() error { e.executor.RegTask("ClearOrders", e.ClearOrders) - e.executor.RegTask("ResetVipPower", e.ResetVipPower) - e.executor.RegTask("ResetUserPower", e.ResetUserPower) return e.executor.Run() } // ClearOrders 清理未支付的订单,如果没有抛出异常则表示执行成功 func (e *XXLJobExecutor) ClearOrders(cxt context.Context, param *xxl.RunReq) (msg string) { logger.Info("执行清理未支付订单...") - var sysConfig model.Config - res := e.db.Where("marker", "system").First(&sysConfig) - if res.Error != nil { - return "error with get system config: " + res.Error.Error() - } - - var config types.SystemConfig - err := utils.JsonDecode(sysConfig.Config, &config) - if err != nil { - return "error with decode system config: " + err.Error() - } - - if config.OrderPayTimeout == 0 { // 默认未支付订单的生命周期为 30 分钟 - config.OrderPayTimeout = 1800 - } - timeout := time.Now().Unix() - int64(config.OrderPayTimeout) - start := utils.Stamp2str(timeout) - // 这里不是用软删除,而是永久删除订单 - res = e.db.Unscoped().Where("status IN ? AND created_at < ?", []types.OrderStatus{types.OrderNotPaid, types.OrderScanned}, start).Delete(&model.Order{}) - logger.Infof("Clear order successfully, affect rows: %d", res.RowsAffected) - return "success" -} - -// ResetVipPower 重置VIP会员算力 -// 自动将 VIP 会员的算力补充到每月赠送的最大值 -func (e *XXLJobExecutor) ResetVipPower(cxt context.Context, param *xxl.RunReq) (msg string) { - logger.Info("开始进行月底账号盘点...") - return "success" -} - -func (e *XXLJobExecutor) ResetUserPower(cxt context.Context, param *xxl.RunReq) (msg string) { - logger.Info("今日算力派发开始:", time.Now()) - var users []model.User - res := e.db.Where("status", 1).Find(&users) - if res.Error != nil { - return "No matching users" - } - - var sysConfig model.Config - res = e.db.Where("marker", "system").First(&sysConfig) - if res.Error != nil { - return "error with get system config: " + res.Error.Error() - } - - var config types.SystemConfig - err := utils.JsonDecode(sysConfig.Config, &config) - if err != nil { - return "error with decode system config: " + err.Error() - } - - if config.DailyPower <= 0 { - return "success" - } - - var counter = 0 - var totalPower = 0 - for _, u := range users { - if u.Power >= config.DailyPower { - continue - } - var power = config.DailyPower - u.Power - // update user - tx := e.db.Model(&model.User{}).Where("id", u.Id).UpdateColumn("power", gorm.Expr("power + ?", power)) - // 记录算力充值日志 - if tx.Error == nil { - var user model.User - e.db.Where("id", u.Id).First(&user) - e.db.Create(&model.PowerLog{ - UserId: u.Id, - Username: u.Username, - Type: types.PowerGift, - Amount: power, - Mark: types.PowerAdd, - Balance: user.Power, - Model: "系统赠送", - Remark: fmt.Sprintf("系统每日算力派发,今日额度:%d", config.DailyPower), - CreatedAt: time.Now(), - }) - } - counter++ - totalPower += power - } - logger.Infof("今日派发算力结束!累计派发 %d 人,累计派发算力:%d", counter, totalPower) + return "success" } diff --git a/api/store/model/admin_user.go b/api/store/model/admin_user.go index ffeccd17..066f0462 100644 --- a/api/store/model/admin_user.go +++ b/api/store/model/admin_user.go @@ -1,11 +1,22 @@ package model +import ( + "time" +) + type AdminUser struct { - BaseModel - Username string - Password string - Salt string // 密码盐 - Status bool `gorm:"default:true"` // 当前状态 - LastLoginAt int64 // 最后登录时间 - LastLoginIp string // 最后登录 IP + Id uint `gorm:"column:id;primaryKey;autoIncrement" json:"id"` + Username string `gorm:"column:username;type:varchar(30);uniqueIndex;not null;comment:用户名" json:"username"` + Password string `gorm:"column:password;type:char(64);not null;comment:密码" json:"password"` + Salt string `gorm:"column:salt;type:char(12);not null;comment:密码盐" json:"salt"` + Status bool `gorm:"column:status;type:tinyint(1);not null;comment:当前状态" json:"status"` + LastLoginAt int64 `gorm:"column:last_login_at;type:int;not null;comment:最后登录时间" json:"last_login_at"` + LastLoginIp string `gorm:"column:last_login_ip;type:char(16);not null;comment:最后登录 IP" json:"last_login_ip"` + CreatedAt time.Time `gorm:"column:created_at;type:datetime;not null;comment:创建时间" json:"created_at"` + UpdatedAt time.Time `gorm:"column:updated_at;type:datetime;not null;comment:更新时间" json:"updated_at"` +} + +// TableName 表名 +func (m *AdminUser) TableName() string { + return "chatgpt_admin_users" } diff --git a/api/store/model/api_key.go b/api/store/model/api_key.go index c32ff9bd..e020435f 100644 --- a/api/store/model/api_key.go +++ b/api/store/model/api_key.go @@ -1,13 +1,24 @@ package model +import ( + "time" +) + // ApiKey OpenAI API 模型 type ApiKey struct { - BaseModel - Name string - Type string // 用途 chat => 聊天,img => 绘图 - Value string // API Key 的值 - ApiURL string // 当前 KEY 的 API 地址 - Enabled bool // 是否启用 - ProxyURL string // 代理地址 - LastUsedAt int64 // 最后使用时间 + Id uint `gorm:"column:id;primaryKey;autoIncrement" json:"id"` + Name string `gorm:"column:name;type:varchar(30);comment:名称" json:"name"` + Value string `gorm:"column:value;type:varchar(255);not null;comment:API KEY value" json:"value"` + Type string `gorm:"column:type;type:varchar(10);default:chat;not null;comment:用途(chat=>聊天,img=>图片)" json:"type"` + LastUsedAt int64 `gorm:"column:last_used_at;type:int;not null;comment:最后使用时间" json:"last_used_at"` + ApiURL string `gorm:"column:api_url;type:varchar(255);comment:API 地址" json:"api_url"` + Enabled bool `gorm:"column:enabled;type:tinyint(1);comment:是否启用" json:"enabled"` + ProxyURL string `gorm:"column:proxy_url;type:varchar(100);comment:代理地址" json:"proxy_url"` + CreatedAt time.Time `gorm:"column:created_at;type:datetime;not null" json:"created_at"` + UpdatedAt time.Time `gorm:"column:updated_at;type:datetime;not null" json:"updated_at"` +} + +// TableName 表名 +func (m *ApiKey) TableName() string { + return "chatgpt_api_keys" } diff --git a/api/store/model/app_type.go b/api/store/model/app_type.go index ee1aceed..c7db9813 100644 --- a/api/store/model/app_type.go +++ b/api/store/model/app_type.go @@ -3,10 +3,15 @@ package model import "time" type AppType struct { - Id uint `gorm:"primarykey"` - Name string - Icon string - Enabled bool - SortNum int - CreatedAt time.Time + Id uint `gorm:"column:id;primaryKey;autoIncrement" json:"id"` + Name string `gorm:"column:name;type:varchar(50);not null;comment:名称" json:"name"` + Icon string `gorm:"column:icon;type:varchar(255);not null;comment:图标URL" json:"icon"` + SortNum int `gorm:"column:sort_num;type:tinyint;not null;comment:排序" json:"sort_num"` + Enabled bool `gorm:"column:enabled;type:tinyint(1);not null;comment:是否启用" json:"enabled"` + CreatedAt time.Time `gorm:"column:created_at;type:datetime;not null" json:"created_at"` +} + +// TableName 表名 +func (m *AppType) TableName() string { + return "chatgpt_app_types" } diff --git a/api/store/model/base.go b/api/store/model/base.go deleted file mode 100644 index 5246b4d0..00000000 --- a/api/store/model/base.go +++ /dev/null @@ -1,9 +0,0 @@ -package model - -import "time" - -type BaseModel struct { - Id uint `gorm:"primarykey;column:id"` - CreatedAt time.Time - UpdatedAt time.Time -} diff --git a/api/store/model/chat_history.go b/api/store/model/chat_history.go index 876c427f..393b99c9 100644 --- a/api/store/model/chat_history.go +++ b/api/store/model/chat_history.go @@ -1,22 +1,25 @@ package model -import "gorm.io/gorm" +import ( + "time" +) type ChatMessage struct { - BaseModel - ChatId string // 会话 ID - UserId uint // 用户 ID - RoleId uint // 角色 ID - Model string // AI模型 - Type string - Icon string - Tokens int - TotalTokens int // 总 token 消耗 - Content string - UseContext bool // 是否可以作为聊天上下文 - DeletedAt gorm.DeletedAt + Id int64 `gorm:"column:id;primaryKey;autoIncrement" json:"id"` + UserId uint `gorm:"column:user_id;type:int;not null;comment:用户 ID" json:"user_id"` + ChatId string `gorm:"column:chat_id;type:char(40);not null;index;comment:会话 ID" json:"chat_id"` + Type string `gorm:"column:type;type:varchar(10);not null;comment:类型:prompt|reply" json:"type"` + Icon string `gorm:"column:icon;type:varchar(255);not null;comment:角色图标" json:"icon"` + RoleId uint `gorm:"column:role_id;type:int;not null;comment:角色 ID" json:"role_id"` + Model string `gorm:"column:model;type:varchar(30);comment:模型名称" json:"model"` + Content string `gorm:"column:content;type:text;not null;comment:聊天内容" json:"content"` + Tokens int `gorm:"column:tokens;type:smallint;not null;comment:耗费 token 数量" json:"tokens"` + TotalTokens int `gorm:"column:total_tokens;type:int;not null;comment:消耗总Token长度" json:"total_tokens"` + UseContext bool `gorm:"column:use_context;type:tinyint(1);not null;comment:是否允许作为上下文语料" json:"use_context"` + CreatedAt time.Time `gorm:"column:created_at;type:datetime;not null" json:"created_at"` + UpdatedAt time.Time `gorm:"column:updated_at;type:datetime;not null" json:"updated_at"` } -func (ChatMessage) TableName() string { +func (m *ChatMessage) TableName() string { return "chatgpt_chat_history" } diff --git a/api/store/model/chat_item.go b/api/store/model/chat_item.go index 80b45901..6e75a41e 100644 --- a/api/store/model/chat_item.go +++ b/api/store/model/chat_item.go @@ -1,14 +1,21 @@ package model -import "gorm.io/gorm" +import ( + "time" +) type ChatItem struct { - BaseModel - ChatId string `gorm:"column:chat_id;unique"` // 会话 ID - UserId uint // 用户 ID - RoleId uint // 角色 ID - ModelId uint // 模型 ID - Model string // 模型 - Title string // 会话标题 - DeletedAt gorm.DeletedAt + Id uint `gorm:"column:id;primaryKey;autoIncrement" json:"id"` + ChatId string `gorm:"column:chat_id;type:char(40);uniqueIndex;not null;comment:会话 ID" json:"chat_id"` + UserId uint `gorm:"column:user_id;type:int;not null;comment:用户 ID" json:"user_id"` + RoleId uint `gorm:"column:role_id;type:int;not null;comment:角色 ID" json:"role_id"` + Title string `gorm:"column:title;type:varchar(100);not null;comment:会话标题" json:"title"` + ModelId uint `gorm:"column:model_id;type:int;not null;default:0;comment:模型 ID" json:"model_id"` + Model string `gorm:"column:model;type:varchar(30);comment:模型名称" json:"model"` + CreatedAt time.Time `gorm:"column:created_at;type:datetime;not null;comment:创建时间" json:"created_at"` + UpdatedAt time.Time `gorm:"column:updated_at;type:datetime;not null;comment:更新时间" json:"updated_at"` +} + +func (m *ChatItem) TableName() string { + return "chatgpt_chat_items" } diff --git a/api/store/model/chat_model.go b/api/store/model/chat_model.go index 20c8c87b..b753c347 100644 --- a/api/store/model/chat_model.go +++ b/api/store/model/chat_model.go @@ -1,17 +1,29 @@ package model +import ( + "time" +) + type ChatModel struct { - BaseModel - Name string - Value string // API Key 的值 - SortNum int - Enabled bool - Power int // 每次对话消耗算力 - Open bool // 是否开放模型给所有人使用 - MaxTokens int // 最大响应长度 - MaxContext int // 最大上下文长度 - Temperature float32 // 模型温度 - KeyId int // 绑定 API KEY ID - Type string // 模型类型 - Options string // 模型选项 + Id uint `gorm:"column:id;primaryKey;autoIncrement" json:"id"` + Description string `gorm:"column:description;type:varchar(1024);not null;default:'';comment:模型类型描述" json:"description"` + Category string `gorm:"column:category;type:varchar(1024);not null;default:'';comment:模型类别" json:"category"` + Type string `gorm:"column:type;type:varchar(10);not null;default:chat;comment:模型类型(chat,img)" json:"type"` + Name string `gorm:"column:name;type:varchar(255);not null;comment:模型名称" json:"name"` + Value string `gorm:"column:value;type:varchar(255);not null;comment:模型值" json:"value"` + SortNum int `gorm:"column:sort_num;type:tinyint(1);not null;comment:排序数字" json:"sort_num"` + Enabled bool `gorm:"column:enabled;type:tinyint(1);not null;default:0;comment:是否启用模型" json:"enabled"` + Power int `gorm:"column:power;type:smallint;not null;comment:消耗算力点数" json:"power"` + Temperature float32 `gorm:"column:temperature;type:float(3,1);not null;default:1.0;comment:模型创意度" json:"temperature"` + MaxTokens int `gorm:"column:max_tokens;type:int;not null;default:1024;comment:最大响应长度" json:"max_tokens"` + MaxContext int `gorm:"column:max_context;type:int;not null;default:4096;comment:最大上下文长度" json:"max_context"` + Open bool `gorm:"column:open;type:tinyint(1);not null;comment:是否开放模型" json:"open"` + KeyId uint `gorm:"column:key_id;type:int;not null;comment:绑定API KEY ID" json:"key_id"` + Options string `gorm:"column:options;type:text;not null;comment:模型自定义选项" json:"options"` + CreatedAt time.Time `gorm:"column:created_at;type:datetime" json:"created_at"` + UpdatedAt time.Time `gorm:"column:updated_at;type:datetime" json:"updated_at"` +} + +func (m *ChatModel) TableName() string { + return "chatgpt_chat_models" } diff --git a/api/store/model/chat_role.go b/api/store/model/chat_role.go index 95dfbce6..f2234f83 100644 --- a/api/store/model/chat_role.go +++ b/api/store/model/chat_role.go @@ -1,14 +1,24 @@ package model +import ( + "time" +) + type ChatRole struct { - BaseModel - Tid int - Key string `gorm:"column:marker;unique"` // 角色唯一标识 - Name string // 角色名称 - Context string `gorm:"column:context_json"` // 角色语料信息 json - HelloMsg string // 打招呼的消息 - Icon string // 角色聊天图标 - Enable bool // 是否启用被启用 - SortNum int //排序数字 - ModelId int // 绑定模型ID,绑定模型ID的角色只能用指定的模型来问答 + Id uint `gorm:"column:id;primaryKey;autoIncrement" json:"id"` + Name string `gorm:"column:name;type:varchar(30);not null;comment:角色名称" json:"name"` + Tid uint `gorm:"column:tid;type:int;not null;comment:分类ID" json:"tid"` + Marker string `gorm:"column:marker;type:varchar(30);uniqueIndex;not null;comment:角色标识" json:"marker"` + Context string `gorm:"column:context_json;type:text;not null;comment:角色语料 json" json:"context_json"` + HelloMsg string `gorm:"column:hello_msg;type:varchar(255);not null;comment:打招呼信息" json:"hello_msg"` + Icon string `gorm:"column:icon;type:varchar(255);not null;comment:角色图标" json:"icon"` + Enable bool `gorm:"column:enable;type:tinyint(1);not null;comment:是否被启用" json:"enable"` + SortNum int `gorm:"column:sort_num;type:smallint;not null;default:0;comment:角色排序" json:"sort_num"` + ModelId uint `gorm:"column:model_id;type:int;not null;default:0;comment:绑定模型ID" json:"model_id"` + CreatedAt time.Time `gorm:"column:created_at;type:datetime;not null" json:"created_at"` + UpdatedAt time.Time `gorm:"column:updated_at;type:datetime;not null" json:"updated_at"` +} + +func (m *ChatRole) TableName() string { + return "chatgpt_chat_roles" } diff --git a/api/store/model/config.go b/api/store/model/config.go index 3b43cbee..09ae709a 100644 --- a/api/store/model/config.go +++ b/api/store/model/config.go @@ -1,7 +1,11 @@ package model type Config struct { - Id uint `gorm:"primarykey;column:id"` - Key string `gorm:"column:marker;unique"` - Config string `gorm:"column:config_json"` + Id uint `gorm:"column:id;primaryKey;autoIncrement" json:"id"` + Key string `gorm:"column:marker;type:varchar(20);uniqueIndex;not null;comment:标识" json:"marker"` + Config string `gorm:"column:config_json;type:text;not null" json:"config_json"` +} + +func (m *Config) TableName() string { + return "chatgpt_configs" } diff --git a/api/store/model/dalle_job.go b/api/store/model/dalle_job.go index f22f7426..893832f8 100644 --- a/api/store/model/dalle_job.go +++ b/api/store/model/dalle_job.go @@ -3,15 +3,19 @@ package model import "time" type DallJob struct { - Id uint `gorm:"primarykey;column:id"` - UserId uint - Prompt string - TaskInfo string // 原始任务信息 - ImgURL string - OrgURL string - Publish bool - Power int - Progress int - ErrMsg string - CreatedAt time.Time + Id uint `gorm:"column:id;primaryKey;autoIncrement" json:"id"` + UserId uint `gorm:"column:user_id;type:int;not null;comment:用户ID" json:"user_id"` + Prompt string `gorm:"column:prompt;type:text;not null;comment:提示词" json:"prompt"` + TaskInfo string `gorm:"column:task_info;type:text;not null;comment:任务详情" json:"task_info"` + ImgURL string `gorm:"column:img_url;type:varchar(255);not null;comment:图片地址" json:"img_url"` + OrgURL string `gorm:"column:org_url;type:varchar(1024);comment:原图地址" json:"org_url"` + Publish int `gorm:"column:publish;type:tinyint(1);not null;comment:是否发布" json:"publish"` + Power int `gorm:"column:power;type:smallint;not null;comment:消耗算力" json:"power"` + Progress int `gorm:"column:progress;type:smallint;not null;comment:任务进度" json:"progress"` + ErrMsg string `gorm:"column:err_msg;type:varchar(1024);not null;comment:错误信息" json:"err_msg"` + CreatedAt time.Time `gorm:"column:created_at;type:datetime;not null" json:"created_at"` +} + +func (m *DallJob) TableName() string { + return "chatgpt_dall_jobs" } diff --git a/api/store/model/file.go b/api/store/model/file.go index 56fe424d..4e529d9c 100644 --- a/api/store/model/file.go +++ b/api/store/model/file.go @@ -3,12 +3,16 @@ package model import "time" type File struct { - Id uint `gorm:"primarykey;column:id"` - UserId int - Name string - ObjKey string - URL string - Ext string - Size int64 - CreatedAt time.Time + Id uint `gorm:"column:id;primaryKey;autoIncrement" json:"id"` + UserId uint `gorm:"column:user_id;type:int;not null;comment:用户 ID" json:"user_id"` + Name string `gorm:"column:name;type:varchar(255);not null;comment:文件名" json:"name"` + ObjKey string `gorm:"column:obj_key;type:varchar(100);comment:文件标识" json:"obj_key"` + URL string `gorm:"column:url;type:varchar(255);not null;comment:文件地址" json:"url"` + Ext string `gorm:"column:ext;type:varchar(10);not null;comment:文件后缀" json:"ext"` + Size int64 `gorm:"column:size;type:bigint;not null;default:0;comment:文件大小" json:"size"` + CreatedAt time.Time `gorm:"column:created_at;type:datetime;not null;comment:创建时间" json:"created_at"` +} + +func (m *File) TableName() string { + return "chatgpt_files" } diff --git a/api/store/model/function.go b/api/store/model/function.go index 2a8b80fb..cb7b18a7 100644 --- a/api/store/model/function.go +++ b/api/store/model/function.go @@ -1,12 +1,16 @@ package model type Function struct { - Id uint `gorm:"primarykey;column:id"` - Name string - Label string - Description string - Parameters string - Action string - Token string - Enabled bool + Id uint `gorm:"column:id;primaryKey;autoIncrement" json:"id"` + Name string `gorm:"column:name;type:varchar(30);uniqueIndex;not null;comment:函数名称" json:"name"` + Label string `gorm:"column:label;type:varchar(30);comment:函数标签" json:"label"` + Description string `gorm:"column:description;type:varchar(255);comment:函数描述" json:"description"` + Parameters string `gorm:"column:parameters;type:text;comment:函数参数(JSON)" json:"parameters"` + Token string `gorm:"column:token;type:varchar(255);comment:API授权token" json:"token"` + Action string `gorm:"column:action;type:varchar(255);comment:函数处理 API" json:"action"` + Enabled bool `gorm:"column:enabled;type:tinyint(1);not null;default:0;comment:是否启用" json:"enabled"` +} + +func (m *Function) TableName() string { + return "chatgpt_functions" } diff --git a/api/store/model/invite_code.go b/api/store/model/invite_code.go index 588904dd..b5bce1e7 100644 --- a/api/store/model/invite_code.go +++ b/api/store/model/invite_code.go @@ -3,10 +3,14 @@ package model import "time" type InviteCode struct { - Id uint `gorm:"primarykey;column:id"` - UserId uint - Code string - Hits int // 点击次数 - RegNum int // 注册人数 - CreatedAt time.Time + Id uint `gorm:"column:id;primaryKey;autoIncrement" json:"id"` + UserId uint `gorm:"column:user_id;type:int;not null;comment:用户ID" json:"user_id"` + Code string `gorm:"column:code;type:char(8);uniqueIndex;not null;comment:邀请码" json:"code"` + Hits int `gorm:"column:hits;type:int;not null;comment:点击次数" json:"hits"` + RegNum int `gorm:"column:reg_num;type:smallint;not null;comment:注册数量" json:"reg_num"` + CreatedAt time.Time `gorm:"column:created_at;type:datetime;not null" json:"created_at"` +} + +func (m *InviteCode) TableName() string { + return "chatgpt_invite_codes" } diff --git a/api/store/model/invite_log.go b/api/store/model/invite_log.go index 22052b2a..dd5b5ea1 100644 --- a/api/store/model/invite_log.go +++ b/api/store/model/invite_log.go @@ -5,11 +5,15 @@ import ( ) type InviteLog struct { - Id uint `gorm:"primarykey;column:id"` - InviterId uint - UserId uint - Username string - InviteCode string - Remark string - CreatedAt time.Time + Id uint `gorm:"column:id;primaryKey;autoIncrement" json:"id"` + InviterId uint `gorm:"column:inviter_id;type:int;not null;comment:邀请人ID" json:"inviter_id"` + UserId uint `gorm:"column:user_id;type:int;not null;comment:注册用户ID" json:"user_id"` + Username string `gorm:"column:username;type:varchar(30);not null;comment:用户名" json:"username"` + InviteCode string `gorm:"column:invite_code;type:char(8);not null;comment:邀请码" json:"invite_code"` + Remark string `gorm:"column:remark;type:varchar(255);not null;comment:备注" json:"remark"` + CreatedAt time.Time `gorm:"column:created_at;type:datetime;not null" json:"created_at"` +} + +func (m *InviteLog) TableName() string { + return "chatgpt_invite_logs" } diff --git a/api/store/model/menu.go b/api/store/model/menu.go index e215e204..63babb67 100644 --- a/api/store/model/menu.go +++ b/api/store/model/menu.go @@ -2,10 +2,14 @@ package model // Menu 系统菜单 type Menu struct { - Id uint `gorm:"primarykey;column:id"` - Name string // 菜单名称 - Icon string // 菜单图标 - URL string // 菜单跳转地址 - SortNum int // 排序 - Enabled bool // 启用状态 + Id uint `gorm:"column:id;primaryKey;autoIncrement" json:"id"` + Name string `gorm:"column:name;type:varchar(30);not null;comment:菜单名称" json:"name"` + Icon string `gorm:"column:icon;type:varchar(150);not null;comment:菜单图标" json:"icon"` + URL string `gorm:"column:url;type:varchar(100);not null;comment:地址" json:"url"` + SortNum int `gorm:"column:sort_num;type:smallint;not null;comment:排序" json:"sort_num"` + Enabled bool `gorm:"column:enabled;type:tinyint(1);not null;comment:是否启用" json:"enabled"` +} + +func (m *Menu) TableName() string { + return "chatgpt_menus" } diff --git a/api/store/model/mj_job.go b/api/store/model/mj_job.go index feb0471c..44010b90 100644 --- a/api/store/model/mj_job.go +++ b/api/store/model/mj_job.go @@ -3,26 +3,26 @@ package model import "time" type MidJourneyJob struct { - Id uint `gorm:"primarykey;column:id"` - Type string - UserId int - TaskId string - TaskInfo string // 原始任务信息 - ChannelId string - MessageId string - ReferenceId string - ImgURL string - OrgURL string // 原图地址 - Hash string // message hash - Progress int - Prompt string - UseProxy bool // 是否使用反代加载图片 - Publish bool //是否发布图片到画廊 - ErrMsg string // 报错信息 - Power int // 消耗算力 - CreatedAt time.Time + Id uint `gorm:"column:id;primaryKey;autoIncrement" json:"id"` + UserId uint `gorm:"column:user_id;type:int;not null;comment:用户 ID" json:"user_id"` + TaskId string `gorm:"column:task_id;type:varchar(20);uniqueIndex;comment:任务 ID" json:"task_id"` + TaskInfo string `gorm:"column:task_info;type:text;not null;comment:任务详情" json:"task_info"` + Type string `gorm:"column:type;type:varchar(20);default:image;comment:任务类别" json:"type"` + MessageId string `gorm:"column:message_id;type:char(40);not null;index;comment:消息 ID" json:"message_id"` + ChannelId string `gorm:"column:channel_id;type:varchar(100);comment:频道ID" json:"channel_id"` + RefId string `gorm:"column:reference_id;type:char(40);comment:引用消息 ID" json:"reference_id"` + Prompt string `gorm:"column:prompt;type:text;not null;comment:会话提示词" json:"prompt"` + ImgURL string `gorm:"column:img_url;type:varchar(400);comment:图片URL" json:"img_url"` + OrgURL string `gorm:"column:org_url;type:varchar(400);comment:原始图片地址" json:"org_url"` + Hash string `gorm:"column:hash;type:varchar(100);comment:message hash" json:"hash"` + Progress int `gorm:"column:progress;type:smallint;default:0;comment:任务进度" json:"progress"` + UseProxy int `gorm:"column:use_proxy;type:tinyint(1);not null;default:0;comment:是否使用反代" json:"use_proxy"` + Publish int `gorm:"column:publish;type:tinyint(1);not null;comment:是否发布" json:"publish"` + ErrMsg string `gorm:"column:err_msg;type:varchar(1024);comment:错误信息" json:"err_msg"` + Power int `gorm:"column:power;type:smallint;not null;default:0;comment:消耗算力" json:"power"` + CreatedAt time.Time `gorm:"column:created_at;type:datetime;not null" json:"created_at"` } -func (MidJourneyJob) TableName() string { +func (m *MidJourneyJob) TableName() string { return "chatgpt_mj_jobs" } diff --git a/api/store/model/order.go b/api/store/model/order.go index 4e79ed9d..9eda023a 100644 --- a/api/store/model/order.go +++ b/api/store/model/order.go @@ -2,21 +2,28 @@ package model import ( "geekai/core/types" + "time" ) // Order 充值订单 type Order struct { - BaseModel - UserId uint - ProductId uint - Username string - OrderNo string - TradeNo string - Subject string - Amount float64 - Status types.OrderStatus - Remark string - PayTime int64 - PayWay string // 支付渠道 - PayType string // 支付类型 + Id uint `gorm:"column:id;primaryKey;autoIncrement" json:"id"` + UserId uint `gorm:"column:user_id;type:int;not null;comment:用户ID" json:"user_id"` + ProductId uint `gorm:"column:product_id;type:int;not null;comment:产品ID" json:"product_id"` + Username string `gorm:"column:username;type:varchar(30);not null;comment:用户名" json:"username"` + OrderNo string `gorm:"column:order_no;type:varchar(30);uniqueIndex;not null;comment:订单ID" json:"order_no"` + TradeNo string `gorm:"column:trade_no;type:varchar(60);comment:支付平台交易流水号" json:"trade_no"` + Subject string `gorm:"column:subject;type:varchar(100);not null;comment:订单产品" json:"subject"` + Amount float64 `gorm:"column:amount;type:decimal(10,2);not null;default:0.00;comment:订单金额" json:"amount"` + Status types.OrderStatus `gorm:"column:status;type:tinyint(1);not null;default:0;comment:订单状态(0:待支付,1:已扫码,2:支付成功)" json:"status"` + Remark string `gorm:"column:remark;type:varchar(255);not null;comment:备注" json:"remark"` + PayTime int64 `gorm:"column:pay_time;type:int;comment:支付时间" json:"pay_time"` + PayWay string `gorm:"column:pay_way;type:varchar(20);not null;comment:支付方式" json:"pay_way"` + PayType string `gorm:"column:pay_type;type:varchar(30);not null;comment:支付类型" json:"pay_type"` + CreatedAt time.Time `gorm:"column:created_at;type:datetime;not null" json:"created_at"` + UpdatedAt time.Time `gorm:"column:updated_at;type:datetime;not null" json:"updated_at"` +} + +func (m *Order) TableName() string { + return "chatgpt_orders" } diff --git a/api/store/model/power_log.go b/api/store/model/power_log.go index fd6c3228..3e5e403c 100644 --- a/api/store/model/power_log.go +++ b/api/store/model/power_log.go @@ -7,14 +7,18 @@ import ( // PowerLog 算力消费日志 type PowerLog struct { - Id uint `gorm:"primarykey;column:id"` - UserId uint - Username string - Type types.PowerType - Amount int - Balance int - Model string // 模型 - Remark string // 备注 - Mark types.PowerMark // 资金类型 - CreatedAt time.Time + Id uint `gorm:"column:id;primaryKey;autoIncrement" json:"id"` + UserId uint `gorm:"column:user_id;type:int;not null;comment:用户ID" json:"user_id"` + Username string `gorm:"column:username;type:varchar(30);not null;comment:用户名" json:"username"` + Type types.PowerType `gorm:"column:type;type:tinyint(1);not null;comment:类型(1:充值,2:消费,3:退费)" json:"type"` + Amount int `gorm:"column:amount;type:smallint;not null;comment:算力数值" json:"amount"` + Balance int `gorm:"column:balance;type:int;not null;comment:余额" json:"balance"` + Model string `gorm:"column:model;type:varchar(30);not null;comment:模型" json:"model"` + Remark string `gorm:"column:remark;type:varchar(512);not null;comment:备注" json:"remark"` + Mark types.PowerMark `gorm:"column:mark;type:tinyint(1);not null;comment:资金类型(0:支出,1:收入)" json:"mark"` + CreatedAt time.Time `gorm:"column:created_at;type:datetime;not null;comment:创建时间" json:"created_at"` +} + +func (m *PowerLog) TableName() string { + return "chatgpt_power_logs" } diff --git a/api/store/model/product.go b/api/store/model/product.go index 66e35d14..f1bcc744 100644 --- a/api/store/model/product.go +++ b/api/store/model/product.go @@ -1,14 +1,26 @@ package model +import ( + "time" +) + // Product 充值产品 type Product struct { - BaseModel - Name string - Price float64 - Discount float64 - Days int - Power int - Enabled bool - Sales int - SortNum int + Id uint `gorm:"column:id;primaryKey;autoIncrement" json:"id"` + Name string `gorm:"column:name;type:varchar(30);not null;comment:名称" json:"name"` + Price float64 `gorm:"column:price;type:decimal(10,2);not null;default:0.00;comment:价格" json:"price"` + Discount float64 `gorm:"column:discount;type:decimal(10,2);not null;default:0.00;comment:优惠金额" json:"discount"` + Days int `gorm:"column:days;type:smallint;not null;default:0;comment:延长天数" json:"days"` + Power int `gorm:"column:power;type:int;not null;default:0;comment:增加算力值" json:"power"` + Enabled bool `gorm:"column:enabled;type:tinyint(1);not null;default:0;comment:是否启动" json:"enabled"` + Sales int `gorm:"column:sales;type:int;not null;default:0;comment:销量" json:"sales"` + SortNum int `gorm:"column:sort_num;type:tinyint;not null;default:0;comment:排序" json:"sort_num"` + CreatedAt time.Time `gorm:"column:created_at;type:datetime;not null" json:"created_at"` + UpdatedAt time.Time `gorm:"column:updated_at;type:datetime;not null" json:"updated_at"` + AppUrl string `gorm:"column:app_url;type:varchar(255);comment:App跳转地址" json:"app_url"` + Url string `gorm:"column:url;type:varchar(255);comment:跳转地址" json:"url"` +} + +func (m *Product) TableName() string { + return "chatgpt_products" } diff --git a/api/store/model/redeem.go b/api/store/model/redeem.go index 6cb1c0d3..9c399460 100644 --- a/api/store/model/redeem.go +++ b/api/store/model/redeem.go @@ -5,12 +5,16 @@ import "time" // 兑换码 type Redeem struct { - Id uint `gorm:"primarykey;column:id"` - UserId uint // 用户 ID - Name string // 名称 - Power int // 算力 - Code string // 兑换码 - Enabled bool // 启用状态 - RedeemedAt int64 // 兑换时间 - CreatedAt time.Time + Id uint `gorm:"column:id;primaryKey;autoIncrement" json:"id"` + UserId uint `gorm:"column:user_id;type:int;not null;comment:用户 ID" json:"user_id"` + Name string `gorm:"column:name;type:varchar(30);not null;comment:兑换码名称" json:"name"` + Power int `gorm:"column:power;type:int;not null;comment:算力" json:"power"` + Code string `gorm:"column:code;type:varchar(100);uniqueIndex;not null;comment:兑换码" json:"code"` + Enabled bool `gorm:"column:enabled;type:tinyint(1);not null;comment:是否启用" json:"enabled"` + CreatedAt time.Time `gorm:"column:created_at;type:datetime;not null" json:"created_at"` + RedeemedAt int64 `gorm:"column:redeemed_at;type:int;not null;comment:兑换时间" json:"redeemed_at"` +} + +func (m *Redeem) TableName() string { + return "chatgpt_redeems" } diff --git a/api/store/model/sd_job.go b/api/store/model/sd_job.go index c2ff59a8..13fc4ae0 100644 --- a/api/store/model/sd_job.go +++ b/api/store/model/sd_job.go @@ -3,21 +3,21 @@ package model import "time" type SdJob struct { - Id uint `gorm:"primarykey;column:id"` - Type string - UserId int - TaskId string - TaskInfo string // 原始任务信息 - ImgURL string - Progress int - Prompt string - Params string - Publish bool //是否发布图片到画廊 - ErrMsg string // 报错信息 - Power int // 消耗算力 - CreatedAt time.Time + Id uint `gorm:"column:id;primaryKey;autoIncrement" json:"id"` + UserId uint `gorm:"column:user_id;type:int;not null;comment:用户 ID" json:"user_id"` + Type string `gorm:"column:type;type:varchar(20);default:txt2img;comment:任务类别" json:"type"` + TaskId string `gorm:"column:task_id;type:char(30);uniqueIndex;not null;comment:任务 ID" json:"task_id"` + TaskInfo string `gorm:"column:task_info;type:text;not null;comment:任务详情" json:"task_info"` + Prompt string `gorm:"column:prompt;type:text;not null;comment:会话提示词" json:"prompt"` + ImgURL string `gorm:"column:img_url;type:varchar(255);comment:图片URL" json:"img_url"` + Params string `gorm:"column:params;type:text;comment:绘画参数json" json:"params"` + Progress int `gorm:"column:progress;type:smallint;default:0;comment:任务进度" json:"progress"` + Publish int `gorm:"column:publish;type:tinyint(1);not null;comment:是否发布" json:"publish"` + ErrMsg string `gorm:"column:err_msg;type:varchar(1024);comment:错误信息" json:"err_msg"` + Power int `gorm:"column:power;type:smallint;not null;default:0;comment:消耗算力" json:"power"` + CreatedAt time.Time `gorm:"column:created_at;type:datetime;not null" json:"created_at"` } -func (SdJob) TableName() string { +func (m *SdJob) TableName() string { return "chatgpt_sd_jobs" } diff --git a/api/store/model/suno_job.go b/api/store/model/suno_job.go index ecc0de09..aebcc016 100644 --- a/api/store/model/suno_job.go +++ b/api/store/model/suno_job.go @@ -3,33 +3,33 @@ package model import "time" type SunoJob struct { - Id uint `gorm:"primarykey;column:id"` - UserId int - Channel string // 频道 - Title string - Type int - TaskId string - TaskInfo string // 原始任务信息 - RefTaskId string // 续写的任务id - Tags string // 歌曲风格和标签 - Instrumental bool // 是否生成纯音乐 - ExtendSecs int // 续写秒数 - SongId string // 续写的歌曲id - RefSongId string - Prompt string // 提示词 - CoverURL string // 封面图 URL - AudioURL string // 音频 URL - ModelName string // 模型名称 - Progress int // 任务进度 - Duration int // 银屏时长,秒 - Publish bool // 是否发布 - ErrMsg string // 错误信息 - RawData string // 原始数据 json - Power int // 消耗算力 - PlayTimes int // 播放次数 - CreatedAt time.Time + Id uint `gorm:"column:id;primaryKey;autoIncrement" json:"id"` + UserId uint `gorm:"column:user_id;type:int;not null;comment:用户 ID" json:"user_id"` + Channel string `gorm:"column:channel;type:varchar(100);not null;comment:渠道" json:"channel"` + Title string `gorm:"column:title;type:varchar(100);comment:歌曲标题" json:"title"` + Type int `gorm:"column:type;type:tinyint(1);default:0;comment:任务类型,1:灵感创作,2:自定义创作" json:"type"` + TaskId string `gorm:"column:task_id;type:varchar(50);comment:任务 ID" json:"task_id"` + TaskInfo string `gorm:"column:task_info;type:text;not null;comment:任务详情" json:"task_info"` + RefTaskId string `gorm:"column:ref_task_id;type:char(50);comment:引用任务 ID" json:"ref_task_id"` + Tags string `gorm:"column:tags;type:varchar(100);comment:歌曲风格" json:"tags"` + Instrumental bool `gorm:"column:instrumental;type:tinyint(1);default:0;comment:是否为纯音乐" json:"instrumental"` + ExtendSecs int `gorm:"column:extend_secs;type:smallint;default:0;comment:延长秒数" json:"extend_secs"` + SongId string `gorm:"column:song_id;type:varchar(50);comment:要续写的歌曲 ID" json:"song_id"` + RefSongId string `gorm:"column:ref_song_id;type:varchar(50);not null;comment:引用的歌曲ID" json:"ref_song_id"` + Prompt string `gorm:"column:prompt;type:varchar(2000);not null;comment:提示词" json:"prompt"` + CoverURL string `gorm:"column:cover_url;type:varchar(512);comment:封面图地址" json:"cover_url"` + AudioURL string `gorm:"column:audio_url;type:varchar(512);comment:音频地址" json:"audio_url"` + ModelName string `gorm:"column:model_name;type:varchar(30);comment:模型地址" json:"model_name"` + Progress int `gorm:"column:progress;type:smallint;default:0;comment:任务进度" json:"progress"` + Duration int `gorm:"column:duration;type:smallint;not null;default:0;comment:歌曲时长" json:"duration"` + Publish int `gorm:"column:publish;type:tinyint(1);not null;comment:是否发布" json:"publish"` + ErrMsg string `gorm:"column:err_msg;type:varchar(1024);comment:错误信息" json:"err_msg"` + RawData string `gorm:"column:raw_data;type:text;comment:原始数据" json:"raw_data"` + Power int `gorm:"column:power;type:smallint;not null;default:0;comment:消耗算力" json:"power"` + PlayTimes int `gorm:"column:play_times;type:int;comment:播放次数" json:"play_times"` + CreatedAt time.Time `gorm:"column:created_at;type:datetime;not null" json:"created_at"` } -func (SunoJob) TableName() string { +func (m *SunoJob) TableName() string { return "chatgpt_suno_jobs" } diff --git a/api/store/model/user.go b/api/store/model/user.go index 6a6e5829..3a6fda61 100644 --- a/api/store/model/user.go +++ b/api/store/model/user.go @@ -1,23 +1,33 @@ package model +import ( + "time" +) + type User struct { - BaseModel - Username string - Nickname string - Email string - Mobile string - Password string - Avatar string - Salt string // 密码盐 - Power int // 剩余算力 - ChatConfig string `gorm:"column:chat_config_json"` // 聊天配置 json - ChatRoles string `gorm:"column:chat_roles_json"` // 聊天角色 - ChatModels string `gorm:"column:chat_models_json"` // AI 模型,不同的用户拥有不同的聊天模型 - ExpiredTime int64 // 账户到期时间 - Status bool `gorm:"default:true"` // 当前状态 - LastLoginAt int64 // 最后登录时间 - LastLoginIp string // 最后登录 IP - OpenId string `gorm:"column:openid"` - Platform string `json:"platform"` - Vip bool // 是否 VIP 会员 + Id uint `gorm:"column:id;primaryKey;autoIncrement" json:"id"` + Username string `gorm:"column:username;type:varchar(30);uniqueIndex;not null;comment:用户名" json:"username"` + Mobile string `gorm:"column:mobile;type:char(11);comment:手机号" json:"mobile"` + Email string `gorm:"column:email;type:varchar(50);comment:邮箱地址" json:"email"` + Nickname string `gorm:"column:nickname;type:varchar(30);not null;comment:昵称" json:"nickname"` + Password string `gorm:"column:password;type:char(64);not null;comment:密码" json:"password"` + Avatar string `gorm:"column:avatar;type:varchar(255);not null;comment:头像" json:"avatar"` + Salt string `gorm:"column:salt;type:char(12);not null;comment:密码盐" json:"salt"` + Power int `gorm:"column:power;type:int;not null;default:0;comment:剩余算力" json:"power"` + ExpiredTime int64 `gorm:"column:expired_time;type:int;not null;comment:用户过期时间" json:"expired_time"` + Status bool `gorm:"column:status;type:tinyint(1);not null;comment:当前状态" json:"status"` + ChatConfig string `gorm:"column:chat_config;type:text;not null;comment:聊天配置json" json:"chat_config"` + ChatRoles string `gorm:"column:chat_roles_json;type:text;not null;comment:聊天角色 json" json:"chat_roles_json"` + ChatModels string `gorm:"column:chat_models_json;type:text;not null;comment:AI模型 json" json:"chat_models_json"` + LastLoginAt int64 `gorm:"column:last_login_at;type:int;not null;comment:最后登录时间" json:"last_login_at"` + Vip bool `gorm:"column:vip;type:tinyint(1);not null;default:0;comment:是否会员" json:"vip"` + LastLoginIp string `gorm:"column:last_login_ip;type:char(16);not null;comment:最后登录 IP" json:"last_login_ip"` + OpenId string `gorm:"column:openid;type:varchar(100);comment:第三方登录账号ID" json:"openid"` + Platform string `gorm:"column:platform;type:varchar(30);comment:登录平台" json:"platform"` + CreatedAt time.Time `gorm:"column:created_at;type:datetime;not null" json:"created_at"` + UpdatedAt time.Time `gorm:"column:updated_at;type:datetime;not null" json:"updated_at"` +} + +func (m *User) TableName() string { + return "chatgpt_users" } diff --git a/api/store/model/user_login_log.go b/api/store/model/user_login_log.go index 87596d53..6e878752 100644 --- a/api/store/model/user_login_log.go +++ b/api/store/model/user_login_log.go @@ -1,9 +1,19 @@ package model +import ( + "time" +) + type UserLoginLog struct { - BaseModel - UserId uint - Username string - LoginIp string - LoginAddress string + Id uint `gorm:"column:id;primaryKey;autoIncrement" json:"id"` + UserId uint `gorm:"column:user_id;type:int;not null;comment:用户ID" json:"user_id"` + Username string `gorm:"column:username;type:varchar(30);not null;comment:用户名" json:"username"` + LoginIp string `gorm:"column:login_ip;type:char(16);not null;comment:登录IP" json:"login_ip"` + LoginAddress string `gorm:"column:login_address;type:varchar(30);not null;comment:登录地址" json:"login_address"` + CreatedAt time.Time `gorm:"column:created_at;type:datetime;not null" json:"created_at"` + UpdatedAt time.Time `gorm:"column:updated_at;type:datetime;not null" json:"updated_at"` +} + +func (m *UserLoginLog) TableName() string { + return "chatgpt_user_login_logs" } diff --git a/api/store/model/video_job.go b/api/store/model/video_job.go index b3bbb08e..500a26b7 100644 --- a/api/store/model/video_job.go +++ b/api/store/model/video_job.go @@ -3,25 +3,25 @@ package model import "time" type VideoJob struct { - Id uint `gorm:"primarykey;column:id"` - UserId int - Channel string // 频道 - Type string // luma,runway,cog - TaskId string - TaskInfo string // 原始任务信息 - Prompt string // 提示词 - PromptExt string // 优化后提示词 - CoverURL string // 封面图 URL - VideoURL string // 无水印视频 URL - WaterURL string // 有水印视频 URL - Progress int // 任务进度 - Publish bool // 是否发布 - ErrMsg string // 错误信息 - RawData string // 原始数据 json - Power int // 消耗算力 - CreatedAt time.Time + Id uint `gorm:"column:id;primaryKey;autoIncrement" json:"id"` + UserId uint `gorm:"column:user_id;type:int;not null;comment:用户 ID" json:"user_id"` + Channel string `gorm:"column:channel;type:varchar(100);not null;comment:渠道" json:"channel"` + TaskId string `gorm:"column:task_id;type:varchar(100);not null;comment:任务 ID" json:"task_id"` + TaskInfo string `gorm:"column:task_info;type:text;comment:原始任务信息" json:"task_info"` + Type string `gorm:"column:type;type:varchar(20);comment:任务类型,luma,runway,cogvideo" json:"type"` + Prompt string `gorm:"column:prompt;type:text;not null;comment:提示词" json:"prompt"` + PromptExt string `gorm:"column:prompt_ext;type:text;comment:优化后提示词" json:"prompt_ext"` + CoverURL string `gorm:"column:cover_url;type:varchar(512);comment:封面图地址" json:"cover_url"` + VideoURL string `gorm:"column:video_url;type:varchar(512);comment:视频地址" json:"video_url"` + WaterURL string `gorm:"column:water_url;type:varchar(512);comment:带水印的视频地址" json:"water_url"` + Progress int `gorm:"column:progress;type:smallint;default:0;comment:任务进度" json:"progress"` + Publish int `gorm:"column:publish;type:tinyint(1);not null;comment:是否发布" json:"publish"` + ErrMsg string `gorm:"column:err_msg;type:varchar(1024);comment:错误信息" json:"err_msg"` + RawData string `gorm:"column:raw_data;type:text;comment:原始数据" json:"raw_data"` + Power int `gorm:"column:power;type:smallint;not null;default:0;comment:消耗算力" json:"power"` + CreatedAt time.Time `gorm:"column:created_at;type:datetime;not null" json:"created_at"` } -func (VideoJob) TableName() string { +func (m *VideoJob) TableName() string { return "chatgpt_video_jobs" } diff --git a/api/store/vo/chat_model.go b/api/store/vo/chat_model.go index 50196263..81ae2d4e 100644 --- a/api/store/vo/chat_model.go +++ b/api/store/vo/chat_model.go @@ -10,6 +10,8 @@ type ChatModel struct { Open bool `json:"open"` MaxTokens int `json:"max_tokens"` // 最大响应长度 MaxContext int `json:"max_context"` // 最大上下文长度 + Description string `json:"description"` // 模型描述 + Category string `json:"category"` //模型类别 Temperature float32 `json:"temperature"` // 模型温度 KeyId int `json:"key_id,omitempty"` KeyName string `json:"key_name"` diff --git a/database/chatgpt_plus-v4.0.4.sql b/database/archive/chatgpt_plus-v4.0.4.sql similarity index 100% rename from database/chatgpt_plus-v4.0.4.sql rename to database/archive/chatgpt_plus-v4.0.4.sql diff --git a/database/chatgpt_plus-v4.0.5.sql b/database/archive/chatgpt_plus-v4.0.5.sql similarity index 100% rename from database/chatgpt_plus-v4.0.5.sql rename to database/archive/chatgpt_plus-v4.0.5.sql diff --git a/database/chatgpt_plus-v4.0.6.sql b/database/archive/chatgpt_plus-v4.0.6.sql similarity index 100% rename from database/chatgpt_plus-v4.0.6.sql rename to database/archive/chatgpt_plus-v4.0.6.sql diff --git a/database/chatgpt_plus-v4.0.7.sql b/database/archive/chatgpt_plus-v4.0.7.sql similarity index 100% rename from database/chatgpt_plus-v4.0.7.sql rename to database/archive/chatgpt_plus-v4.0.7.sql diff --git a/database/chatgpt_plus-v4.0.8.sql b/database/archive/chatgpt_plus-v4.0.8.sql similarity index 100% rename from database/chatgpt_plus-v4.0.8.sql rename to database/archive/chatgpt_plus-v4.0.8.sql diff --git a/database/chatgpt_plus-v4.0.9.sql b/database/archive/chatgpt_plus-v4.0.9.sql similarity index 100% rename from database/chatgpt_plus-v4.0.9.sql rename to database/archive/chatgpt_plus-v4.0.9.sql diff --git a/database/chatgpt_plus-v4.1.0.sql b/database/archive/chatgpt_plus-v4.1.0.sql similarity index 100% rename from database/chatgpt_plus-v4.1.0.sql rename to database/archive/chatgpt_plus-v4.1.0.sql diff --git a/database/chatgpt_plus-v4.1.1.sql b/database/archive/chatgpt_plus-v4.1.1.sql similarity index 100% rename from database/chatgpt_plus-v4.1.1.sql rename to database/archive/chatgpt_plus-v4.1.1.sql diff --git a/database/chatgpt_plus-v4.1.2.sql b/database/archive/chatgpt_plus-v4.1.2.sql similarity index 100% rename from database/chatgpt_plus-v4.1.2.sql rename to database/archive/chatgpt_plus-v4.1.2.sql diff --git a/database/geekai_plus-v4.1.3.sql b/database/archive/geekai_plus-v4.1.3.sql similarity index 100% rename from database/geekai_plus-v4.1.3.sql rename to database/archive/geekai_plus-v4.1.3.sql diff --git a/database/geekai_plus-v4.1.4.sql b/database/archive/geekai_plus-v4.1.4.sql similarity index 100% rename from database/geekai_plus-v4.1.4.sql rename to database/archive/geekai_plus-v4.1.4.sql diff --git a/database/geekai_plus-v4.1.5.sql b/database/archive/geekai_plus-v4.1.5.sql similarity index 100% rename from database/geekai_plus-v4.1.5.sql rename to database/archive/geekai_plus-v4.1.5.sql diff --git a/database/geekai_plus-v4.1.6.sql b/database/archive/geekai_plus-v4.1.6.sql similarity index 100% rename from database/geekai_plus-v4.1.6.sql rename to database/archive/geekai_plus-v4.1.6.sql diff --git a/database/geekai_plus-v4.1.7.sql b/database/archive/geekai_plus-v4.1.7.sql similarity index 100% rename from database/geekai_plus-v4.1.7.sql rename to database/archive/geekai_plus-v4.1.7.sql diff --git a/database/geekai_plus-v4.1.8.sql b/database/archive/geekai_plus-v4.1.8.sql similarity index 100% rename from database/geekai_plus-v4.1.8.sql rename to database/archive/geekai_plus-v4.1.8.sql diff --git a/database/geekai_plus-v4.1.9.sql b/database/archive/geekai_plus-v4.1.9.sql similarity index 100% rename from database/geekai_plus-v4.1.9.sql rename to database/archive/geekai_plus-v4.1.9.sql diff --git a/database/geekai_plus-v4.2.0.sql b/database/archive/geekai_plus-v4.2.0.sql similarity index 100% rename from database/geekai_plus-v4.2.0.sql rename to database/archive/geekai_plus-v4.2.0.sql diff --git a/database/geekai_plus-v4.2.1.sql b/database/archive/geekai_plus-v4.2.1.sql similarity index 100% rename from database/geekai_plus-v4.2.1.sql rename to database/archive/geekai_plus-v4.2.1.sql diff --git a/database/geekai_plus-v4.2.2.sql b/database/archive/geekai_plus-v4.2.2.sql similarity index 100% rename from database/geekai_plus-v4.2.2.sql rename to database/archive/geekai_plus-v4.2.2.sql diff --git a/database/update-v4.0.0.sql b/database/archive/update-v4.0.0.sql similarity index 100% rename from database/update-v4.0.0.sql rename to database/archive/update-v4.0.0.sql diff --git a/database/update-v4.0.2.sql b/database/archive/update-v4.0.2.sql similarity index 100% rename from database/update-v4.0.2.sql rename to database/archive/update-v4.0.2.sql diff --git a/database/update-v4.0.3.sql b/database/archive/update-v4.0.3.sql similarity index 100% rename from database/update-v4.0.3.sql rename to database/archive/update-v4.0.3.sql diff --git a/database/update-v4.0.4.sql b/database/archive/update-v4.0.4.sql similarity index 100% rename from database/update-v4.0.4.sql rename to database/archive/update-v4.0.4.sql diff --git a/database/update-v4.0.7.sql b/database/archive/update-v4.0.7.sql similarity index 100% rename from database/update-v4.0.7.sql rename to database/archive/update-v4.0.7.sql diff --git a/database/update-v4.0.8.sql b/database/archive/update-v4.0.8.sql similarity index 100% rename from database/update-v4.0.8.sql rename to database/archive/update-v4.0.8.sql diff --git a/database/update-v4.1.0.sql b/database/archive/update-v4.1.0.sql similarity index 100% rename from database/update-v4.1.0.sql rename to database/archive/update-v4.1.0.sql diff --git a/database/update-v4.1.1.sql b/database/archive/update-v4.1.1.sql similarity index 100% rename from database/update-v4.1.1.sql rename to database/archive/update-v4.1.1.sql diff --git a/database/update-v4.1.2.sql b/database/archive/update-v4.1.2.sql similarity index 100% rename from database/update-v4.1.2.sql rename to database/archive/update-v4.1.2.sql diff --git a/database/update-v4.1.3.sql b/database/archive/update-v4.1.3.sql similarity index 100% rename from database/update-v4.1.3.sql rename to database/archive/update-v4.1.3.sql diff --git a/database/update-v4.1.4.sql b/database/archive/update-v4.1.4.sql similarity index 100% rename from database/update-v4.1.4.sql rename to database/archive/update-v4.1.4.sql diff --git a/database/update-v4.1.5.sql b/database/archive/update-v4.1.5.sql similarity index 100% rename from database/update-v4.1.5.sql rename to database/archive/update-v4.1.5.sql diff --git a/database/update-v4.1.6.sql b/database/archive/update-v4.1.6.sql similarity index 100% rename from database/update-v4.1.6.sql rename to database/archive/update-v4.1.6.sql diff --git a/database/update-v4.1.7.sql b/database/archive/update-v4.1.7.sql similarity index 100% rename from database/update-v4.1.7.sql rename to database/archive/update-v4.1.7.sql diff --git a/database/update-v4.1.8.sql b/database/archive/update-v4.1.8.sql similarity index 100% rename from database/update-v4.1.8.sql rename to database/archive/update-v4.1.8.sql diff --git a/database/update-v4.2.1.sql b/database/archive/update-v4.2.1.sql similarity index 100% rename from database/update-v4.2.1.sql rename to database/archive/update-v4.2.1.sql diff --git a/database/update-v4.2.2.sql b/database/archive/update-v4.2.2.sql similarity index 100% rename from database/update-v4.2.2.sql rename to database/archive/update-v4.2.2.sql diff --git a/database/update-v4.2.3.sql b/database/update-v4.2.3.sql new file mode 100644 index 00000000..0cdf9f14 --- /dev/null +++ b/database/update-v4.2.3.sql @@ -0,0 +1,5 @@ +ALTER TABLE `chatgpt_chat_models` ADD `category` VARCHAR(1024) NOT NULL DEFAULT '' COMMENT '模型类别' AFTER `id`; +ALTER TABLE `chatgpt_chat_models` ADD `description` VARCHAR(1024) NOT NULL DEFAULT '' COMMENT '模型类型描述' AFTER `id`; +ALTER TABLE `chatgpt_orders` DROP `deleted_at`; +ALTER TABLE `chatgpt_chat_history` DROP `deleted_at`; +ALTER TABLE `chatgpt_chat_items` DROP `deleted_at`; diff --git a/web/package-lock.json b/web/package-lock.json index 90514b12..82dd37b7 100644 --- a/web/package-lock.json +++ b/web/package-lock.json @@ -8,8 +8,12 @@ "name": "geekai-web", "version": "0.1.0", "dependencies": { + "@better-scroll/core": "^2.5.1", + "@better-scroll/mouse-wheel": "^2.5.1", + "@better-scroll/observe-dom": "^2.5.1", + "@better-scroll/pull-up": "^2.5.1", + "@better-scroll/scroll-bar": "^2.5.1", "@element-plus/icons-vue": "^2.3.1", - "@openai/realtime-api-beta": "github:openai/openai-realtime-api-beta", "animate.css": "^4.1.1", "axios": "^0.27.2", "clipboard": "^2.0.11", @@ -35,7 +39,6 @@ "qs": "^6.11.1", "sortablejs": "^1.15.0", "three": "^0.128.0", - "v3-waterfall": "^1.3.3", "vant": "^4.5.0", "vue": "^3.2.13", "vue-router": "^4.0.15", @@ -1728,6 +1731,51 @@ "node": ">=6.9.0" } }, + "node_modules/@better-scroll/core": { + "version": "2.5.1", + "resolved": "https://registry.npmmirror.com/@better-scroll/core/-/core-2.5.1.tgz", + "integrity": "sha512-koKOuYA55dQ04FJRIVUpMGDr1hbCfWmfX0MGp1hKagkQSWSRpwblqACiwtggVauoj9aaJRJZ9hDsTM4weaavlg==", + "dependencies": { + "@better-scroll/shared-utils": "^2.5.1" + } + }, + "node_modules/@better-scroll/mouse-wheel": { + "version": "2.5.1", + "resolved": "https://registry.npmmirror.com/@better-scroll/mouse-wheel/-/mouse-wheel-2.5.1.tgz", + "integrity": "sha512-DGnrirRMY6zMM7xwgx09D/cA9A//3J1/uDkq8iBVEyE5p0sEr/keQpjEfFHGkBRa505BnbBwdbN6f5lugEDSPw==", + "dependencies": { + "@better-scroll/core": "^2.5.1" + } + }, + "node_modules/@better-scroll/observe-dom": { + "version": "2.5.1", + "resolved": "https://registry.npmmirror.com/@better-scroll/observe-dom/-/observe-dom-2.5.1.tgz", + "integrity": "sha512-TCMGFLRfpXBPIwtUV/efliUmfmrhSNI7NXdSyjdWjsLOS7dh3eFkmcom5ERVWMaXVELSmujGXLqobT+dT0C/jg==", + "dependencies": { + "@better-scroll/core": "^2.5.1" + } + }, + "node_modules/@better-scroll/pull-up": { + "version": "2.5.1", + "resolved": "https://registry.npmmirror.com/@better-scroll/pull-up/-/pull-up-2.5.1.tgz", + "integrity": "sha512-1hu3xSMxdB8T391KffpNZ7g93lMwZEHjfb1F1Y4KvIkciDt8nXqkGpqrZF+YwR+EJTgYcWqUO8kgmI6XXu7Pkg==", + "dependencies": { + "@better-scroll/core": "^2.5.1" + } + }, + "node_modules/@better-scroll/scroll-bar": { + "version": "2.5.1", + "resolved": "https://registry.npmmirror.com/@better-scroll/scroll-bar/-/scroll-bar-2.5.1.tgz", + "integrity": "sha512-i6r60pWG/ztkFK2j5Gj54I0LJb2jGh5TWJNQBoW0gUkp28B+0JvBFTwZn9tF7beZCBorKR7Hvvu4O9A1TJy94Q==", + "dependencies": { + "@better-scroll/core": "^2.5.1" + } + }, + "node_modules/@better-scroll/shared-utils": { + "version": "2.5.1", + "resolved": "https://registry.npmmirror.com/@better-scroll/shared-utils/-/shared-utils-2.5.1.tgz", + "integrity": "sha512-AplkfSjXVYP9LZiD6JsKgmgQJ/mG4uuLmBuwLz8W5OsYc7AYTfN8kw6GqZ5OwCGoXkVhBGyd8NeC4xwYItp0aw==" + }, "node_modules/@ctrl/tinycolor": { "version": "3.6.1", "resolved": "https://registry.npmjs.org/@ctrl/tinycolor/-/tinycolor-3.6.1.tgz", @@ -2133,13 +2181,6 @@ "node": ">= 8" } }, - "node_modules/@openai/realtime-api-beta": { - "version": "0.0.0", - "resolved": "git+ssh://git@github.com/openai/openai-realtime-api-beta.git#a5cb94824f625423858ebacb9f769226ca98945f", - "dependencies": { - "ws": "^8.18.0" - } - }, "node_modules/@pkgjs/parseargs": { "version": "0.11.0", "resolved": "https://registry.npmmirror.com/@pkgjs/parseargs/-/parseargs-0.11.0.tgz", @@ -12711,11 +12752,6 @@ "uuid": "dist/bin/uuid" } }, - "node_modules/v3-waterfall": { - "version": "1.3.3", - "resolved": "https://registry.npmjs.org/v3-waterfall/-/v3-waterfall-1.3.3.tgz", - "integrity": "sha512-jUmp0xpHGkEcUxaYKGRtI5b2NvogxI/UrfoCLmpTi0UbQndDdqjwufxJvWwiJjwZQyOIPpnq9ZOFtkBwxchq3Q==" - }, "node_modules/v8-compile-cache": { "version": "2.4.0", "resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.4.0.tgz", @@ -13531,6 +13567,7 @@ "version": "8.18.0", "resolved": "https://registry.npmjs.org/ws/-/ws-8.18.0.tgz", "integrity": "sha512-8VbfWfHLbbwu3+N6OKsOMpBdT4kXPDDB9cJk2bJ6mh9ucxdlnNvH1e+roYkKmN9Nxw2yjz7VzeO9oOz2zJ04Pw==", + "dev": true, "engines": { "node": ">=10.0.0" }, diff --git a/web/src/views/ChatPlus.vue b/web/src/views/ChatPlus.vue index 89df83a4..c3e14ceb 100644 --- a/web/src/views/ChatPlus.vue +++ b/web/src/views/ChatPlus.vue @@ -14,7 +14,13 @@