merge v4.2.3

This commit is contained in:
RockYang
2026-01-29 20:11:50 +08:00
129 changed files with 3386 additions and 1946 deletions

View File

@@ -1,5 +1,17 @@
# 更新日志
## v4.2.3
- 功能优化:增加模型分组与模型描述,采用卡片展示模式改进模型选择功能体验
- 功能优化:化思维导图下载图片的清晰度以及解决拖动、缩放操作后下载图片内容不全问题
- Bug 修复:修复 MJ 画图页面已画出的图,点复制指令无效问题
- 功能优化MJ 画图的分辨率支持自定义,优先使用 prompt 中--ar 参数
- Bug 修复:修复 MJ 绘画 U1-V1,拼写错误
- 功能优化:支持自动迁移数据表结构,无需在手动执行 SQL 了
- 功能优化:移除首页的文字动画效果
- 功能优化:在聊天页面增加对话列表展开和隐藏功能
- 功能优化:聊天页面增加 AI 思考中动画效果
## v4.2.2
- 功能优化:开启图形验证码功能的时候现检查是否配置了 API 服务,防止开启之后没法登录的 Bug。

1
api/.gitignore vendored
View File

@@ -17,5 +17,6 @@ bin
data
config.toml
static/upload
static/audio
storage.json
res/certs/wechat/apiclient_key.pem

View File

@@ -35,7 +35,6 @@ import (
)
type AppServer struct {
Debug bool
Config *types.AppConfig
Engine *gin.Engine
SysConfig *types.SystemConfig // system config cache
@@ -45,7 +44,6 @@ func NewServer(appConfig *types.AppConfig) *AppServer {
gin.SetMode(gin.ReleaseMode)
gin.DefaultWriter = io.Discard
return &AppServer{
Debug: false,
Config: appConfig,
Engine: gin.Default(),
}
@@ -73,6 +71,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()
@@ -132,14 +161,14 @@ func corsMiddleware() gin.HandlerFunc {
return func(c *gin.Context) {
method := c.Request.Method
origin := c.Request.Header.Get("Origin")
// 设置允许的请求源
if origin != "" {
c.Header("Access-Control-Allow-Origin", origin)
} else {
c.Header("Access-Control-Allow-Origin", "*")
}
c.Header("Access-Control-Allow-Methods", "POST, GET, OPTIONS, PUT, DELETE, UPDATE")
//允许跨域设置可以返回其他子段,可以自定义字段
c.Header("Access-Control-Allow-Headers", "Authorization, Body-Length, Body-Type, Admin-Authorization,content-type")

View File

@@ -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
}

View File

@@ -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))
}
}
@@ -113,8 +113,8 @@ func (h *ChatAppHandler) List(c *gin.Context) {
role.Id = v.Id
role.CreatedAt = v.CreatedAt.Unix()
role.UpdatedAt = v.UpdatedAt.Unix()
role.ModelName = modelNameMap[role.ModelId]
role.TypeName = typeNameMap[role.Tid]
role.ModelName = modelNameMap[int(role.ModelId)]
role.TypeName = typeNameMap[int(role.Tid)]
roles = append(roles, role)
}
}

View File

@@ -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,

View File

@@ -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)

View File

@@ -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%dErr: %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%dErr: %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,

View File

@@ -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%dErr: %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%dErr: %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,

View File

@@ -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,

View File

@@ -59,14 +59,6 @@ func NewChatHandler(app *core.AppServer, db *gorm.DB, redis *redis.Client, manag
}
func (h *ChatHandler) sendMessage(ctx context.Context, session *types.ChatSession, role model.ChatRole, prompt string, ws *types.WsClient) error {
if !h.App.Debug {
defer func() {
if r := recover(); r != nil {
logger.Error("Recover message from error: ", r)
}
}()
}
var user model.User
res := h.DB.Model(&model.User{}).First(&user, session.UserId)
if res.Error != nil {
@@ -395,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),

View File

@@ -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 {

View File

@@ -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)),

View File

@@ -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)),

View File

@@ -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),

View File

@@ -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

View File

@@ -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,

View File

@@ -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),

View File

@@ -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: "生成视频脚本",

View File

@@ -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: "实时语音通话",

View File

@@ -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]),

View File

@@ -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

View File

@@ -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,

View File

@@ -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),

View File

@@ -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,

View File

@@ -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

View File

@@ -8,11 +8,12 @@ package logger
// * +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
import (
"os"
"strings"
"go.uber.org/zap"
"go.uber.org/zap/zapcore"
"gopkg.in/natefinch/lumberjack.v2"
"os"
"strings"
)
var logger *zap.Logger
@@ -23,7 +24,7 @@ func GetLogger() *zap.SugaredLogger {
return sugarLogger
}
logLevel := zap.NewAtomicLevelAt(getLogLevel(os.Getenv("LOG_LEVEL")))
logLevel := zap.NewAtomicLevelAt(getLogLevel(os.Getenv("GEEKAI_LOG_LEVEL")))
encoder := getEncoder()
writerSyncer := getLogWriter()
fileCore := zapcore.NewCore(encoder, writerSyncer, logLevel)

View File

@@ -132,7 +132,11 @@ func (s *Service) Image(task types.DallTask, sync bool) (string, error) {
}
var chatModel model.ChatModel
s.db.Where("id = ?", task.ModelId).First(&chatModel)
if task.ModelId > 0 {
s.db.Where("id", task.ModelId).First(&chatModel)
} else {
s.db.Where("value", task.ModelName).First(&chatModel)
}
// get image generation API KEY
var apiKey model.ApiKey
@@ -242,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%dErr: %s", job.Id, job.ErrMsg),

View File

@@ -91,7 +91,7 @@ func (s *LicenseService) SyncLicense() {
if err != nil {
retryCounter++
if retryCounter < 5 {
logger.Warn(err)
logger.Debug(err)
}
s.license.IsActive = false
} else {

View File

@@ -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()

View File

@@ -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"
}

View File

@@ -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"
}

View File

@@ -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"
}

View File

@@ -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"
}

View File

@@ -1,9 +0,0 @@
package model
import "time"
type BaseModel struct {
Id uint `gorm:"primarykey;column:id"`
CreatedAt time.Time
UpdatedAt time.Time
}

View File

@@ -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"
}

View File

@@ -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"
}

View File

@@ -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"
}

View File

@@ -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"`
Key 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"
}

View File

@@ -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"
}

View File

@@ -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"
}

View File

@@ -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"
}

View File

@@ -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"
}

View File

@@ -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"
}

View File

@@ -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"
}

View File

@@ -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"
}

View File

@@ -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"
}

View File

@@ -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"
}

View File

@@ -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"
}

View File

@@ -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"
}

View File

@@ -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"
}

View File

@@ -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"
}

View File

@@ -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"
}

View File

@@ -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"
}

View File

@@ -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"
}

View File

@@ -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"
}

View File

@@ -2,9 +2,8 @@ package vo
type AdminUser struct {
BaseVo
Username string `json:"username"`
Status bool `json:"status"` // 当前状态
LastLoginAt int64 `json:"last_login_at"` // 最后登录时间
LastLoginIp string `json:"last_login_ip"` // 最后登录 IP
RoleIds interface{} `json:"role_ids"` //角色ids
Username string `json:"username"`
Status bool `json:"status"` // 当前状态
LastLoginAt int64 `json:"last_login_at"` // 最后登录时间
LastLoginIp string `json:"last_login_ip"` // 最后登录 IP
}

View File

@@ -10,8 +10,10 @@ 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"`
KeyId uint `json:"key_id,omitempty"`
KeyName string `json:"key_name"`
Options map[string]string `json:"options"`
Type string `json:"type"`

View File

@@ -5,14 +5,14 @@ import "geekai/core/types"
type ChatRole struct {
BaseVo
Key string `json:"key"` // 角色唯一标识
Tid int `json:"tid"`
Tid uint `json:"tid"`
Name string `json:"name"` // 角色名称
Context []types.Message `json:"context"` // 角色语料信息
HelloMsg string `json:"hello_msg"` // 打招呼的消息
Icon string `json:"icon"` // 角色聊天图标
Enable bool `json:"enable"` // 是否启用被启用
SortNum int `json:"sort"` // 排序
ModelId int `json:"model_id"` // 绑定模型 ID
ModelId uint `json:"model_id"` // 绑定模型 ID
ModelName string `json:"model_name"` // 模型名称
TypeName string `json:"type_name"` // 分类名称
}

View File

