增加自动迁移数据表代码

This commit is contained in:
RockYang
2025-04-29 22:55:30 +08:00
parent d1c9fd6eba
commit 8a2d2f66b5
89 changed files with 484 additions and 406 deletions

View File

@@ -72,6 +72,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()

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

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

@@ -69,7 +69,7 @@ func (h *ChatModelHandler) Save(c *gin.Context) {
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
@@ -117,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

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

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

@@ -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,19 +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 // 最大上下文长度
Description string //模型描述
Category string //模型类别
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"`
Marker string `gorm:"column:marker;type:varchar(30);uniqueIndex;not null;comment:角色标识" json:"marker"`
Context string `gorm:"column:context_json;type:text;not null;comment:角色语料 json" json:"context_json"`
HelloMsg string `gorm:"column:hello_msg;type:varchar(255);not null;comment:打招呼信息" json:"hello_msg"`
Icon string `gorm:"column:icon;type:varchar(255);not null;comment:角色图标" json:"icon"`
Enable bool `gorm:"column:enable;type:tinyint(1);not null;comment:是否被启用" json:"enable"`
SortNum int `gorm:"column:sort_num;type:smallint;not null;default:0;comment:角色排序" json:"sort_num"`
ModelId uint `gorm:"column:model_id;type:int;not null;default:0;comment:绑定模型ID" json:"model_id"`
CreatedAt time.Time `gorm:"column:created_at;type:datetime;not null" json:"created_at"`
UpdatedAt time.Time `gorm:"column:updated_at;type:datetime;not null" json:"updated_at"`
}
func (m *ChatRole) TableName() string {
return "chatgpt_chat_roles"
}

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