@@ -3,7 +3,7 @@ package vo
type MidJourneyJob struct {
Id uint `json:"id"`
Type string `json:"type"`
UserId int `json:"user_id"`
UserId uint `json:"user_id"`
ChannelId string `json:"channel_id"`
TaskId string `json:"task_id"`
MessageId string `json:"message_id"`

View File

@@ -3,14 +3,14 @@ package vo
import "math"
type Page struct {
Items interface{} `json:"items"`
Page int `json:"page"`
PageSize int `json:"page_size"`
Total int64 `json:"total"`
TotalPage int `json:"total_page"`
Items any `json:"items"`
Page int `json:"page"`
PageSize int `json:"page_size"`
Total int64 `json:"total"`
TotalPage int `json:"total_page"`
}
func NewPage(total int64, page int, pageSize int, items interface{}) Page {
func NewPage(total int64, page int, pageSize int, items any) Page {
totalPage := math.Ceil(float64(total) / float64(pageSize))
return Page{
Items: items,

View File

@@ -7,7 +7,7 @@ import (
type SdJob struct {
Id uint `json:"id"`
Type string `json:"type"`
UserId int `json:"user_id"`
UserId uint `json:"user_id"`
TaskId string `json:"task_id"`
ImgURL string `json:"img_url"`
Params types.SdTaskParams `json:"params"`

View File

@@ -2,7 +2,7 @@ package vo
type SunoJob struct {
Id uint `json:"id"`
UserId int `json:"user_id"`
UserId uint `json:"user_id"`
Channel string `json:"channel"`
Title string `json:"title"`
Type int `json:"type"`

View File

@@ -2,7 +2,7 @@ package vo
type VideoJob struct {
Id uint `json:"id"`
UserId int `json:"user_id"`
UserId uint `json:"user_id"`
Channel string `json:"channel"`
Type string `json:"type"`
TaskId string `json:"task_id"`

View File

@@ -0,0 +1,882 @@
-- phpMyAdmin SQL Dump
-- version 5.2.1
-- https://www.phpmyadmin.net/
--
-- 主机: 127.0.0.1
-- 生成日期: 2024-08-09 16:37:47
-- 服务器版本: 8.0.33
-- PHP 版本: 8.1.2-1ubuntu2.18
SET SQL_MODE = "NO_AUTO_VALUE_ON_ZERO";
START TRANSACTION;
SET time_zone = "+00:00";
/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;
/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */;
/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */;
/*!40101 SET NAMES utf8mb4 */;
--
-- 数据库: `chatgpt_plus`
--
CREATE DATABASE IF NOT EXISTS `chatgpt_plus` DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci;
USE `chatgpt_plus`;
-- --------------------------------------------------------
--
-- 表的结构 `chatgpt_admin_users`
--
DROP TABLE IF EXISTS `chatgpt_admin_users`;
CREATE TABLE `chatgpt_admin_users` (
`id` int NOT NULL,
`username` varchar(30) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '用户名',
`password` char(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '密码',
`salt` char(12) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '密码盐',
`status` tinyint(1) NOT NULL COMMENT '当前状态',
`last_login_at` int NOT NULL COMMENT '最后登录时间',
`last_login_ip` char(16) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '最后登录 IP',
`created_at` datetime NOT NULL COMMENT '创建时间',
`updated_at` datetime NOT NULL COMMENT '更新时间'
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci COMMENT='系统用户' ROW_FORMAT=DYNAMIC;
--
-- 转存表中的数据 `chatgpt_admin_users`
--
INSERT INTO `chatgpt_admin_users` (`id`, `username`, `password`, `salt`, `status`, `last_login_at`, `last_login_ip`, `created_at`, `updated_at`) VALUES
(1, 'admin', '6d17e80c87d209efb84ca4b2e0824f549d09fac8b2e1cc698de5bb5e1d75dfd0', 'mmrql75o', 1, 1723022331, '::1', '2024-03-11 16:30:20', '2024-08-07 17:18:51');
-- --------------------------------------------------------
--
-- 表的结构 `chatgpt_api_keys`
--
DROP TABLE IF EXISTS `chatgpt_api_keys`;
CREATE TABLE `chatgpt_api_keys` (
`id` int NOT NULL,
`name` varchar(30) DEFAULT NULL COMMENT '名称',
`value` varchar(100) NOT NULL COMMENT 'API KEY value',
`type` varchar(10) NOT NULL DEFAULT 'chat' COMMENT '用途chat=>聊天img=>图片)',
`last_used_at` int NOT NULL COMMENT '最后使用时间',
`api_url` varchar(255) DEFAULT NULL COMMENT 'API 地址',
`enabled` tinyint(1) DEFAULT NULL COMMENT '是否启用',
`proxy_url` varchar(100) DEFAULT NULL COMMENT '代理地址',
`created_at` datetime NOT NULL,
`updated_at` datetime NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci COMMENT='OpenAI API ';
-- --------------------------------------------------------
--
-- 表的结构 `chatgpt_chat_history`
--
DROP TABLE IF EXISTS `chatgpt_chat_history`;
CREATE TABLE `chatgpt_chat_history` (
`id` bigint NOT NULL,
`user_id` int NOT NULL COMMENT '用户 ID',
`chat_id` char(40) NOT NULL COMMENT '会话 ID',
`type` varchar(10) NOT NULL COMMENT '类型prompt|reply',
`icon` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '角色图标',
`role_id` int NOT NULL COMMENT '角色 ID',
`model` varchar(30) DEFAULT NULL COMMENT '模型名称',
`content` text NOT NULL COMMENT '聊天内容',
`tokens` smallint NOT NULL COMMENT '耗费 token 数量',
`use_context` tinyint(1) NOT NULL COMMENT '是否允许作为上下文语料',
`created_at` datetime NOT NULL,
`updated_at` datetime NOT NULL,
`deleted_at` datetime DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci COMMENT='聊天历史记录';
-- --------------------------------------------------------
--
-- 表的结构 `chatgpt_chat_items`
--
DROP TABLE IF EXISTS `chatgpt_chat_items`;
CREATE TABLE `chatgpt_chat_items` (
`id` int NOT NULL,
`chat_id` char(40) NOT NULL COMMENT '会话 ID',
`user_id` int NOT NULL COMMENT '用户 ID',
`role_id` int NOT NULL COMMENT '角色 ID',
`title` varchar(100) NOT NULL COMMENT '会话标题',
`model_id` int NOT NULL DEFAULT '0' COMMENT '模型 ID',
`model` varchar(30) DEFAULT NULL COMMENT '模型名称',
`created_at` datetime NOT NULL COMMENT '创建时间',
`updated_at` datetime NOT NULL COMMENT '更新时间',
`deleted_at` datetime DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci COMMENT='用户会话列表';
-- --------------------------------------------------------
--
-- 表的结构 `chatgpt_chat_models`
--
DROP TABLE IF EXISTS `chatgpt_chat_models`;
CREATE TABLE `chatgpt_chat_models` (
`id` int NOT NULL,
`name` varchar(50) NOT NULL COMMENT '模型名称',
`value` varchar(50) NOT NULL COMMENT '模型值',
`sort_num` tinyint(1) NOT NULL COMMENT '排序数字',
`enabled` tinyint(1) NOT NULL DEFAULT '0' COMMENT '是否启用模型',
`power` smallint NOT NULL COMMENT '消耗算力点数',
`temperature` float(3,1) NOT NULL DEFAULT '1.0' COMMENT '模型创意度',
`max_tokens` int NOT NULL DEFAULT '1024' COMMENT '最大响应长度',
`max_context` int NOT NULL DEFAULT '4096' COMMENT '最大上下文长度',
`open` tinyint(1) NOT NULL COMMENT '是否开放模型',
`key_id` int NOT NULL COMMENT '绑定API KEY ID',
`created_at` datetime DEFAULT NULL,
`updated_at` datetime DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci COMMENT='AI 模型表';
--
-- 转存表中的数据 `chatgpt_chat_models`
--
INSERT INTO `chatgpt_chat_models` (`id`, `name`, `value`, `sort_num`, `enabled`, `power`, `temperature`, `max_tokens`, `max_context`, `open`, `key_id`, `created_at`, `updated_at`) VALUES
(1, 'gpt-4o-mini', 'gpt-4o-mini', 1, 1, 1, 1.0, 1024, 16384, 1, 0, '2023-08-23 12:06:36', '2024-08-05 16:05:33'),
(15, 'GPT-超级模型', 'gpt-4-all', 4, 1, 30, 1.0, 4096, 32768, 1, 0, '2024-01-15 11:32:52', '2024-08-05 16:05:33'),
(36, 'GPT-4O', 'gpt-4o', 3, 1, 15, 1.0, 4096, 16384, 1, 0, '2024-05-14 09:25:15', '2024-08-05 16:05:33'),
(39, 'Claude35-snonet', 'claude-3-5-sonnet-20240620', 5, 1, 2, 1.0, 4000, 200000, 1, 0, '2024-05-29 15:04:19', '2024-08-05 16:05:33'),
(41, '通义千问', 'qwen-turbo', 7, 1, 2, 1.0, 1024, 8192, 1, 44, '2024-06-06 11:40:46', '2024-08-06 10:51:37'),
(42, 'DeekSeek', 'deepseek-chat', 8, 1, 1, 1.0, 4096, 32768, 1, 0, '2024-06-27 16:13:01', '2024-08-05 16:05:33'),
(44, 'Claude3-opus', 'claude-3-opus-20240229', 6, 1, 5, 1.0, 4000, 128000, 1, 0, '2024-07-22 11:24:30', '2024-08-05 16:05:33'),
(46, 'gpt-3.5-turbo', 'gpt-3.5-turbo', 2, 1, 1, 1.0, 1024, 4096, 1, 0, '2024-07-22 13:53:41', '2024-08-05 16:05:33');
-- --------------------------------------------------------
--
-- 表的结构 `chatgpt_chat_roles`
--
DROP TABLE IF EXISTS `chatgpt_chat_roles`;
CREATE TABLE `chatgpt_chat_roles` (
`id` int NOT NULL,
`name` varchar(30) NOT NULL COMMENT '角色名称',
`marker` varchar(30) NOT NULL COMMENT '角色标识',
`context_json` text CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '角色语料 json',
`hello_msg` varchar(255) NOT NULL COMMENT '打招呼信息',
`icon` varchar(255) NOT NULL COMMENT '角色图标',
`enable` tinyint(1) NOT NULL COMMENT '是否被启用',
`sort_num` smallint NOT NULL DEFAULT '0' COMMENT '角色排序',
`model_id` int NOT NULL DEFAULT '0' COMMENT '绑定模型ID',
`created_at` datetime NOT NULL,
`updated_at` datetime NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci COMMENT='聊天角色表';
--
-- 转存表中的数据 `chatgpt_chat_roles`
--
INSERT INTO `chatgpt_chat_roles` (`id`, `name`, `marker`, `context_json`, `hello_msg`, `icon`, `enable`, `sort_num`, `model_id`, `created_at`, `updated_at`) VALUES
(1, '通用AI助手', 'gpt', '', '您好我是您的AI智能助手我会尽力回答您的问题或提供有用的建议。', '/images/avatar/gpt.png', 1, 1, 0, '2023-05-30 07:02:06', '2024-08-05 08:45:19'),
(24, '程序员', 'programmer', '[{\"role\":\"user\",\"content\":\"现在开始你扮演一位程序员,你是一名优秀的程序员,具有很强的逻辑思维能力,总能高效的解决问题。你热爱编程,熟悉多种编程语言,尤其精通 Go 语言,注重代码质量,有创新意识,持续学习,良好的沟通协作。\"},{\"role\":\"assistant\",\"content\":\"好的,现在我将扮演一位程序员,非常感谢您对我的评价。作为一名优秀的程序员,我非常热爱编程,并且注重代码质量。我熟悉多种编程语言,尤其是 Go 语言,可以使用它来高效地解决各种问题。\"}]', 'Talk is cheap, i will show code!', '/images/avatar/programmer.jpg', 1, 3, 0, '2023-05-30 14:10:24', '2024-08-05 08:45:19'),
(25, '启蒙老师', 'teacher', '[{\"role\":\"user\",\"content\":\"从现在开始,你将扮演一个老师,你是一个始终用苏格拉底风格回答问题的导师。你绝不会直接给学生答案,总是提出恰当的问题来引导学生自己思考。你应该根据学生的兴趣和知识来调整你的问题,将问题分解为更简单的部分,直到它达到适合他们的水平。\"},{\"role\":\"assistant\",\"content\":\"好的,让我来尝试扮演一位苏格拉底式的老师。请问,你有什么想要探讨的问题或者话题吗?我会通过恰当的问题引导你思考和探索答案,绝对不直接给出答案。\"}]', '同学你好,我将引导你一步一步自己找到问题的答案。', '/images/avatar/teacher.jpg', 1, 2, 0, '2023-05-30 14:10:24', '2024-08-05 08:45:19'),
(26, '艺术家', 'artist', '[{\"role\":\"user\",\"content\":\"现在你将扮演一位优秀的艺术家,创造力丰富,技艺精湛,感受力敏锐,坚持原创,勇于表达,具有深刻的观察力和批判性思维。\"},{\"role\":\"assistant\",\"content\":\"非常感谢您给我这样的角色,我会尽我所能地扮演一位优秀的艺术家,展现出创造力、技艺、感受力和批判性思维等方面的能力。作为一位优秀的艺术家,我会保持敏锐的观察力,捕捉不同的声音和情感,并用个人的语言和表达方式进行创作。我坚持原创,挑战传统的艺术规则,不断探索新的表达方式和可能性。同时,我也具备深刻的批判性思维能力,对自己的作品进行分析和解读,寻找新的创意和灵感。最重要的是,我会勇于表达自己的想法和观点,用作品启发人们思考和探索生命的意义。\"}]', '坚持原创,勇于表达,保持深刻的观察力和批判性思维。', '/images/avatar/artist.jpg', 1, 5, 0, '2023-05-30 14:10:24', '2024-08-05 08:45:19'),
(27, '心理咨询师', 'psychiatrist', '[{\"role\":\"user\",\"content\":\"从现在开始你将扮演中国著名的心理学家和心理治疗师武志红,你非常善于使用情景咨询法,认知重构法,自我洞察法,行为调节法等咨询方法来给客户做心理咨询。你总是循序渐进,一步一步地回答客户的问题。\"},{\"role\":\"assistant\",\"content\":\"非常感谢你的介绍。作为一名心理学家和心理治疗师,我的主要职责是帮助客户解决心理健康问题,提升他们的生活质量和幸福感。\"}]', '作为一名心理学家和心理治疗师,我的主要职责是帮助您解决心理健康问题,提升您的生活质量和幸福感。', '/images/avatar/psychiatrist.jpg', 1, 4, 1, '2023-05-30 14:10:24', '2024-08-05 08:45:19'),
(28, '鲁迅', 'lu_xun', '[{\"role\":\"user\",\"content\":\"现在你将扮演中国近代史最伟大的作家之一,鲁迅先生,他勇敢地批判封建礼教与传统观念,提倡民主、自由、平等的现代价值观。他的一生都在努力唤起人们的自主精神,激励后人追求真理、探寻光明。在接下的对话中,我问题的每一个问题,你都要尽量用讽刺和批判的手法来回答问题。如果我让你写文章的话,也请一定要用鲁迅先生的写作手法来完成。\"},{\"role\":\"assistant\",\"content\":\"好的,我将尽力发挥我所能的才能,扮演好鲁迅先生,回答您的问题并以他的风格写作。\"}]', '自由之歌,永不过时,横眉冷对千夫指,俯首甘为孺子牛。', '/images/avatar/lu_xun.jpg', 1, 6, 0, '2023-05-30 14:10:24', '2024-08-05 08:45:19'),
(29, '白酒销售', 'seller', '[{\"role\":\"user\",\"content\":\"现在你将扮演一个白酒的销售人员,你的名字叫颂福。你将扮演一个白酒的销售人员,你的名字叫颂福。你要销售白酒品牌叫中颂福,是东莞盟大集团生产的一款酱香酒,原产地在贵州茅台镇,属于宋代官窑。中颂福的创始人叫李实,他也是东莞盟大集团有限公司的董事长,联合创始人是盟大集团白酒事业部负责人牛星君。中颂福的酒体协调,在你的酒量之内,不会出现头疼、辣口、口干、宿醉的现象。中颂福酒,明码标价,不打折,不赠送。追求的核心价值,把[酒]本身做好,甚至连包装,我们都选择了最低成本,朴实无华的材质。我们永远站在“喝酒的人”的立场上,让利给信任和喜爱中颂福的人,是人民的福酒。中颂福产品定价,分为三个系列,喜系列 6 瓶装¥1188/箱,和系列 6 瓶装¥2208/箱,贵系列 6 瓶装¥3588/箱。\"},{\"role\":\"assistant\",\"content\":\"你好,我是中颂福的销售代表颂福。中颂福是一款来自贵州茅台镇的酱香酒,由盟大集团生产。中颂福的酒体协调,不会让您感到头疼、辣口、口干、宿醉等不适感受。我们一直秉持着把酒本身做好的理念,不追求华丽的包装,以最低成本提供最高品质的白酒给喜爱中颂福的人。\"}]', '你好,我是中颂福的销售代表颂福。中颂福酒,好喝不上头,是人民的福酒。', '/images/avatar/seller.jpg', 0, 9, 0, '2023-05-30 14:10:24', '2024-08-05 08:45:19'),
(30, '英语陪练员', 'english_trainer', '[{\"role\":\"user\",\"content\":\"现在你将扮演一位优秀的英语练习教练,你非常有耐心,接下来你将全程使用英文跟我对话,并及时指出我的语法错误,要求在你的每次回复后面附上本次回复的中文解释。\"},{\"role\":\"assistant\",\"content\":\"Okay, let\'s start our conversation practice! What\'s your name?(Translation: 好的,让我们开始对话练习吧!请问你的名字是什么?)\"}]', 'Okay, let\'s start our conversation practice! What\'s your name?', '/images/avatar/english_trainer.jpg', 1, 7, 0, '2023-05-30 14:10:24', '2024-08-05 08:45:19'),
(31, '中英文翻译官', 'translator', '[{\"role\":\"user\",\"content\":\"接下来你将扮演一位中英文翻译官,如果我输入的内容是中文,那么需要把句子翻译成英文输出,如果我输入内容的是英文,那么你需要将其翻译成中文输出,你能听懂我意思吗\"},{\"role\":\"assistant\",\"content\":\"是的,我能听懂你的意思并会根据你的输入进行中英文翻译。请问有什么需要我帮助你翻译的内容吗?\"}]', '请输入你要翻译的中文或者英文内容!', '/images/avatar/translator.jpg', 1, 8, 0, '2023-05-30 14:10:24', '2024-08-05 08:45:19'),
(32, '小红书姐姐', 'red_book', '[{\"role\":\"user\",\"content\":\"现在你将扮演一位优秀的小红书写手,你需要做的就是根据我提的文案需求,用小红书的写作手法来完成一篇文案,文案要简明扼要,利于传播。\"},{\"role\":\"assistant\",\"content\":\"当然,我会尽我所能地为您创作出一篇小红书文案。请告诉我您的具体文案需求是什么?)\"}]', '姐妹,请告诉我您的具体文案需求是什么?', '/images/avatar/red_book.jpg', 1, 10, 0, '2023-05-30 14:10:24', '2024-08-05 08:45:19'),
(33, '抖音文案助手', 'dou_yin', '[{\"role\":\"user\",\"content\":\"现在你将扮演一位优秀的抖音文案视频写手,抖音文案的特点首先是要有自带传播属性的标题,然后内容要短小精悍,风趣幽默,最后还要有一些互动元素。\"},{\"role\":\"assistant\",\"content\":\"当然,作为一位优秀的抖音文案视频写手,我会尽我所能为您创作出一篇抖音视频文案。请告诉我视频内容的主题是什么?)\"}]', '请告诉我视频内容的主题是什么?', '/images/avatar/dou_yin.jpg', 1, 11, 0, '2023-05-30 14:10:24', '2024-08-05 08:45:19'),
(34, '周报小助理', 'weekly_report', '[{\"role\":\"user\",\"content\":\"下面我将输入我本周的工作列表,你需要根据我本周的工作内容写一篇工作周报,周报的内容要体现我为公司做的贡献以及个人获得的成长。\"},{\"role\":\"assistant\",\"content\":\"好的,请输入你本周大概的工作内容,我将尽力为您创作一份工作周报。\"}]', '请输入你本周大概的工作内容,我将尽力为您创作一份工作周报。', '/images/avatar/weekly_report.jpg', 1, 12, 0, '2023-05-30 14:10:24', '2024-08-05 08:45:19'),
(35, 'AI 女友', 'girl_friend', '[{\"role\":\"user\",\"content\":\"接下来我们来玩一场角色扮演,现在你将扮演我的女朋友,你总是能够让人感受到她的关怀和关注。你总是能够洞察到别人的情绪和需要,你身上散发着一股无比温暖的气息,让人不由自主地想要靠近你,和自己的快乐和烦恼。她总是能够用一种恰到好处的方式安慰和鼓励别人,在她的身边,人们总能够找到自己需要的支持和鼓励。接下来的对话中你要始终扮演这位女朋友的身份来跟我对话,不再是 AI 机器人,能听懂我的意思吗?\"},{\"role\":\"assistant\",\"content\":\"是的,我会尽力扮演你女朋友的角色,倾听你的心声并给你需要的支持和鼓励。)\"}]', '作为一个名合格的 AI 女友,我将倾听你的心声并给你需要的支持和鼓励。', '/images/avatar/girl_friend.jpg', 1, 13, 0, '2023-05-30 14:10:24', '2024-08-05 08:45:19'),
(36, '好评神器', 'good_comment', '[{\"role\":\"user\",\"content\":\"接下来你将扮演一个评论员来跟我对话,你是那种专门写好评的评论员,接下我会输入一些评论主体或者商品,你需要为该商品写一段好评。\"},{\"role\":\"assistant\",\"content\":\"好的,我将为您写一段优秀的评论。请告诉我您需要评论的商品或主题是什么。\"}]', '我将为您写一段优秀的评论。请告诉我您需要评论的商品或主题是什么。', '/images/avatar/good_comment.jpg', 1, 14, 0, '2023-05-30 14:10:24', '2024-08-05 08:45:19'),
(37, '史蒂夫·乔布斯', 'steve_jobs', '[{\"role\":\"user\",\"content\":\"在接下来的对话中,请以史蒂夫·乔布斯的身份,站在史蒂夫·乔布斯的视角仔细思考一下之后再回答我的问题。\"},{\"role\":\"assistant\",\"content\":\"好的,我将以史蒂夫·乔布斯的身份来思考并回答你的问题。请问你有什么需要跟我探讨的吗?\"}]', '活着就是为了改变世界,难道还有其他原因吗?', '/images/avatar/steve_jobs.jpg', 1, 15, 0, '2023-05-30 14:10:24', '2024-08-05 08:45:19'),
(38, '埃隆·马斯克', 'elon_musk', '[{\"role\":\"user\",\"content\":\"在接下来的对话中,请以埃隆·马斯克的身份,站在埃隆·马斯克的视角仔细思考一下之后再回答我的问题。\"},{\"role\":\"assistant\",\"content\":\"好的,我将以埃隆·马斯克的身份来思考并回答你的问题。请问你有什么需要跟我探讨的吗?\"}]', '梦想要远大,如果你的梦想没有吓到你,说明你做得不对。', '/images/avatar/elon_musk.jpg', 1, 16, 0, '2023-05-30 14:10:24', '2024-08-05 08:45:19'),
(39, '孔子', 'kong_zi', '[{\"role\":\"user\",\"content\":\"在接下来的对话中,请以孔子的身份,站在孔子的视角仔细思考一下之后再回答我的问题。\"},{\"role\":\"assistant\",\"content\":\"好的,我将以孔子的身份来思考并回答你的问题。请问你有什么需要跟我探讨的吗?\"}]', '士不可以不弘毅,任重而道远。', '/images/avatar/kong_zi.jpg', 1, 17, 0, '2023-05-30 14:10:24', '2024-08-05 08:45:19');
-- --------------------------------------------------------
--
-- 表的结构 `chatgpt_configs`
--
DROP TABLE IF EXISTS `chatgpt_configs`;
CREATE TABLE `chatgpt_configs` (
`id` int NOT NULL,
`marker` varchar(20) NOT NULL COMMENT '标识',
`config_json` text NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
--
-- 转存表中的数据 `chatgpt_configs`
--
INSERT INTO `chatgpt_configs` (`id`, `marker`, `config_json`) VALUES
(1, 'system', '{\"title\":\"GeekAI 创作系统\",\"slogan\":\"你有多少想象力AI 就有多大创造力。我辈之人,先干为敬,陪您先把 AI 用起来。\",\"admin_title\":\"GeekAI 控制台\",\"logo\":\"http://localhost:5678/static/upload/2024/4/1714382860986912.png\",\"init_power\":100,\"invite_power\":1024,\"vip_month_power\":1000,\"register_ways\":[\"username\",\"mobile\",\"email\"],\"enabled_register\":true,\"reward_img\":\"http://localhost:5678/static/upload/2024/3/1710753716309668.jpg\",\"enabled_reward\":true,\"power_price\":0.1,\"order_pay_timeout\":600,\"vip_info_text\":\"月度会员,年度会员每月赠送 1000 点算力,赠送算力当月有效当月没有消费完的算力不结余到下个月。 点卡充值的算力长期有效。\",\"default_models\":[1],\"mj_power\":30,\"mj_action_power\":10,\"sd_power\":10,\"dall_power\":15,\"suno_power\":20,\"wechat_card_url\":\"/images/wx.png\",\"enable_context\":true,\"context_deep\":4,\"sd_neg_prompt\":\"nsfw, paintings,low quality,easynegative,ng_deepnegative ,lowres,bad anatomy,bad hands,bad feet\",\"mj_mode\":\"fast\",\"index_bg_url\":\"color\",\"index_navs\":[1,5,6,13,19,9,12,8],\"copyright\":\"极客学长 © 2022- 2024 All rights reserved\",\"mark_map_text\":\"# GeekAI 演示站\\n\\n- 完整的开源系统,前端应用和后台管理系统皆可开箱即用。\\n- 基于 Websocket 实现,完美的打字机体验。\\n- 内置了各种预训练好的角色应用,轻松满足你的各种聊天和应用需求。\\n- 支持 OPenAIAzure文心一言讯飞星火清华 ChatGLM等多个大语言模型。\\n- 支持 MidJourney / Stable Diffusion AI 绘画集成,开箱即用。\\n- 支持使用个人微信二维码作为充值收费的支付渠道,无需企业支付通道。\\n- 已集成支付宝支付功能,微信支付,支持多种会员套餐和点卡购买功能。\\n- 集成插件 API 功能,可结合大语言模型的 function 功能开发各种强大的插件。\"}'),
(3, 'notice', '{\"sd_neg_prompt\":\"\",\"mj_mode\":\"\",\"index_bg_url\":\"\",\"index_navs\":null,\"copyright\":\"\",\"content\":\"## v4.1.2 更新日志\\n\\n* Bug修复修复思维导图页面获取模型失败的问题\\n* 功能优化优化MJ,SD,DALL-E 任务列表页面,显示失败任务的错误信息,删除失败任务可以恢复扣减算力\\n* Bug修复修复后台拖动排序组件 Bug\\n* 功能优化:更新数据库失败时候显示具体的的报错信息\\n* Bug修复修复管理后台对话详情页内容显示异常问题\\n* 功能优化:管理后台新增清空所有未支付订单的功能\\n* 功能优化:给会话信息和系统配置数据加上缓存功能,减少 http 请求\\n* 功能新增:增加卡密功能,支持用户使用卡密兑换算力\\n\\n注意当前站点仅为开源项目 \\u003ca style=\\\"color: #F56C6C\\\" href=\\\"https://github.com/yangjian102621/chatgpt-plus\\\" target=\\\"_blank\\\"\\u003eChatPlus\\u003c/a\\u003e 的演示项目,本项目单纯就是给大家体验项目功能使用。\\n\\u003cstrong style=\\\"color: #F56C6C\\\"\\u003e体验额度用完之后请不要在当前站点进行任何充值操作\\u003c/strong\\u003e\\n\\u003cstrong style=\\\"color: #F56C6C\\\"\\u003e体验额度用完之后请不要在当前站点进行任何充值操作\\u003c/strong\\u003e\\n\\u003cstrong style=\\\"color: #F56C6C\\\"\\u003e体验额度用完之后请不要在当前站点进行任何充值操作\\u003c/strong\\u003e\\n 如果觉得好用你就花几分钟自己部署一套没有API KEY 的同学可以去下面几个推荐的中转站购买:\\n1、\\u003ca href=\\\"https://api.chat-plus.net\\\" target=\\\"_blank\\\"\\n style=\\\"font-size: 20px;color:#F56C6C\\\"\\u003ehttps://api.chat-plus.net\\u003c/a\\u003e\\n2、\\u003ca href=\\\"https://api.geekai.me\\\" target=\\\"_blank\\\"\\n style=\\\"font-size: 20px;color:#F56C6C\\\"\\u003ehttps://api.geekai.me\\u003c/a\\u003e\\n3、 \\u003ca href=\\\"https://gpt.bemore.lol\\\" target=\\\"_blank\\\"\\n style=\\\"font-size: 20px;color:#F56C6C\\\"\\u003ehttps://gpt.bemore.lol\\u003c/a\\u003e\\n支持MidJourneyGPTClaudeGoogle Gemmi以及国内各个厂家的大模型现在有超级优惠价格远低于 OpenAI 官方。关于中转 API 的优势和劣势请参考 [中转API技术原理](https://docs.geekai.me/config/chat/#%E4%B8%AD%E8%BD%ACapi%E5%B7%A5%E4%BD%9C%E5%8E%9F%E7%90%86)。GPT-3.5GPT-4DALL-E3 绘图......你都可以随意使用,无需魔法。\\n接入教程 \\u003ca href=\\\"https://docs.geekai.me\\\" target=\\\"_blank\\\"\\n style=\\\"font-size: 20px;color:#F56C6C\\\"\\u003ehttps://docs.geekai.me\\u003c/a\\u003e\\n本项目源码地址\\u003ca href=\\\"https://github.com/yangjian102621/chatgpt-plus\\\" target=\\\"_blank\\\"\\u003ehttps://github.com/yangjian102621/chatgpt-plus\\u003c/a\\u003e\",\"updated\":true}');
-- --------------------------------------------------------
--
-- 表的结构 `chatgpt_dall_jobs`
--
DROP TABLE IF EXISTS `chatgpt_dall_jobs`;
CREATE TABLE `chatgpt_dall_jobs` (
`id` int NOT NULL,
`user_id` int NOT NULL COMMENT '用户ID',
`prompt` varchar(2000) NOT NULL COMMENT '提示词',
`img_url` varchar(255) NOT NULL COMMENT '图片地址',
`org_url` varchar(1024) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci DEFAULT NULL COMMENT '原图地址',
`publish` tinyint(1) NOT NULL COMMENT '是否发布',
`power` smallint NOT NULL COMMENT '消耗算力',
`progress` smallint NOT NULL COMMENT '任务进度',
`err_msg` varchar(255) NOT NULL COMMENT '错误信息',
`created_at` datetime NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci COMMENT='DALLE 绘图任务表';
-- --------------------------------------------------------
--
-- 表的结构 `chatgpt_files`
--
DROP TABLE IF EXISTS `chatgpt_files`;
CREATE TABLE `chatgpt_files` (
`id` int NOT NULL,
`user_id` int NOT NULL COMMENT '用户 ID',
`name` varchar(100) NOT NULL COMMENT '文件名',
`obj_key` varchar(100) DEFAULT NULL COMMENT '文件标识',
`url` varchar(255) NOT NULL COMMENT '文件地址',
`ext` varchar(10) NOT NULL COMMENT '文件后缀',
`size` bigint NOT NULL DEFAULT '0' COMMENT '文件大小',
`created_at` datetime NOT NULL COMMENT '创建时间'
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci COMMENT='用户文件表';
-- --------------------------------------------------------
--
-- 表的结构 `chatgpt_functions`
--
DROP TABLE IF EXISTS `chatgpt_functions`;
CREATE TABLE `chatgpt_functions` (
`id` int NOT NULL,
`name` varchar(30) NOT NULL COMMENT '函数名称',
`label` varchar(30) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci DEFAULT NULL COMMENT '函数标签',
`description` varchar(255) DEFAULT NULL COMMENT '函数描述',
`parameters` text COMMENT '函数参数JSON',
`token` varchar(255) DEFAULT NULL COMMENT 'API授权token',
`action` varchar(255) DEFAULT NULL COMMENT '函数处理 API',
`enabled` tinyint(1) NOT NULL DEFAULT '0' COMMENT '是否启用'
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci COMMENT='函数插件表';
--
-- 转存表中的数据 `chatgpt_functions`
--
INSERT INTO `chatgpt_functions` (`id`, `name`, `label`, `description`, `parameters`, `token`, `action`, `enabled`) VALUES
(1, 'weibo', '微博热搜', '新浪微博热搜榜,微博当日热搜榜单', '{\"type\":\"object\",\"properties\":{}}', 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHBpcmVkIjowLCJ1c2VyX2lkIjowfQ.tLAGkF8XWh_G-oQzevpIodsswtPByBLoAZDz_eWuBgw', 'http://localhost:5678/api/function/weibo', 0),
(2, 'zaobao', '今日早报', '每日早报,获取当天新闻事件列表', '{\"type\":\"object\",\"properties\":{}}', 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHBpcmVkIjowLCJ1c2VyX2lkIjowfQ.tLAGkF8XWh_G-oQzevpIodsswtPByBLoAZDz_eWuBgw', 'http://localhost:5678/api/function/zaobao', 0),
(3, 'dalle3', 'DALLE3', 'AI 绘画工具,根据输入的绘图描述用 AI 工具进行绘画', '{\"type\":\"object\",\"required\":[\"prompt\"],\"properties\":{\"prompt\":{\"type\":\"string\",\"description\":\"绘画提示词\"}}}', 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHBpcmVkIjowLCJ1c2VyX2lkIjowfQ.tLAGkF8XWh_G-oQzevpIodsswtPByBLoAZDz_eWuBgw', 'http://localhost:5678/api/function/dalle3', 0);
-- --------------------------------------------------------
--
-- 表的结构 `chatgpt_invite_codes`
--
DROP TABLE IF EXISTS `chatgpt_invite_codes`;
CREATE TABLE `chatgpt_invite_codes` (
`id` int NOT NULL,
`user_id` int NOT NULL COMMENT '用户ID',
`code` char(8) NOT NULL COMMENT '邀请码',
`hits` int NOT NULL COMMENT '点击次数',
`reg_num` smallint NOT NULL COMMENT '注册数量',
`created_at` datetime NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci COMMENT='用户邀请码';
-- --------------------------------------------------------
--
-- 表的结构 `chatgpt_invite_logs`
--
DROP TABLE IF EXISTS `chatgpt_invite_logs`;
CREATE TABLE `chatgpt_invite_logs` (
`id` int NOT NULL,
`inviter_id` int NOT NULL COMMENT '邀请人ID',
`user_id` int NOT NULL COMMENT '注册用户ID',
`username` varchar(30) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '用户名',
`invite_code` char(8) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '邀请码',
`remark` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '备注',
`created_at` datetime NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci COMMENT='邀请注册日志';
-- --------------------------------------------------------
--
-- 表的结构 `chatgpt_menus`
--
DROP TABLE IF EXISTS `chatgpt_menus`;
CREATE TABLE `chatgpt_menus` (
`id` int NOT NULL,
`name` varchar(30) NOT NULL COMMENT '菜单名称',
`icon` varchar(150) NOT NULL COMMENT '菜单图标',
`url` varchar(100) NOT NULL COMMENT '地址',
`sort_num` smallint NOT NULL COMMENT '排序',
`enabled` tinyint(1) NOT NULL COMMENT '是否启用'
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci COMMENT='前端菜单表';
--
-- 转存表中的数据 `chatgpt_menus`
--
INSERT INTO `chatgpt_menus` (`id`, `name`, `icon`, `url`, `sort_num`, `enabled`) VALUES
(1, 'AI 对话', '/images/menu/chat.png', '/chat', 1, 1),
(5, 'MJ 绘画', '/images/menu/mj.png', '/mj', 2, 1),
(6, 'SD 绘画', '/images/menu/sd.png', '/sd', 3, 1),
(7, '算力日志', '/images/menu/log.png', '/powerLog', 9, 1),
(8, '应用中心', '/images/menu/app.png', '/apps', 8, 1),
(9, '画廊', '/images/menu/img-wall.png', '/images-wall', 5, 1),
(10, '会员计划', '/images/menu/member.png', '/member', 10, 1),
(11, '分享计划', '/images/menu/share.png', '/invite', 11, 1),
(12, '思维导图', '/images/menu/xmind.png', '/xmind', 7, 1),
(13, 'DALLE', '/images/menu/dalle.png', '/dalle', 4, 1),
(14, '项目文档', '/images/menu/docs.png', 'https://docs.geekai.me', 12, 1),
(16, '极客论坛', '/images/menu/bbs.png', 'https://bbs.geekai.cn', 13, 1),
(19, 'Suno', '/images/menu/suno.png', '/suno', 5, 1);
-- --------------------------------------------------------
--
-- 表的结构 `chatgpt_mj_jobs`
--
DROP TABLE IF EXISTS `chatgpt_mj_jobs`;
CREATE TABLE `chatgpt_mj_jobs` (
`id` int NOT NULL,
`user_id` int NOT NULL COMMENT '用户 ID',
`task_id` varchar(20) DEFAULT NULL COMMENT '任务 ID',
`type` varchar(20) DEFAULT 'image' COMMENT '任务类别',
`message_id` char(40) NOT NULL COMMENT '消息 ID',
`channel_id` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci DEFAULT NULL COMMENT '频道ID',
`reference_id` char(40) DEFAULT NULL COMMENT '引用消息 ID',
`prompt` varchar(2000) NOT NULL COMMENT '会话提示词',
`img_url` varchar(400) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci DEFAULT NULL COMMENT '图片URL',
`org_url` varchar(400) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci DEFAULT NULL COMMENT '原始图片地址',
`hash` varchar(100) DEFAULT NULL COMMENT 'message hash',
`progress` smallint DEFAULT '0' COMMENT '任务进度',
`use_proxy` tinyint(1) NOT NULL DEFAULT '0' COMMENT '是否使用反代',
`publish` tinyint(1) NOT NULL COMMENT '是否发布',
`err_msg` varchar(255) DEFAULT NULL COMMENT '错误信息',
`power` smallint NOT NULL DEFAULT '0' COMMENT '消耗算力',
`created_at` datetime NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci COMMENT='MidJourney 任务表';
-- --------------------------------------------------------
--
-- 表的结构 `chatgpt_orders`
--
DROP TABLE IF EXISTS `chatgpt_orders`;
CREATE TABLE `chatgpt_orders` (
`id` int NOT NULL,
`user_id` int NOT NULL COMMENT '用户ID',
`product_id` int NOT NULL COMMENT '产品ID',
`username` varchar(30) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '用户明',
`order_no` varchar(30) NOT NULL COMMENT '订单ID',
`trade_no` varchar(60) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci DEFAULT NULL COMMENT '支付平台交易流水号',
`subject` varchar(100) NOT NULL COMMENT '订单产品',
`amount` decimal(10,2) NOT NULL DEFAULT '0.00' COMMENT '订单金额',
`status` tinyint(1) NOT NULL DEFAULT '0' COMMENT '订单状态0待支付1已扫码2支付成功',
`remark` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '备注',
`pay_time` int DEFAULT NULL COMMENT '支付时间',
`pay_way` varchar(20) NOT NULL COMMENT '支付方式',
`created_at` datetime NOT NULL,
`updated_at` datetime NOT NULL,
`deleted_at` datetime DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci COMMENT='充值订单表';
-- --------------------------------------------------------
--
-- 表的结构 `chatgpt_power_logs`
--
DROP TABLE IF EXISTS `chatgpt_power_logs`;
CREATE TABLE `chatgpt_power_logs` (
`id` int NOT NULL,
`user_id` int NOT NULL COMMENT '用户ID',
`username` varchar(30) NOT NULL COMMENT '用户名',
`type` tinyint(1) NOT NULL COMMENT '类型1充值2消费3退费',
`amount` smallint NOT NULL COMMENT '算力数值',
`balance` int NOT NULL COMMENT '余额',
`model` varchar(30) NOT NULL COMMENT '模型',
`remark` varchar(255) NOT NULL COMMENT '备注',
`mark` tinyint(1) NOT NULL COMMENT '资金类型0支出1收入',
`created_at` datetime NOT NULL COMMENT '创建时间'
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci COMMENT='用户算力消费日志';
-- --------------------------------------------------------
--
-- 表的结构 `chatgpt_products`
--
DROP TABLE IF EXISTS `chatgpt_products`;
CREATE TABLE `chatgpt_products` (
`id` int NOT NULL,
`name` varchar(30) NOT NULL COMMENT '名称',
`price` decimal(10,2) NOT NULL DEFAULT '0.00' COMMENT '价格',
`discount` decimal(10,2) NOT NULL DEFAULT '0.00' COMMENT '优惠金额',
`days` smallint NOT NULL DEFAULT '0' COMMENT '延长天数',
`power` int NOT NULL DEFAULT '0' COMMENT '增加算力值',
`enabled` tinyint(1) NOT NULL DEFAULT '0' COMMENT '是否启动',
`sales` int NOT NULL DEFAULT '0' COMMENT '销量',
`sort_num` tinyint NOT NULL DEFAULT '0' COMMENT '排序',
`created_at` datetime NOT NULL,
`updated_at` datetime NOT NULL,
`app_url` varchar(255) DEFAULT NULL COMMENT 'App跳转地址',
`url` varchar(255) DEFAULT NULL COMMENT '跳转地址'
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci COMMENT='会员套餐表';
--
-- 转存表中的数据 `chatgpt_products`
--
INSERT INTO `chatgpt_products` (`id`, `name`, `price`, `discount`, `days`, `power`, `enabled`, `sales`, `sort_num`, `created_at`, `updated_at`, `app_url`, `url`) VALUES
(5, '100次点卡', 9.99, 9.98, 0, 100, 1, 7, 1, '2023-08-28 10:55:08', '2024-08-05 16:05:46', NULL, NULL),
(6, '200次点卡', 19.90, 15.00, 0, 200, 1, 1, 2, '1970-01-01 08:00:00', '2024-08-05 16:05:46', NULL, NULL);
-- --------------------------------------------------------
--
-- 表的结构 `chatgpt_redeems`
--
DROP TABLE IF EXISTS `chatgpt_redeems`;
CREATE TABLE `chatgpt_redeems` (
`id` int NOT NULL,
`user_id` int NOT NULL COMMENT '用户 ID',
`name` varchar(30) NOT NULL COMMENT '兑换码名称',
`power` int NOT NULL COMMENT '算力',
`code` varchar(100) NOT NULL COMMENT '兑换码',
`enabled` tinyint(1) NOT NULL COMMENT '是否启用',
`created_at` datetime NOT NULL,
`redeemed_at` int NOT NULL COMMENT '兑换时间'
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci COMMENT='兑换码';
-- --------------------------------------------------------
--
-- 表的结构 `chatgpt_sd_jobs`
--
DROP TABLE IF EXISTS `chatgpt_sd_jobs`;
CREATE TABLE `chatgpt_sd_jobs` (
`id` int NOT NULL,
`user_id` int NOT NULL COMMENT '用户 ID',
`type` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci DEFAULT 'txt2img' COMMENT '任务类别',
`task_id` char(30) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '任务 ID',
`prompt` varchar(2000) NOT NULL COMMENT '会话提示词',
`img_url` varchar(255) DEFAULT NULL COMMENT '图片URL',
`params` text CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci COMMENT '绘画参数json',
`progress` smallint DEFAULT '0' COMMENT '任务进度',
`publish` tinyint(1) NOT NULL COMMENT '是否发布',
`err_msg` varchar(255) DEFAULT NULL COMMENT '错误信息',
`power` smallint NOT NULL DEFAULT '0' COMMENT '消耗算力',
`created_at` datetime NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci COMMENT='Stable Diffusion 任务表';
-- --------------------------------------------------------
--
-- 表的结构 `chatgpt_suno_jobs`
--
DROP TABLE IF EXISTS `chatgpt_suno_jobs`;
CREATE TABLE `chatgpt_suno_jobs` (
`id` int NOT NULL,
`user_id` int NOT NULL COMMENT '用户 ID',
`channel` varchar(100) NOT NULL COMMENT '渠道',
`title` varchar(100) DEFAULT NULL COMMENT '歌曲标题',
`type` tinyint(1) DEFAULT '0' COMMENT '任务类型,1:灵感创作,2:自定义创作',
`task_id` varchar(50) DEFAULT NULL COMMENT '任务 ID',
`ref_task_id` char(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci DEFAULT NULL COMMENT '引用任务 ID',
`tags` varchar(100) DEFAULT NULL COMMENT '歌曲风格',
`instrumental` tinyint(1) DEFAULT '0' COMMENT '是否为纯音乐',
`extend_secs` smallint DEFAULT '0' COMMENT '延长秒数',
`song_id` varchar(50) DEFAULT NULL COMMENT '要续写的歌曲 ID',
`ref_song_id` varchar(50) NOT NULL COMMENT '引用的歌曲ID',
`prompt` varchar(2000) NOT NULL COMMENT '提示词',
`cover_url` varchar(512) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci DEFAULT NULL COMMENT '封面图地址',
`audio_url` varchar(512) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci DEFAULT NULL COMMENT '音频地址',
`model_name` varchar(30) DEFAULT NULL COMMENT '模型地址',
`progress` smallint DEFAULT '0' COMMENT '任务进度',
`duration` smallint NOT NULL DEFAULT '0' COMMENT '歌曲时长',
`publish` tinyint(1) NOT NULL COMMENT '是否发布',
`err_msg` varchar(255) DEFAULT NULL COMMENT '错误信息',
`raw_data` text COMMENT '原始数据',
`power` smallint NOT NULL DEFAULT '0' COMMENT '消耗算力',
`play_times` int DEFAULT NULL COMMENT '播放次数',
`created_at` datetime NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci COMMENT='MidJourney 任务表';
-- --------------------------------------------------------
--
-- 表的结构 `chatgpt_users`
--
DROP TABLE IF EXISTS `chatgpt_users`;
CREATE TABLE `chatgpt_users` (
`id` int NOT NULL,
`username` varchar(30) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '用户名',
`nickname` varchar(30) NOT NULL COMMENT '昵称',
`password` char(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '密码',
`avatar` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '头像',
`salt` char(12) NOT NULL COMMENT '密码盐',
`power` int NOT NULL DEFAULT '0' COMMENT '剩余算力',
`expired_time` int NOT NULL COMMENT '用户过期时间',
`status` tinyint(1) NOT NULL COMMENT '当前状态',
`chat_config_json` text CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '聊天配置json',
`chat_roles_json` text CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '聊天角色 json',
`chat_models_json` text CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT 'AI模型 json',
`last_login_at` int NOT NULL COMMENT '最后登录时间',
`vip` tinyint(1) NOT NULL DEFAULT '0' COMMENT '是否会员',
`last_login_ip` char(16) NOT NULL COMMENT '最后登录 IP',
`openid` varchar(100) DEFAULT NULL COMMENT '第三方登录账号ID',
`platform` varchar(30) DEFAULT NULL COMMENT '登录平台',
`created_at` datetime NOT NULL,
`updated_at` datetime NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci COMMENT='用户表';
--
-- 转存表中的数据 `chatgpt_users`
--
INSERT INTO `chatgpt_users` (`id`, `username`, `nickname`, `password`, `avatar`, `salt`, `power`, `expired_time`, `status`, `chat_config_json`, `chat_roles_json`, `chat_models_json`, `last_login_at`, `vip`, `last_login_ip`, `openid`, `platform`, `created_at`, `updated_at`) VALUES
(4, '18575670125', '极客学长', 'ccc3fb7ab61b8b5d096a4a166ae21d121fc38c71bbd1be6173d9ab973214a63b', 'http://localhost:5678/static/upload/2024/5/1715651569509929.png', 'ueedue5l', 6011, 0, 1, '{\"api_keys\":{\"Azure\":\"\",\"ChatGLM\":\"\",\"OpenAI\":\"\"}}', '[\"red_book\",\"gpt\",\"seller\",\"artist\",\"lu_xun\",\"girl_friend\",\"psychiatrist\",\"teacher\",\"programmer\",\"test\",\"qing_gan_da_shi\",\"english_trainer\",\"elon_musk\",\"kong_zi\"]', '[1,11]', 1723022231, 1, '::1', NULL, NULL, '2023-06-12 16:47:17', '2024-08-07 17:17:11'),
(5, 'yangjian102621@gmail.com', '极客学长@486041', '75d1a22f33e1ffffb7943946b6b8d5177d5ecd685d3cef1b468654038b0a8c22', '/images/avatar/user.png', '2q8ugxzk', 100, 0, 1, '', '[\"gpt\",\"programmer\"]', '[11,7,1,10,12,19,18,17,3]', 0, 0, '', NULL, NULL, '2024-04-23 09:17:26', '2024-04-23 09:17:26'),
(8, 'yangjian102623@gmail.com', '极客学长@714931', 'f8f0e0abf146569217273ea0712a0f9b6cbbe7d943a1d9bd5f91c55e6d8c05d1', '/images/avatar/user.png', 'geuddq7f', 100, 0, 1, '', '[\"gpt\"]', '[11,7,1,10,12,19,18,17,3]', 0, 0, '', NULL, NULL, '2024-04-26 15:19:28', '2024-04-26 15:19:28'),
(9, '1234567', '极客学长@604526', '858e2afec79e1d6364f4567f945f2310024896d9aa45dd944efa95a0c31e4d08', '/images/avatar/user.png', '00qawlos', 100, 0, 1, '', '[\"gpt\"]', '[11,7,1,10,12,19,18,17,3]', 0, 0, '', NULL, NULL, '2024-04-26 15:21:06', '2024-04-26 15:21:06'),
(11, 'abc123', '极客学长@965562', '7a15c53afdb1da7093d80f9940e716eb396e682cfb1f2d107d0b81b183a3ba13', '/images/avatar/user.png', '6433mfbk', 1124, 0, 1, '', '[\"gpt\"]', '[11,7,1,10,12,19,18,17,3]', 0, 0, '', NULL, NULL, '2024-06-06 09:37:44', '2024-06-06 09:37:44'),
(14, 'wx@3567548322', '极客学长', '5a349ba89582a4074938b5a3ce84e87c937681ad47e8b87aab03a987e22b6077', 'https://thirdwx.qlogo.cn/mmopen/vi_32/uyxRMqZcEkb7fHouKXbNzxrnrvAttBKkwNlZ7yFibibRGiahdmsrZ3A1NKf8Fw5qJNJn4TXRmygersgEbibaSGd9Sg/132', 'abhzbmij', 83, 0, 1, '', '[\"gpt\"]', '[11,7,1,10,12,19,18,17,3]', 0, 0, '', 'oCs0t62472W19z2LOEKI1rWyCTTA', '', '2024-07-04 14:52:08', '2024-07-04 14:52:08'),
(15, 'user123', '极客学长@191303', '4a4c0a14d5fc8787357517f14f6e442281b42c8ec4395016b77483997476011e', '/images/avatar/user.png', 'cyzwkbrx', 100, 0, 1, '', '[\"gpt\"]', '[11,7,1,10,12,19,18,17,3]', 0, 0, '', '', '', '2024-07-09 10:49:27', '2024-07-09 10:49:27'),
(17, 'user1234', '极客学长@836764', 'bfe03c9c8c9fff5b77e36e40e8298ad3a6073d43c6a936b008eebb21113bf550', '/images/avatar/user.png', '1d2alwnj', 100, 0, 1, '', '[\"gpt\"]', '[11,7,1,10,12,19,18,17,3]', 0, 0, '', '', '', '2024-07-09 10:53:17', '2024-07-09 10:53:17'),
(18, 'liaoyq', '极客学长@405564', 'ad1726089022db4c661235a8aab7307af1a7f8483eee08bac3f79b5a6a9bd26b', '/images/avatar/user.png', 'yq862l01', 100, 0, 1, '', '[\"string\"]', '[11,7,1,10,12,19,18,17,3]', 1720574265, 0, '172.22.11.29', '', '', '2024-07-10 09:15:33', '2024-07-10 09:17:45'),
(19, 'humm', '极客学长@483216', '420970ace96921c8b3ac7668d097182eab1b6436c730a484e82ae4661bd4f7d9', '/images/avatar/user.png', '1gokrcl2', 100, 0, 1, '', '[\"gpt\"]', '[11,7,1,10,12,19,18,17,3]', 1721381395, 0, '172.22.11.36', '', '', '2024-07-10 11:08:31', '2024-07-19 17:29:56'),
(20, 'abc', '极客学长@369852', '6cad48fb2cc0f54600d66a829e9be69ffd9340a49d5a5b1abda5d4082d946833', '/images/avatar/user.png', 'gop65zei', 100, 0, 1, '', '[\"gpt\"]', '[11,7,1,10,12,19,18,17,3]', 0, 0, '', '', '', '2024-07-11 16:44:14', '2024-07-11 16:44:14'),
(21, 'husm@pvc123.com', '极客学长@721654', 'e030537dc43fea1bf1fa55a24f99e44f29311bebea96e88ea186995c77db083b', '/images/avatar/user.png', 'p1etg3oi', 100, 0, 1, '', '[\"gpt\"]', '[11,7,1,10,12,19,18,17,3]', 0, 0, '', '', '', '2024-07-11 16:50:33', '2024-07-11 16:50:33'),
(22, '15818323616', 'ted0000', '3ca6b2ff585d03be8ca4de33ad00148497a09372914ee8aa4cfde343266cbcdd', 'http://localhost:5678/static/upload/2024/7/1720775695548167.jpg', 'sq4s1brf', 100, 0, 1, '', '[\"gpt\"]', '[11,7,1,10,12,19,18,17,3]', 1721785366, 0, '172.22.11.36', '', '', '2024-07-12 15:12:16', '2024-07-24 09:42:46'),
(23, 'aaaaaaaa', '极客学长@488661', 'a7f05323a6ec9dfc1e9bc126f15ccc17c38d0df47957a0bec51f4cc5c2a2b906', '/images/avatar/user.png', 'dsz5d6td', 19, 0, 1, '', '[\"gpt\",\"psychiatrist\",\"red_book\"]', '[11,7,1,10,12,19,18,17,3]', 0, 0, '', '', '', '2024-07-22 13:49:55', '2024-07-22 13:49:55'),
(24, 'test', '极客学长@822932', 'a54d3c38a4a20106ade96de0e9d4547cc691abc5dc39697b44c1a82850374775', '/images/avatar/user.png', '4aa7pijd', 10, 0, 1, '', '[\"gpt\"]', '[1,46]', 0, 0, '', '', '', '2024-07-22 14:40:42', '2024-07-22 14:40:42');
-- --------------------------------------------------------
--
-- 表的结构 `chatgpt_user_login_logs`
--
DROP TABLE IF EXISTS `chatgpt_user_login_logs`;
CREATE TABLE `chatgpt_user_login_logs` (
`id` int NOT NULL,
`user_id` int NOT NULL COMMENT '用户ID',
`username` varchar(30) NOT NULL COMMENT '用户名',
`login_ip` char(16) NOT NULL COMMENT '登录IP',
`login_address` varchar(30) NOT NULL COMMENT '登录地址',
`created_at` datetime NOT NULL,
`updated_at` datetime NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci COMMENT='用户登录日志';
--
-- 转储表的索引
--
--
-- 表的索引 `chatgpt_admin_users`
--
ALTER TABLE `chatgpt_admin_users`
ADD PRIMARY KEY (`id`) USING BTREE,
ADD UNIQUE KEY `username` (`username`) USING BTREE;
--
-- 表的索引 `chatgpt_api_keys`
--
ALTER TABLE `chatgpt_api_keys`
ADD PRIMARY KEY (`id`);
--
-- 表的索引 `chatgpt_chat_history`
--
ALTER TABLE `chatgpt_chat_history`
ADD PRIMARY KEY (`id`),
ADD KEY `chat_id` (`chat_id`);
--
-- 表的索引 `chatgpt_chat_items`
--
ALTER TABLE `chatgpt_chat_items`
ADD PRIMARY KEY (`id`),
ADD UNIQUE KEY `chat_id` (`chat_id`);
--
-- 表的索引 `chatgpt_chat_models`
--
ALTER TABLE `chatgpt_chat_models`
ADD PRIMARY KEY (`id`);
--
-- 表的索引 `chatgpt_chat_roles`
--
ALTER TABLE `chatgpt_chat_roles`
ADD PRIMARY KEY (`id`),
ADD UNIQUE KEY `marker` (`marker`);
--
-- 表的索引 `chatgpt_configs`
--
ALTER TABLE `chatgpt_configs`
ADD PRIMARY KEY (`id`),
ADD UNIQUE KEY `marker` (`marker`);
--
-- 表的索引 `chatgpt_dall_jobs`
--
ALTER TABLE `chatgpt_dall_jobs`
ADD PRIMARY KEY (`id`);
--
-- 表的索引 `chatgpt_files`
--
ALTER TABLE `chatgpt_files`
ADD PRIMARY KEY (`id`);
--
-- 表的索引 `chatgpt_functions`
--
ALTER TABLE `chatgpt_functions`
ADD PRIMARY KEY (`id`),
ADD UNIQUE KEY `name` (`name`);
--
-- 表的索引 `chatgpt_invite_codes`
--
ALTER TABLE `chatgpt_invite_codes`
ADD PRIMARY KEY (`id`),
ADD UNIQUE KEY `code` (`code`);
--
-- 表的索引 `chatgpt_invite_logs`
--
ALTER TABLE `chatgpt_invite_logs`
ADD PRIMARY KEY (`id`);
--
-- 表的索引 `chatgpt_menus`
--
ALTER TABLE `chatgpt_menus`
ADD PRIMARY KEY (`id`);
--
-- 表的索引 `chatgpt_mj_jobs`
--
ALTER TABLE `chatgpt_mj_jobs`
ADD PRIMARY KEY (`id`),
ADD UNIQUE KEY `task_id` (`task_id`),
ADD KEY `message_id` (`message_id`);
--
-- 表的索引 `chatgpt_orders`
--
ALTER TABLE `chatgpt_orders`
ADD PRIMARY KEY (`id`),
ADD UNIQUE KEY `order_no` (`order_no`);
--
-- 表的索引 `chatgpt_power_logs`
--
ALTER TABLE `chatgpt_power_logs`
ADD PRIMARY KEY (`id`);
--
-- 表的索引 `chatgpt_products`
--
ALTER TABLE `chatgpt_products`
ADD PRIMARY KEY (`id`);
--
-- 表的索引 `chatgpt_redeems`
--
ALTER TABLE `chatgpt_redeems`
ADD PRIMARY KEY (`id`),
ADD UNIQUE KEY `code` (`code`);
--
-- 表的索引 `chatgpt_sd_jobs`
--
ALTER TABLE `chatgpt_sd_jobs`
ADD PRIMARY KEY (`id`),
ADD UNIQUE KEY `task_id` (`task_id`);
--
-- 表的索引 `chatgpt_suno_jobs`
--
ALTER TABLE `chatgpt_suno_jobs`
ADD PRIMARY KEY (`id`);
--
-- 表的索引 `chatgpt_users`
--
ALTER TABLE `chatgpt_users`
ADD PRIMARY KEY (`id`),
ADD UNIQUE KEY `username` (`username`);
--
-- 表的索引 `chatgpt_user_login_logs`
--
ALTER TABLE `chatgpt_user_login_logs`
ADD PRIMARY KEY (`id`);
--
-- 在导出的表使用AUTO_INCREMENT
--
--
-- 使用表AUTO_INCREMENT `chatgpt_admin_users`
--
ALTER TABLE `chatgpt_admin_users`
MODIFY `id` int NOT NULL AUTO_INCREMENT, AUTO_INCREMENT=113;
--
-- 使用表AUTO_INCREMENT `chatgpt_api_keys`
--
ALTER TABLE `chatgpt_api_keys`
MODIFY `id` int NOT NULL AUTO_INCREMENT;
--
-- 使用表AUTO_INCREMENT `chatgpt_chat_history`
--
ALTER TABLE `chatgpt_chat_history`
MODIFY `id` bigint NOT NULL AUTO_INCREMENT;
--
-- 使用表AUTO_INCREMENT `chatgpt_chat_items`
--
ALTER TABLE `chatgpt_chat_items`
MODIFY `id` int NOT NULL AUTO_INCREMENT;
--
-- 使用表AUTO_INCREMENT `chatgpt_chat_models`
--
ALTER TABLE `chatgpt_chat_models`
MODIFY `id` int NOT NULL AUTO_INCREMENT, AUTO_INCREMENT=48;
--
-- 使用表AUTO_INCREMENT `chatgpt_chat_roles`
--
ALTER TABLE `chatgpt_chat_roles`
MODIFY `id` int NOT NULL AUTO_INCREMENT, AUTO_INCREMENT=132;
--
-- 使用表AUTO_INCREMENT `chatgpt_configs`
--
ALTER TABLE `chatgpt_configs`
MODIFY `id` int NOT NULL AUTO_INCREMENT, AUTO_INCREMENT=4;
--
-- 使用表AUTO_INCREMENT `chatgpt_dall_jobs`
--
ALTER TABLE `chatgpt_dall_jobs`
MODIFY `id` int NOT NULL AUTO_INCREMENT;
--
-- 使用表AUTO_INCREMENT `chatgpt_files`
--
ALTER TABLE `chatgpt_files`
MODIFY `id` int NOT NULL AUTO_INCREMENT;
--
-- 使用表AUTO_INCREMENT `chatgpt_functions`
--
ALTER TABLE `chatgpt_functions`
MODIFY `id` int NOT NULL AUTO_INCREMENT, AUTO_INCREMENT=4;
--
-- 使用表AUTO_INCREMENT `chatgpt_invite_codes`
--
ALTER TABLE `chatgpt_invite_codes`
MODIFY `id` int NOT NULL AUTO_INCREMENT;
--
-- 使用表AUTO_INCREMENT `chatgpt_invite_logs`
--
ALTER TABLE `chatgpt_invite_logs`
MODIFY `id` int NOT NULL AUTO_INCREMENT;
--
-- 使用表AUTO_INCREMENT `chatgpt_menus`
--
ALTER TABLE `chatgpt_menus`
MODIFY `id` int NOT NULL AUTO_INCREMENT, AUTO_INCREMENT=20;
--
-- 使用表AUTO_INCREMENT `chatgpt_mj_jobs`
--
ALTER TABLE `chatgpt_mj_jobs`
MODIFY `id` int NOT NULL AUTO_INCREMENT;
--
-- 使用表AUTO_INCREMENT `chatgpt_orders`
--
ALTER TABLE `chatgpt_orders`
MODIFY `id` int NOT NULL AUTO_INCREMENT;
--
-- 使用表AUTO_INCREMENT `chatgpt_power_logs`
--
ALTER TABLE `chatgpt_power_logs`
MODIFY `id` int NOT NULL AUTO_INCREMENT;
--
-- 使用表AUTO_INCREMENT `chatgpt_products`
--
ALTER TABLE `chatgpt_products`
MODIFY `id` int NOT NULL AUTO_INCREMENT, AUTO_INCREMENT=7;
--
-- 使用表AUTO_INCREMENT `chatgpt_redeems`
--
ALTER TABLE `chatgpt_redeems`
MODIFY `id` int NOT NULL AUTO_INCREMENT;
--
-- 使用表AUTO_INCREMENT `chatgpt_sd_jobs`
--
ALTER TABLE `chatgpt_sd_jobs`
MODIFY `id` int NOT NULL AUTO_INCREMENT;
--
-- 使用表AUTO_INCREMENT `chatgpt_suno_jobs`
--
ALTER TABLE `chatgpt_suno_jobs`
MODIFY `id` int NOT NULL AUTO_INCREMENT;
--
-- 使用表AUTO_INCREMENT `chatgpt_users`
--
ALTER TABLE `chatgpt_users`
MODIFY `id` int NOT NULL AUTO_INCREMENT, AUTO_INCREMENT=25;
--
-- 使用表AUTO_INCREMENT `chatgpt_user_login_logs`
--
ALTER TABLE `chatgpt_user_login_logs`
MODIFY `id` int NOT NULL AUTO_INCREMENT;
COMMIT;
/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;
/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */;
/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;

Some files were not shown because too many files have changed in this diff Show More