feat: load preview page do not require user to login

This commit is contained in:
RockYang 2024-03-19 18:25:01 +08:00
parent 8f47474edd
commit 58e44b7d12
57 changed files with 758 additions and 1550 deletions

View File

@ -132,51 +132,37 @@ func corsMiddleware() gin.HandlerFunc {
// 用户授权验证 // 用户授权验证
func authorizeMiddleware(s *AppServer, client *redis.Client) gin.HandlerFunc { func authorizeMiddleware(s *AppServer, client *redis.Client) gin.HandlerFunc {
return func(c *gin.Context) { return func(c *gin.Context) {
if c.Request.URL.Path == "/api/user/login" ||
c.Request.URL.Path == "/api/user/resetPass" ||
c.Request.URL.Path == "/api/admin/login" ||
c.Request.URL.Path == "/api/admin/login/captcha" ||
c.Request.URL.Path == "/api/user/register" ||
c.Request.URL.Path == "/api/chat/history" ||
c.Request.URL.Path == "/api/chat/detail" ||
c.Request.URL.Path == "/api/role/list" ||
c.Request.URL.Path == "/api/mj/imgWall" ||
c.Request.URL.Path == "/api/mj/client" ||
c.Request.URL.Path == "/api/mj/notify" ||
c.Request.URL.Path == "/api/invite/hits" ||
c.Request.URL.Path == "/api/sd/imgWall" ||
c.Request.URL.Path == "/api/sd/client" ||
c.Request.URL.Path == "/api/config/get" ||
strings.HasPrefix(c.Request.URL.Path, "/api/test") ||
strings.HasPrefix(c.Request.URL.Path, "/api/function/") ||
strings.HasPrefix(c.Request.URL.Path, "/api/sms/") ||
strings.HasPrefix(c.Request.URL.Path, "/api/captcha/") ||
strings.HasPrefix(c.Request.URL.Path, "/api/payment/") ||
strings.HasPrefix(c.Request.URL.Path, "/static/") {
c.Next()
return
}
var tokenString string var tokenString string
if strings.Contains(c.Request.URL.Path, "/api/admin/") { // 后台管理 API isAdminApi := strings.Contains(c.Request.URL.Path, "/api/admin/")
if isAdminApi { // 后台管理 API
tokenString = c.GetHeader(types.AdminAuthHeader) tokenString = c.GetHeader(types.AdminAuthHeader)
} else if c.Request.URL.Path == "/api/chat/new" { } else if c.Request.URL.Path == "/api/chat/new" {
tokenString = c.Query("token") tokenString = c.Query("token")
} else { } else {
tokenString = c.GetHeader(types.UserAuthHeader) tokenString = c.GetHeader(types.UserAuthHeader)
} }
if tokenString == "" { if tokenString == "" {
resp.ERROR(c, "You should put Authorization in request headers") if needLogin(c) {
c.Abort() resp.ERROR(c, "You should put Authorization in request headers")
return c.Abort()
return
} else { // 直接放行
c.Next()
return
}
} }
token, err := jwt.Parse(tokenString, func(token *jwt.Token) (interface{}, error) { token, err := jwt.Parse(tokenString, func(token *jwt.Token) (interface{}, error) {
if _, ok := token.Method.(*jwt.SigningMethodHMAC); !ok { if _, ok := token.Method.(*jwt.SigningMethodHMAC); !ok {
return nil, fmt.Errorf("unexpected signing method: %v", token.Header["alg"]) return nil, fmt.Errorf("unexpected signing method: %v", token.Header["alg"])
} }
if isAdminApi {
return []byte(s.Config.AdminSession.SecretKey), nil
} else {
return []byte(s.Config.Session.SecretKey), nil
}
return []byte(s.Config.Session.SecretKey), nil
}) })
if err != nil { if err != nil {
@ -200,7 +186,7 @@ func authorizeMiddleware(s *AppServer, client *redis.Client) gin.HandlerFunc {
} }
key := fmt.Sprintf("users/%v", claims["user_id"]) key := fmt.Sprintf("users/%v", claims["user_id"])
if _, err := client.Get(context.Background(), key).Result(); err != nil { if _, err := client.Get(context.Background(), key).Result(); err != nil && needLogin(c) {
resp.NotAuth(c, "Token is not found in redis") resp.NotAuth(c, "Token is not found in redis")
c.Abort() c.Abort()
return return
@ -209,6 +195,35 @@ func authorizeMiddleware(s *AppServer, client *redis.Client) gin.HandlerFunc {
} }
} }
func needLogin(c *gin.Context) bool {
if c.Request.URL.Path == "/api/user/login" ||
c.Request.URL.Path == "/api/user/resetPass" ||
c.Request.URL.Path == "/api/admin/login" ||
c.Request.URL.Path == "/api/admin/login/captcha" ||
c.Request.URL.Path == "/api/user/register" ||
c.Request.URL.Path == "/api/chat/history" ||
c.Request.URL.Path == "/api/chat/detail" ||
c.Request.URL.Path == "/api/chat/list" ||
c.Request.URL.Path == "/api/role/list" ||
c.Request.URL.Path == "/api/model/list" ||
c.Request.URL.Path == "/api/mj/imgWall" ||
c.Request.URL.Path == "/api/mj/client" ||
c.Request.URL.Path == "/api/mj/notify" ||
c.Request.URL.Path == "/api/invite/hits" ||
c.Request.URL.Path == "/api/sd/imgWall" ||
c.Request.URL.Path == "/api/sd/client" ||
c.Request.URL.Path == "/api/config/get" ||
strings.HasPrefix(c.Request.URL.Path, "/api/test") ||
strings.HasPrefix(c.Request.URL.Path, "/api/function/") ||
strings.HasPrefix(c.Request.URL.Path, "/api/sms/") ||
strings.HasPrefix(c.Request.URL.Path, "/api/captcha/") ||
strings.HasPrefix(c.Request.URL.Path, "/api/payment/") ||
strings.HasPrefix(c.Request.URL.Path, "/static/") {
return false
}
return true
}
// 统一参数处理 // 统一参数处理
func parameterHandlerMiddleware() gin.HandlerFunc { func parameterHandlerMiddleware() gin.HandlerFunc {
return func(c *gin.Context) { return func(c *gin.Context) {

View File

@ -8,6 +8,7 @@ type AppConfig struct {
Path string `toml:"-"` Path string `toml:"-"`
Listen string Listen string
Session Session Session Session
AdminSession Session
ProxyURL string ProxyURL string
MysqlDns string // mysql 连接地址 MysqlDns string // mysql 连接地址
StaticDir string // 静态资源目录 StaticDir string // 静态资源目录
@ -139,7 +140,7 @@ type SystemConfig struct {
InvitePower int `json:"invite_power,omitempty"` // 邀请新用户赠送算力值 InvitePower int `json:"invite_power,omitempty"` // 邀请新用户赠送算力值
VipMonthPower int `json:"vip_month_power,omitempty"` // VIP 会员每月赠送的算力值 VipMonthPower int `json:"vip_month_power,omitempty"` // VIP 会员每月赠送的算力值
RegisterWays []string `json:"register_ways,omitempty"` // 注册方式:支持手机,邮箱注册 RegisterWays []string `json:"register_ways,omitempty"` // 注册方式:支持手机,邮箱注册,账号密码注册
EnabledRegister bool `json:"enabled_register,omitempty"` // 是否开放注册 EnabledRegister bool `json:"enabled_register,omitempty"` // 是否开放注册
RewardImg string `json:"reward_img,omitempty"` // 众筹收款二维码地址 RewardImg string `json:"reward_img,omitempty"` // 众筹收款二维码地址

View File

@ -30,19 +30,15 @@ type Manager struct {
type ManagerHandler struct { type ManagerHandler struct {
handler.BaseHandler handler.BaseHandler
db *gorm.DB
redis *redis.Client redis *redis.Client
} }
func NewAdminHandler(app *core.AppServer, db *gorm.DB, client *redis.Client) *ManagerHandler { func NewAdminHandler(app *core.AppServer, db *gorm.DB, client *redis.Client) *ManagerHandler {
h := ManagerHandler{db: db, redis: client} return &ManagerHandler{BaseHandler: handler.BaseHandler{DB: db, App: app}, redis: client}
h.App = app
return &h
} }
// Login 登录 // Login 登录
func (h *ManagerHandler) Login(c *gin.Context) { func (h *ManagerHandler) Login(c *gin.Context) {
var data Manager var data Manager
if err := c.ShouldBindJSON(&data); err != nil { if err := c.ShouldBindJSON(&data); err != nil {
resp.ERROR(c, types.InvalidArgs) resp.ERROR(c, types.InvalidArgs)
@ -56,7 +52,7 @@ func (h *ManagerHandler) Login(c *gin.Context) {
} }
var manager model.AdminUser var manager model.AdminUser
res := h.db.Model(&model.AdminUser{}).Where("username = ?", data.Username).First(&manager) res := h.DB.Model(&model.AdminUser{}).Where("username = ?", data.Username).First(&manager)
if res.Error != nil { if res.Error != nil {
resp.ERROR(c, "请检查用户名或者密码是否填写正确") resp.ERROR(c, "请检查用户名或者密码是否填写正确")
return return
@ -78,7 +74,7 @@ func (h *ManagerHandler) Login(c *gin.Context) {
"user_id": manager.Username, "user_id": manager.Username,
"expired": time.Now().Add(time.Second * time.Duration(h.App.Config.Session.MaxAge)).Unix(), "expired": time.Now().Add(time.Second * time.Duration(h.App.Config.Session.MaxAge)).Unix(),
}) })
tokenString, err := token.SignedString([]byte(h.App.Config.Session.SecretKey)) tokenString, err := token.SignedString([]byte(h.App.Config.AdminSession.SecretKey))
if err != nil { if err != nil {
resp.ERROR(c, "Failed to generate token, "+err.Error()) resp.ERROR(c, "Failed to generate token, "+err.Error())
return return
@ -93,35 +89,19 @@ func (h *ManagerHandler) Login(c *gin.Context) {
// 更新最后登录时间和IP // 更新最后登录时间和IP
manager.LastLoginIp = c.ClientIP() manager.LastLoginIp = c.ClientIP()
manager.LastLoginAt = time.Now().Unix() manager.LastLoginAt = time.Now().Unix()
h.db.Model(&manager).Updates(manager) h.DB.Model(&manager).Updates(manager)
permissions := h.GetAdminSlugs(manager.Id)
var result = struct { var result = struct {
IsSuperAdmin bool `json:"is_super_admin"` IsSuperAdmin bool `json:"is_super_admin"`
Token string `json:"token"` Token string `json:"token"`
Permissions []string `json:"permissions"`
}{ }{
IsSuperAdmin: manager.Id == 1, IsSuperAdmin: manager.Id == 1,
Token: tokenString, Token: tokenString,
Permissions: permissions,
} }
resp.SUCCESS(c, result) resp.SUCCESS(c, result)
} }
func (h *ManagerHandler) GetAdminSlugs(userId uint) []string {
var permissions []string
err := h.db.Raw("SELECT distinct p.slug "+
"FROM chatgpt_admin_user_roles as ur "+
"LEFT JOIN chatgpt_admin_role_permissions as rp ON ur.role_id = rp.role_id "+
"LEFT JOIN chatgpt_admin_permissions as p ON rp.permission_id = p.id "+
"WHERE ur.admin_id = ?", userId).Scan(&permissions)
if err.Error == nil {
return []string{}
}
return permissions
}
// Logout 注销 // Logout 注销
func (h *ManagerHandler) Logout(c *gin.Context) { func (h *ManagerHandler) Logout(c *gin.Context) {
key := h.GetUserKey(c) key := h.GetUserKey(c)

View File

@ -1,132 +0,0 @@
package admin
import (
"chatplus/core"
"chatplus/core/types"
"chatplus/handler"
"chatplus/store/model"
"chatplus/store/vo"
"chatplus/utils"
"chatplus/utils/resp"
"fmt"
"github.com/gin-gonic/gin"
"gorm.io/gorm"
)
type SysPermissionHandler struct {
handler.BaseHandler
db *gorm.DB
}
func NewSysPermissionHandler(app *core.AppServer, db *gorm.DB) *SysPermissionHandler {
h := SysPermissionHandler{db: db}
h.App = app
return &h
}
func (h *SysPermissionHandler) List(c *gin.Context) {
if err := utils.CheckPermission(c, h.db); err != nil {
resp.NotPermission(c)
return
}
var items []model.AdminPermission
var data = make([]vo.AdminPermission, 0)
res := h.db.Find(&items)
if res.Error != nil {
resp.ERROR(c, "暂无数据")
return
}
for _, item := range items {
adminPermissionVo := vo.AdminPermission{}
_ = utils.CopyObject(item, &adminPermissionVo)
data = append(data, adminPermissionVo)
}
data = ArrayToTree(data)
resp.SUCCESS(c, data)
}
func ArrayToTree(dates []vo.AdminPermission) []vo.AdminPermission {
group := make(map[int][]vo.AdminPermission, 0)
for _, node := range dates {
group[node.Pid] = append(group[node.Pid], node)
}
// 初始化递归,从根节点开始构建树
result := FindSiblings(group[0], group)
return result
}
func FindSiblings(siblings []vo.AdminPermission, group map[int][]vo.AdminPermission) []vo.AdminPermission {
result := make([]vo.AdminPermission, 0)
for _, sibling := range siblings {
children, ok := group[sibling.Id]
if ok {
sibling.Children = FindSiblings(children, group)
}
result = append(result, sibling)
}
return result
}
func (h *SysPermissionHandler) Save(c *gin.Context) {
var data struct {
Id int `json:"id"`
Name string `json:"name"`
Slug string `json:"slug"`
Sort int `json:"sort"`
Pid int `json:"pid"`
}
if err := c.ShouldBindJSON(&data); err != nil {
resp.ERROR(c, types.InvalidArgs)
return
}
var permission = model.AdminPermission{}
var res *gorm.DB
if data.Id > 0 { // 更新
permission.Id = data.Id
// 此处需要用 map 更新,用结构体无法更新 0 值
res = h.db.Model(&permission).Updates(map[string]interface{}{
"name": data.Name,
"slug": data.Slug,
"sort": data.Sort,
"pid": data.Pid,
})
} else {
p := model.AdminPermission{
Name: data.Name,
Slug: data.Slug,
Sort: data.Sort,
Pid: data.Pid,
}
res = h.db.Create(&p)
}
if res.Error != nil {
fmt.Println(res.Error)
resp.ERROR(c, "更新数据库失败")
return
}
resp.SUCCESS(c)
}
func (h *SysPermissionHandler) Remove(c *gin.Context) {
var data struct {
Id int
}
if err := c.ShouldBindJSON(&data); err != nil {
resp.ERROR(c, types.InvalidArgs)
return
}
if data.Id > 0 {
res := h.db.Where("id = ?", data.Id).Delete(&model.AdminPermission{})
if res.Error != nil {
resp.ERROR(c, "删除失败")
return
}
}
resp.SUCCESS(c)
}

View File

@ -1,166 +0,0 @@
package admin
import (
"chatplus/core"
"chatplus/core/types"
"chatplus/handler"
"chatplus/store/model"
"chatplus/store/vo"
"chatplus/utils"
"chatplus/utils/resp"
"github.com/gin-gonic/gin"
"gorm.io/gorm"
)
type SysRoleHandler struct {
handler.BaseHandler
db *gorm.DB
}
func NewSysRoleHandler(app *core.AppServer, db *gorm.DB) *SysRoleHandler {
h := SysRoleHandler{db: db}
h.App = app
return &h
}
type permission struct {
Id int `json:"id"`
Name string `json:"name"`
Slug string `json:"slug"`
}
func (h *SysRoleHandler) List(c *gin.Context) {
if err := utils.CheckPermission(c, h.db); err != nil {
resp.NotPermission(c)
return
}
page := h.GetInt(c, "page", 1)
pageSize := h.GetInt(c, "page_size", 20)
name := h.GetTrim(c, "name")
offset := (page - 1) * pageSize
var items []model.AdminRole
var data = make([]vo.AdminRole, 0)
var total int64
session := h.db.Session(&gorm.Session{})
if name != "" {
session = session.Where("name LIKE ?", "%"+name+"%")
}
session.Model(&model.AdminRole{}).Count(&total)
res := session.Offset(offset).Limit(pageSize).Find(&items)
if res.Error != nil {
resp.ERROR(c, "暂无数据")
return
}
for _, item := range items {
adminRoleVo := vo.AdminRole{}
err := utils.CopyObject(item, &adminRoleVo)
if err == nil {
var permissions []permission
h.db.Raw("SELECT p.id,p.name,p.slug "+
"FROM chatgpt_admin_role_permissions as rp "+
"LEFT JOIN chatgpt_admin_permissions as p ON rp.permission_id = p.id "+
"WHERE rp.role_id = ?", item.Id).Scan(&permissions)
adminRoleVo.Permissions = permissions
adminRoleVo.CreatedAt = item.CreatedAt.Format("2006-01-02 15:04:05")
data = append(data, adminRoleVo)
}
}
pageVo := vo.NewPage(total, page, pageSize, data)
resp.SUCCESS(c, pageVo)
}
func (h *SysRoleHandler) Save(c *gin.Context) {
var data struct {
Id int
Name string
Description string
Permissions []int
}
if err := c.ShouldBindJSON(&data); err != nil {
resp.ERROR(c, types.InvalidArgs)
return
}
var role = model.AdminRole{}
var res *gorm.DB
tx := h.db.Begin()
if data.Id > 0 { // 更新
role.Id = data.Id
//删除角色对应的权限
err := tx.Where("role_id = ?", role.Id).Delete(model.AdminRolePermission{})
if err.Error != nil {
tx.Rollback()
resp.ERROR(c, "更新数据库失败")
return
}
//更新角色名
res = tx.Model(&role).Updates(map[string]interface{}{
"name": data.Name,
"description": data.Description,
})
} else {
//新建角色
role.Name = data.Name
role.Description = data.Description
res = tx.Create(&role)
}
if res.Error != nil {
tx.Rollback()
resp.ERROR(c, "更新数据库失败")
return
}
rp := make([]model.AdminRolePermission, 0)
if len(data.Permissions) > 0 {
for _, per := range data.Permissions {
rp = append(rp, model.AdminRolePermission{
RoleId: role.Id,
PermissionId: per,
})
}
res2 := tx.CreateInBatches(rp, len(rp))
if res2.Error != nil {
tx.Rollback()
resp.ERROR(c, "更新数据库失败")
return
}
}
tx.Commit()
resp.SUCCESS(c)
}
func (h *SysRoleHandler) Remove(c *gin.Context) {
var data struct {
Id int
}
if err := c.ShouldBindJSON(&data); err != nil {
resp.ERROR(c, types.InvalidArgs)
return
}
if data.Id > 0 {
tx := h.db.Begin()
res := tx.Where("id = ?", data.Id).Delete(&model.AdminRole{})
if res.Error != nil {
tx.Rollback()
resp.ERROR(c, "删除失败")
return
}
res = tx.Where("role_id = ?", data.Id).Delete(&model.AdminRolePermission{})
if res.Error != nil {
tx.Rollback()
resp.ERROR(c, "删除失败")
return
}
tx.Commit()
}
resp.SUCCESS(c)
}

View File

@ -1,219 +0,0 @@
package admin
import (
"chatplus/core"
"chatplus/core/types"
"chatplus/handler"
"chatplus/store/model"
"chatplus/store/vo"
"chatplus/utils"
"chatplus/utils/resp"
"github.com/gin-gonic/gin"
"gorm.io/gorm"
)
type SysUserHandler struct {
handler.BaseHandler
db *gorm.DB
}
func NewSysUserHandler(app *core.AppServer, db *gorm.DB) *SysUserHandler {
h := SysUserHandler{db: db}
h.App = app
return &h
}
type role struct {
Id int `json:"id"`
Name string `json:"name"`
}
// List 用户列表
func (h *SysUserHandler) List(c *gin.Context) {
if err := utils.CheckPermission(c, h.db); err != nil {
resp.NotPermission(c)
return
}
page := h.GetInt(c, "page", 1)
pageSize := h.GetInt(c, "page_size", 20)
username := h.GetTrim(c, "username")
offset := (page - 1) * pageSize
var items []model.AdminUser
var users = make([]vo.AdminUser, 0)
var total int64
session := h.db.Session(&gorm.Session{})
if username != "" {
session = session.Where("username LIKE ?", "%"+username+"%")
}
// 查询total
session.Model(&model.AdminUser{}).Count(&total)
res := session.Offset(offset).Limit(pageSize).Find(&items)
if res.Error == nil {
for _, item := range items {
var userVo vo.AdminUser
err := utils.CopyObject(item, &userVo)
if err == nil {
var roles []role
h.db.Raw("SELECT r.id,r.name "+
"FROM chatgpt_admin_user_roles as ur "+
"LEFT JOIN chatgpt_admin_roles as r ON ur.role_id = r.id "+
"WHERE ur.admin_id = ?", item.Id).Scan(&roles)
userVo.Id = item.Id
userVo.CreatedAt = item.CreatedAt.Unix()
userVo.UpdatedAt = item.UpdatedAt.Unix()
userVo.RoleIds = roles
users = append(users, userVo)
} else {
logger.Error(err)
}
}
}
pageVo := vo.NewPage(total, page, pageSize, users)
resp.SUCCESS(c, pageVo)
}
// Save 更新或者新增
func (h *SysUserHandler) Save(c *gin.Context) {
var data struct {
Id uint `json:"id"`
Password string `json:"password"`
Username string `json:"username"`
Status bool `json:"status"`
RoleIds []int `json:"role_ids"`
}
if err := c.ShouldBindJSON(&data); err != nil {
resp.ERROR(c, types.InvalidArgs)
return
}
// 默认id为1是超级管理员
if data.Id == 1 {
resp.ERROR(c, "超级管理员不支持更新")
return
}
var user = model.AdminUser{}
var res *gorm.DB
var userVo vo.AdminUser
tx := h.db.Begin()
if data.Id > 0 { // 更新
user.Id = data.Id
err := tx.Where("admin_id = ?", user.Id).Delete(&model.AdminUserRole{})
if err.Error != nil {
tx.Rollback()
resp.ERROR(c, "更新数据库失败")
return
}
// 此处需要用 map 更新,用结构体无法更新 0 值
res = tx.Model(&user).Updates(map[string]interface{}{
"username": data.Username,
"status": data.Status,
})
} else {
salt := utils.RandString(8)
user.Username = data.Username
user.Password = utils.GenPassword(data.Password, salt)
user.Salt = salt
user.Status = true
res = tx.Create(&user)
_ = utils.CopyObject(user, &userVo)
userVo.Id = user.Id
userVo.CreatedAt = user.CreatedAt.Unix()
userVo.UpdatedAt = user.UpdatedAt.Unix()
}
if res.Error != nil {
tx.Rollback()
resp.ERROR(c, "更新数据库失败")
return
}
// 添加角色
userRole := make([]model.AdminUserRole, 0)
if len(data.RoleIds) > 0 {
for _, roleId := range data.RoleIds {
userRole = append(userRole, model.AdminUserRole{
AdminId: user.Id,
RoleId: roleId,
})
}
err := tx.CreateInBatches(userRole, len(userRole))
if err.Error != nil {
tx.Rollback()
resp.ERROR(c, "更新数据库失败")
return
}
}
tx.Commit()
resp.SUCCESS(c, userVo)
}
// ResetPass 重置密码
func (h *SysUserHandler) ResetPass(c *gin.Context) {
var data struct {
Id uint
Password string
}
if err := c.ShouldBindJSON(&data); err != nil {
resp.ERROR(c, types.InvalidArgs)
return
}
var user model.AdminUser
res := h.db.First(&user, data.Id)
if res.Error != nil {
resp.ERROR(c, "No user found")
return
}
password := utils.GenPassword(data.Password, user.Salt)
user.Password = password
res = h.db.Updates(&user)
if res.Error != nil {
resp.ERROR(c)
} else {
resp.SUCCESS(c)
}
}
// Remove 删除
func (h *SysUserHandler) Remove(c *gin.Context) {
var data struct {
Id uint
}
if err := c.ShouldBindJSON(&data); err != nil {
resp.ERROR(c, types.InvalidArgs)
return
}
// 默认id为1是超级管理员
if data.Id == 1 {
resp.ERROR(c, "超级管理员不能删除")
return
}
if data.Id > 0 {
tx := h.db.Begin()
res := tx.Where("id = ?", data.Id).Delete(&model.AdminUser{})
if res.Error != nil {
tx.Rollback()
resp.ERROR(c, "删除失败")
return
}
res2 := tx.Where("admin_id = ?", data.Id).Delete(&model.AdminUserRole{})
if res2.Error != nil {
tx.Rollback()
resp.ERROR(c, "删除失败")
return
}
tx.Commit()
}
resp.SUCCESS(c)
}

View File

@ -14,13 +14,10 @@ import (
type ApiKeyHandler struct { type ApiKeyHandler struct {
handler.BaseHandler handler.BaseHandler
db *gorm.DB
} }
func NewApiKeyHandler(app *core.AppServer, db *gorm.DB) *ApiKeyHandler { func NewApiKeyHandler(app *core.AppServer, db *gorm.DB) *ApiKeyHandler {
h := ApiKeyHandler{db: db} return &ApiKeyHandler{BaseHandler: handler.BaseHandler{DB: db, App: app}}
h.App = app
return &h
} }
func (h *ApiKeyHandler) Save(c *gin.Context) { func (h *ApiKeyHandler) Save(c *gin.Context) {
@ -41,7 +38,7 @@ func (h *ApiKeyHandler) Save(c *gin.Context) {
apiKey := model.ApiKey{} apiKey := model.ApiKey{}
if data.Id > 0 { if data.Id > 0 {
h.db.Find(&apiKey, data.Id) h.DB.Find(&apiKey, data.Id)
} }
apiKey.Platform = data.Platform apiKey.Platform = data.Platform
apiKey.Value = data.Value apiKey.Value = data.Value
@ -50,7 +47,7 @@ func (h *ApiKeyHandler) Save(c *gin.Context) {
apiKey.Enabled = data.Enabled apiKey.Enabled = data.Enabled
apiKey.ProxyURL = data.ProxyURL apiKey.ProxyURL = data.ProxyURL
apiKey.Name = data.Name apiKey.Name = data.Name
res := h.db.Save(&apiKey) res := h.DB.Save(&apiKey)
if res.Error != nil { if res.Error != nil {
resp.ERROR(c, "更新数据库失败!") resp.ERROR(c, "更新数据库失败!")
return return
@ -68,14 +65,14 @@ func (h *ApiKeyHandler) Save(c *gin.Context) {
} }
func (h *ApiKeyHandler) List(c *gin.Context) { func (h *ApiKeyHandler) List(c *gin.Context) {
if err := utils.CheckPermission(c, h.db); err != nil { if err := utils.CheckPermission(c, h.DB); err != nil {
resp.NotPermission(c) resp.NotPermission(c)
return return
} }
var items []model.ApiKey var items []model.ApiKey
var keys = make([]vo.ApiKey, 0) var keys = make([]vo.ApiKey, 0)
res := h.db.Find(&items) res := h.DB.Find(&items)
if res.Error == nil { if res.Error == nil {
for _, item := range items { for _, item := range items {
var key vo.ApiKey var key vo.ApiKey
@ -105,7 +102,7 @@ func (h *ApiKeyHandler) Set(c *gin.Context) {
return return
} }
res := h.db.Model(&model.ApiKey{}).Where("id = ?", data.Id).Update(data.Filed, data.Value) res := h.DB.Model(&model.ApiKey{}).Where("id = ?", data.Id).Update(data.Filed, data.Value)
if res.Error != nil { if res.Error != nil {
resp.ERROR(c, "更新数据库失败!") resp.ERROR(c, "更新数据库失败!")
return return
@ -122,7 +119,7 @@ func (h *ApiKeyHandler) Remove(c *gin.Context) {
return return
} }
if data.Id > 0 { if data.Id > 0 {
res := h.db.Where("id = ?", data.Id).Delete(&model.ApiKey{}) res := h.DB.Where("id = ?", data.Id).Delete(&model.ApiKey{})
if res.Error != nil { if res.Error != nil {
resp.ERROR(c, "更新数据库失败!") resp.ERROR(c, "更新数据库失败!")
return return

View File

@ -13,9 +13,7 @@ type CaptchaHandler struct {
} }
func NewCaptchaHandler(app *core.AppServer) *CaptchaHandler { func NewCaptchaHandler(app *core.AppServer) *CaptchaHandler {
h := CaptchaHandler{} return &CaptchaHandler{BaseHandler: handler.BaseHandler{App: app}}
h.App = app
return &h
} }
type CaptchaVo struct { type CaptchaVo struct {

View File

@ -14,13 +14,10 @@ import (
type ChatHandler struct { type ChatHandler struct {
handler.BaseHandler handler.BaseHandler
db *gorm.DB
} }
func NewChatHandler(app *core.AppServer, db *gorm.DB) *ChatHandler { func NewChatHandler(app *core.AppServer, db *gorm.DB) *ChatHandler {
h := ChatHandler{db: db} return &ChatHandler{BaseHandler: handler.BaseHandler{App: app, DB: db}}
h.App = app
return &h
} }
type chatItemVo struct { type chatItemVo struct {
@ -36,7 +33,7 @@ type chatItemVo struct {
} }
func (h *ChatHandler) List(c *gin.Context) { func (h *ChatHandler) List(c *gin.Context) {
if err := utils.CheckPermission(c, h.db); err != nil { if err := utils.CheckPermission(c, h.DB); err != nil {
resp.NotPermission(c) resp.NotPermission(c)
return return
} }
@ -54,7 +51,7 @@ func (h *ChatHandler) List(c *gin.Context) {
return return
} }
session := h.db.Session(&gorm.Session{}) session := h.DB.Session(&gorm.Session{})
if data.Title != "" { if data.Title != "" {
session = session.Where("title LIKE ?", "%"+data.Title+"%") session = session.Where("title LIKE ?", "%"+data.Title+"%")
} }
@ -88,9 +85,9 @@ func (h *ChatHandler) List(c *gin.Context) {
var messages []model.ChatMessage var messages []model.ChatMessage
var users []model.User var users []model.User
var roles []model.ChatRole var roles []model.ChatRole
h.db.Where("chat_id IN ?", chatIds).Find(&messages) h.DB.Where("chat_id IN ?", chatIds).Find(&messages)
h.db.Where("id IN ?", userIds).Find(&users) h.DB.Where("id IN ?", userIds).Find(&users)
h.db.Where("id IN ?", roleIds).Find(&roles) h.DB.Where("id IN ?", roleIds).Find(&roles)
tokenMap := make(map[string]int) tokenMap := make(map[string]int)
userMap := make(map[uint]string) userMap := make(map[uint]string)
@ -155,7 +152,7 @@ func (h *ChatHandler) Messages(c *gin.Context) {
return return
} }
session := h.db.Session(&gorm.Session{}) session := h.DB.Session(&gorm.Session{})
if data.Content != "" { if data.Content != "" {
session = session.Where("content LIKE ?", "%"+data.Content+"%") session = session.Where("content LIKE ?", "%"+data.Content+"%")
} }
@ -183,7 +180,7 @@ func (h *ChatHandler) Messages(c *gin.Context) {
userIds = append(userIds, item.UserId) userIds = append(userIds, item.UserId)
} }
var users []model.User var users []model.User
h.db.Where("id IN ?", userIds).Find(&users) h.DB.Where("id IN ?", userIds).Find(&users)
userMap := make(map[uint]string) userMap := make(map[uint]string)
for _, user := range users { for _, user := range users {
userMap[user.Id] = user.Username userMap[user.Id] = user.Username
@ -210,7 +207,7 @@ func (h *ChatHandler) History(c *gin.Context) {
chatId := c.Query("chat_id") // 会话 ID chatId := c.Query("chat_id") // 会话 ID
var items []model.ChatMessage var items []model.ChatMessage
var messages = make([]vo.HistoryMessage, 0) var messages = make([]vo.HistoryMessage, 0)
res := h.db.Where("chat_id = ?", chatId).Find(&items) res := h.DB.Where("chat_id = ?", chatId).Find(&items)
if res.Error != nil { if res.Error != nil {
resp.ERROR(c, "No history message") resp.ERROR(c, "No history message")
return return
@ -237,7 +234,7 @@ func (h *ChatHandler) RemoveChat(c *gin.Context) {
return return
} }
tx := h.db.Begin() tx := h.DB.Begin()
// 删除聊天记录 // 删除聊天记录
res := tx.Unscoped().Debug().Where("chat_id = ?", chatId).Delete(&model.ChatMessage{}) res := tx.Unscoped().Debug().Where("chat_id = ?", chatId).Delete(&model.ChatMessage{})
if res.Error != nil { if res.Error != nil {
@ -260,7 +257,7 @@ func (h *ChatHandler) RemoveChat(c *gin.Context) {
// RemoveMessage 删除聊天记录 // RemoveMessage 删除聊天记录
func (h *ChatHandler) RemoveMessage(c *gin.Context) { func (h *ChatHandler) RemoveMessage(c *gin.Context) {
id := h.GetInt(c, "id", 0) id := h.GetInt(c, "id", 0)
tx := h.db.Unscoped().Where("id = ?", id).Delete(&model.ChatMessage{}) tx := h.DB.Unscoped().Where("id = ?", id).Delete(&model.ChatMessage{})
if tx.Error != nil { if tx.Error != nil {
resp.ERROR(c, "更新数据库失败!") resp.ERROR(c, "更新数据库失败!")
return return

View File

@ -15,13 +15,10 @@ import (
type ChatModelHandler struct { type ChatModelHandler struct {
handler.BaseHandler handler.BaseHandler
db *gorm.DB
} }
func NewChatModelHandler(app *core.AppServer, db *gorm.DB) *ChatModelHandler { func NewChatModelHandler(app *core.AppServer, db *gorm.DB) *ChatModelHandler {
h := ChatModelHandler{db: db} return &ChatModelHandler{BaseHandler: handler.BaseHandler{App: app, DB: db}}
h.App = app
return &h
} }
func (h *ChatModelHandler) Save(c *gin.Context) { func (h *ChatModelHandler) Save(c *gin.Context) {
@ -59,7 +56,7 @@ func (h *ChatModelHandler) Save(c *gin.Context) {
if item.Id > 0 { if item.Id > 0 {
item.CreatedAt = time.Unix(data.CreatedAt, 0) item.CreatedAt = time.Unix(data.CreatedAt, 0)
} }
res := h.db.Save(&item) res := h.DB.Save(&item)
if res.Error != nil { if res.Error != nil {
resp.ERROR(c, "更新数据库失败!") resp.ERROR(c, "更新数据库失败!")
return return
@ -78,12 +75,12 @@ func (h *ChatModelHandler) Save(c *gin.Context) {
// List 模型列表 // List 模型列表
func (h *ChatModelHandler) List(c *gin.Context) { func (h *ChatModelHandler) List(c *gin.Context) {
if err := utils.CheckPermission(c, h.db); err != nil { if err := utils.CheckPermission(c, h.DB); err != nil {
resp.NotPermission(c) resp.NotPermission(c)
return return
} }
session := h.db.Session(&gorm.Session{}) session := h.DB.Session(&gorm.Session{})
enable := h.GetBool(c, "enable") enable := h.GetBool(c, "enable")
if enable { if enable {
session = session.Where("enabled", enable) session = session.Where("enabled", enable)
@ -120,7 +117,7 @@ func (h *ChatModelHandler) Set(c *gin.Context) {
return return
} }
res := h.db.Model(&model.ChatModel{}).Where("id = ?", data.Id).Update(data.Filed, data.Value) res := h.DB.Model(&model.ChatModel{}).Where("id = ?", data.Id).Update(data.Filed, data.Value)
if res.Error != nil { if res.Error != nil {
resp.ERROR(c, "更新数据库失败!") resp.ERROR(c, "更新数据库失败!")
return return
@ -140,7 +137,7 @@ func (h *ChatModelHandler) Sort(c *gin.Context) {
} }
for index, id := range data.Ids { for index, id := range data.Ids {
res := h.db.Model(&model.ChatModel{}).Where("id = ?", id).Update("sort_num", data.Sorts[index]) res := h.DB.Model(&model.ChatModel{}).Where("id = ?", id).Update("sort_num", data.Sorts[index])
if res.Error != nil { if res.Error != nil {
resp.ERROR(c, "更新数据库失败!") resp.ERROR(c, "更新数据库失败!")
return return
@ -157,7 +154,7 @@ func (h *ChatModelHandler) Remove(c *gin.Context) {
return return
} }
res := h.db.Where("id = ?", id).Delete(&model.ChatModel{}) res := h.DB.Where("id = ?", id).Delete(&model.ChatModel{})
if res.Error != nil { if res.Error != nil {
resp.ERROR(c, "更新数据库失败!") resp.ERROR(c, "更新数据库失败!")
return return

View File

@ -15,13 +15,10 @@ import (
type ChatRoleHandler struct { type ChatRoleHandler struct {
handler.BaseHandler handler.BaseHandler
db *gorm.DB
} }
func NewChatRoleHandler(app *core.AppServer, db *gorm.DB) *ChatRoleHandler { func NewChatRoleHandler(app *core.AppServer, db *gorm.DB) *ChatRoleHandler {
h := ChatRoleHandler{db: db} return &ChatRoleHandler{BaseHandler: handler.BaseHandler{App: app, DB: db}}
h.App = app
return &h
} }
// Save 创建或者更新某个角色 // Save 创建或者更新某个角色
@ -41,7 +38,7 @@ func (h *ChatRoleHandler) Save(c *gin.Context) {
if data.CreatedAt > 0 { if data.CreatedAt > 0 {
role.CreatedAt = time.Unix(data.CreatedAt, 0) role.CreatedAt = time.Unix(data.CreatedAt, 0)
} }
res := h.db.Save(&role) res := h.DB.Save(&role)
if res.Error != nil { if res.Error != nil {
resp.ERROR(c, "更新数据库失败!") resp.ERROR(c, "更新数据库失败!")
return return
@ -53,14 +50,14 @@ func (h *ChatRoleHandler) Save(c *gin.Context) {
} }
func (h *ChatRoleHandler) List(c *gin.Context) { func (h *ChatRoleHandler) List(c *gin.Context) {
if err := utils.CheckPermission(c, h.db); err != nil { if err := utils.CheckPermission(c, h.DB); err != nil {
resp.NotPermission(c) resp.NotPermission(c)
return return
} }
var items []model.ChatRole var items []model.ChatRole
var roles = make([]vo.ChatRole, 0) var roles = make([]vo.ChatRole, 0)
res := h.db.Order("sort_num ASC").Find(&items) res := h.DB.Order("sort_num ASC").Find(&items)
if res.Error != nil { if res.Error != nil {
resp.ERROR(c, "No data found") resp.ERROR(c, "No data found")
return return
@ -93,7 +90,7 @@ func (h *ChatRoleHandler) Sort(c *gin.Context) {
} }
for index, id := range data.Ids { for index, id := range data.Ids {
res := h.db.Model(&model.ChatRole{}).Where("id = ?", id).Update("sort_num", data.Sorts[index]) res := h.DB.Model(&model.ChatRole{}).Where("id = ?", id).Update("sort_num", data.Sorts[index])
if res.Error != nil { if res.Error != nil {
resp.ERROR(c, "更新数据库失败!") resp.ERROR(c, "更新数据库失败!")
return return
@ -115,7 +112,7 @@ func (h *ChatRoleHandler) Set(c *gin.Context) {
return return
} }
res := h.db.Model(&model.ChatRole{}).Where("id = ?", data.Id).Update(data.Filed, data.Value) res := h.DB.Model(&model.ChatRole{}).Where("id = ?", data.Id).Update(data.Filed, data.Value)
if res.Error != nil { if res.Error != nil {
resp.ERROR(c, "更新数据库失败!") resp.ERROR(c, "更新数据库失败!")
return return
@ -135,7 +132,7 @@ func (h *ChatRoleHandler) Remove(c *gin.Context) {
resp.ERROR(c, types.InvalidArgs) resp.ERROR(c, types.InvalidArgs)
return return
} }
res := h.db.Where("id = ?", data.Id).Delete(&model.ChatRole{}) res := h.DB.Where("id = ?", data.Id).Delete(&model.ChatRole{})
if res.Error != nil { if res.Error != nil {
resp.ERROR(c, "删除失败!") resp.ERROR(c, "删除失败!")
return return

View File

@ -14,13 +14,10 @@ import (
type ConfigHandler struct { type ConfigHandler struct {
handler.BaseHandler handler.BaseHandler
db *gorm.DB
} }
func NewConfigHandler(app *core.AppServer, db *gorm.DB) *ConfigHandler { func NewConfigHandler(app *core.AppServer, db *gorm.DB) *ConfigHandler {
h := ConfigHandler{db: db} return &ConfigHandler{BaseHandler: handler.BaseHandler{App: app, DB: db}}
h.App = app
return &h
} }
func (h *ConfigHandler) Update(c *gin.Context) { func (h *ConfigHandler) Update(c *gin.Context) {
@ -40,7 +37,7 @@ func (h *ConfigHandler) Update(c *gin.Context) {
value := utils.JsonEncode(&data.Config) value := utils.JsonEncode(&data.Config)
config := model.Config{Key: data.Key, Config: value} config := model.Config{Key: data.Key, Config: value}
res := h.db.FirstOrCreate(&config, model.Config{Key: data.Key}) res := h.DB.FirstOrCreate(&config, model.Config{Key: data.Key})
if res.Error != nil { if res.Error != nil {
resp.ERROR(c, res.Error.Error()) resp.ERROR(c, res.Error.Error())
return return
@ -48,7 +45,7 @@ func (h *ConfigHandler) Update(c *gin.Context) {
if config.Id > 0 { if config.Id > 0 {
config.Config = value config.Config = value
res := h.db.Updates(&config) res := h.DB.Updates(&config)
if res.Error != nil { if res.Error != nil {
resp.ERROR(c, res.Error.Error()) resp.ERROR(c, res.Error.Error())
return return
@ -56,7 +53,7 @@ func (h *ConfigHandler) Update(c *gin.Context) {
// update config cache for AppServer // update config cache for AppServer
var cfg model.Config var cfg model.Config
h.db.Where("marker", data.Key).First(&cfg) h.DB.Where("marker", data.Key).First(&cfg)
var err error var err error
if data.Key == "system" { if data.Key == "system" {
err = utils.JsonDecode(cfg.Config, &h.App.SysConfig) err = utils.JsonDecode(cfg.Config, &h.App.SysConfig)
@ -73,14 +70,14 @@ func (h *ConfigHandler) Update(c *gin.Context) {
// Get 获取指定的系统配置 // Get 获取指定的系统配置
func (h *ConfigHandler) Get(c *gin.Context) { func (h *ConfigHandler) Get(c *gin.Context) {
if err := utils.CheckPermission(c, h.db); err != nil { if err := utils.CheckPermission(c, h.DB); err != nil {
resp.NotPermission(c) resp.NotPermission(c)
return return
} }
key := c.Query("key") key := c.Query("key")
var config model.Config var config model.Config
res := h.db.Where("marker", key).First(&config) res := h.DB.Where("marker", key).First(&config)
if res.Error != nil { if res.Error != nil {
resp.ERROR(c, res.Error.Error()) resp.ERROR(c, res.Error.Error())
return return

View File

@ -14,13 +14,10 @@ import (
type DashboardHandler struct { type DashboardHandler struct {
handler.BaseHandler handler.BaseHandler
db *gorm.DB
} }
func NewDashboardHandler(app *core.AppServer, db *gorm.DB) *DashboardHandler { func NewDashboardHandler(app *core.AppServer, db *gorm.DB) *DashboardHandler {
h := DashboardHandler{db: db} return &DashboardHandler{BaseHandler: handler.BaseHandler{App: app, DB: db}}
h.App = app
return &h
} }
type statsVo struct { type statsVo struct {
@ -37,35 +34,35 @@ func (h *DashboardHandler) Stats(c *gin.Context) {
var userCount int64 var userCount int64
now := time.Now() now := time.Now()
zeroTime := time.Date(now.Year(), now.Month(), now.Day(), 0, 0, 0, 0, now.Location()) zeroTime := time.Date(now.Year(), now.Month(), now.Day(), 0, 0, 0, 0, now.Location())
res := h.db.Model(&model.User{}).Where("created_at > ?", zeroTime).Count(&userCount) res := h.DB.Model(&model.User{}).Where("created_at > ?", zeroTime).Count(&userCount)
if res.Error == nil { if res.Error == nil {
stats.Users = userCount stats.Users = userCount
} }
// new chats statistic // new chats statistic
var chatCount int64 var chatCount int64
res = h.db.Model(&model.ChatItem{}).Where("created_at > ?", zeroTime).Count(&chatCount) res = h.DB.Model(&model.ChatItem{}).Where("created_at > ?", zeroTime).Count(&chatCount)
if res.Error == nil { if res.Error == nil {
stats.Chats = chatCount stats.Chats = chatCount
} }
// tokens took stats // tokens took stats
var historyMessages []model.ChatMessage var historyMessages []model.ChatMessage
res = h.db.Where("created_at > ?", zeroTime).Find(&historyMessages) res = h.DB.Where("created_at > ?", zeroTime).Find(&historyMessages)
for _, item := range historyMessages { for _, item := range historyMessages {
stats.Tokens += item.Tokens stats.Tokens += item.Tokens
} }
// 众筹收入 // 众筹收入
var rewards []model.Reward var rewards []model.Reward
res = h.db.Where("created_at > ?", zeroTime).Find(&rewards) res = h.DB.Where("created_at > ?", zeroTime).Find(&rewards)
for _, item := range rewards { for _, item := range rewards {
stats.Income += item.Amount stats.Income += item.Amount
} }
// 订单收入 // 订单收入
var orders []model.Order var orders []model.Order
res = h.db.Where("status = ?", types.OrderPaidSuccess).Where("created_at > ?", zeroTime).Find(&orders) res = h.DB.Where("status = ?", types.OrderPaidSuccess).Where("created_at > ?", zeroTime).Find(&orders)
for _, item := range orders { for _, item := range orders {
stats.Income += item.Amount stats.Income += item.Amount
} }
@ -84,7 +81,7 @@ func (h *DashboardHandler) Stats(c *gin.Context) {
// 统计用户7天增加的曲线 // 统计用户7天增加的曲线
var users []model.User var users []model.User
res = h.db.Model(&model.User{}).Where("created_at > ?", startDate).Find(&users) res = h.DB.Model(&model.User{}).Where("created_at > ?", startDate).Find(&users)
if res.Error == nil { if res.Error == nil {
for _, item := range users { for _, item := range users {
userStatistic[item.CreatedAt.Format("2006-01-02")] += 1 userStatistic[item.CreatedAt.Format("2006-01-02")] += 1
@ -92,20 +89,20 @@ func (h *DashboardHandler) Stats(c *gin.Context) {
} }
// 统计7天Token 消耗 // 统计7天Token 消耗
res = h.db.Where("created_at > ?", startDate).Find(&historyMessages) res = h.DB.Where("created_at > ?", startDate).Find(&historyMessages)
for _, item := range historyMessages { for _, item := range historyMessages {
historyMessagesStatistic[item.CreatedAt.Format("2006-01-02")] += float64(item.Tokens) historyMessagesStatistic[item.CreatedAt.Format("2006-01-02")] += float64(item.Tokens)
} }
// 浮点数相加? // 浮点数相加?
// 统计最近7天的众筹 // 统计最近7天的众筹
res = h.db.Where("created_at > ?", startDate).Find(&rewards) res = h.DB.Where("created_at > ?", startDate).Find(&rewards)
for _, item := range rewards { for _, item := range rewards {
incomeStatistic[item.CreatedAt.Format("2006-01-02")], _ = decimal.NewFromFloat(incomeStatistic[item.CreatedAt.Format("2006-01-02")]).Add(decimal.NewFromFloat(item.Amount)).Float64() incomeStatistic[item.CreatedAt.Format("2006-01-02")], _ = decimal.NewFromFloat(incomeStatistic[item.CreatedAt.Format("2006-01-02")]).Add(decimal.NewFromFloat(item.Amount)).Float64()
} }
// 统计最近7天的订单 // 统计最近7天的订单
res = h.db.Where("status = ?", types.OrderPaidSuccess).Where("created_at > ?", startDate).Find(&orders) res = h.DB.Where("status = ?", types.OrderPaidSuccess).Where("created_at > ?", startDate).Find(&orders)
for _, item := range orders { for _, item := range orders {
incomeStatistic[item.CreatedAt.Format("2006-01-02")], _ = decimal.NewFromFloat(incomeStatistic[item.CreatedAt.Format("2006-01-02")]).Add(decimal.NewFromFloat(item.Amount)).Float64() incomeStatistic[item.CreatedAt.Format("2006-01-02")], _ = decimal.NewFromFloat(incomeStatistic[item.CreatedAt.Format("2006-01-02")]).Add(decimal.NewFromFloat(item.Amount)).Float64()
} }

View File

@ -17,13 +17,10 @@ import (
type FunctionHandler struct { type FunctionHandler struct {
handler.BaseHandler handler.BaseHandler
db *gorm.DB
} }
func NewFunctionHandler(app *core.AppServer, db *gorm.DB) *FunctionHandler { func NewFunctionHandler(app *core.AppServer, db *gorm.DB) *FunctionHandler {
h := FunctionHandler{db: db} return &FunctionHandler{BaseHandler: handler.BaseHandler{App: app, DB: db}}
h.App = app
return &h
} }
func (h *FunctionHandler) Save(c *gin.Context) { func (h *FunctionHandler) Save(c *gin.Context) {
@ -44,7 +41,7 @@ func (h *FunctionHandler) Save(c *gin.Context) {
Enabled: data.Enabled, Enabled: data.Enabled,
} }
res := h.db.Save(&f) res := h.DB.Save(&f)
if res.Error != nil { if res.Error != nil {
resp.ERROR(c, "error with save data:"+res.Error.Error()) resp.ERROR(c, "error with save data:"+res.Error.Error())
return return
@ -65,7 +62,7 @@ func (h *FunctionHandler) Set(c *gin.Context) {
return return
} }
res := h.db.Model(&model.Function{}).Where("id = ?", data.Id).Update(data.Filed, data.Value) res := h.DB.Model(&model.Function{}).Where("id = ?", data.Id).Update(data.Filed, data.Value)
if res.Error != nil { if res.Error != nil {
resp.ERROR(c, "更新数据库失败!") resp.ERROR(c, "更新数据库失败!")
return return
@ -74,13 +71,13 @@ func (h *FunctionHandler) Set(c *gin.Context) {
} }
func (h *FunctionHandler) List(c *gin.Context) { func (h *FunctionHandler) List(c *gin.Context) {
if err := utils.CheckPermission(c, h.db); err != nil { if err := utils.CheckPermission(c, h.DB); err != nil {
resp.NotPermission(c) resp.NotPermission(c)
return return
} }
var items []model.Function var items []model.Function
res := h.db.Find(&items) res := h.DB.Find(&items)
if res.Error != nil { if res.Error != nil {
resp.ERROR(c, "No data found") resp.ERROR(c, "No data found")
return return
@ -102,7 +99,7 @@ func (h *FunctionHandler) Remove(c *gin.Context) {
id := h.GetInt(c, "id", 0) id := h.GetInt(c, "id", 0)
if id > 0 { if id > 0 {
res := h.db.Delete(&model.Function{Id: uint(id)}) res := h.DB.Delete(&model.Function{Id: uint(id)})
if res.Error != nil { if res.Error != nil {
resp.ERROR(c, "更新数据库失败!") resp.ERROR(c, "更新数据库失败!")
return return

View File

@ -15,17 +15,14 @@ import (
type OrderHandler struct { type OrderHandler struct {
handler.BaseHandler handler.BaseHandler
db *gorm.DB
} }
func NewOrderHandler(app *core.AppServer, db *gorm.DB) *OrderHandler { func NewOrderHandler(app *core.AppServer, db *gorm.DB) *OrderHandler {
h := OrderHandler{db: db} return &OrderHandler{BaseHandler: handler.BaseHandler{App: app, DB: db}}
h.App = app
return &h
} }
func (h *OrderHandler) List(c *gin.Context) { func (h *OrderHandler) List(c *gin.Context) {
if err := utils.CheckPermission(c, h.db); err != nil { if err := utils.CheckPermission(c, h.DB); err != nil {
resp.NotPermission(c) resp.NotPermission(c)
return return
} }
@ -42,7 +39,7 @@ func (h *OrderHandler) List(c *gin.Context) {
return return
} }
session := h.db.Session(&gorm.Session{}) session := h.DB.Session(&gorm.Session{})
if data.OrderNo != "" { if data.OrderNo != "" {
session = session.Where("order_no", data.OrderNo) session = session.Where("order_no", data.OrderNo)
} }
@ -82,7 +79,7 @@ func (h *OrderHandler) Remove(c *gin.Context) {
if id > 0 { if id > 0 {
var item model.Order var item model.Order
res := h.db.First(&item, id) res := h.DB.First(&item, id)
if res.Error != nil { if res.Error != nil {
resp.ERROR(c, "记录不存在!") resp.ERROR(c, "记录不存在!")
return return
@ -93,7 +90,7 @@ func (h *OrderHandler) Remove(c *gin.Context) {
return return
} }
res = h.db.Unscoped().Where("id = ?", id).Delete(&model.Order{}) res = h.DB.Unscoped().Where("id = ?", id).Delete(&model.Order{})
if res.Error != nil { if res.Error != nil {
resp.ERROR(c, "更新数据库失败!") resp.ERROR(c, "更新数据库失败!")
return return

View File

@ -15,13 +15,10 @@ import (
type ProductHandler struct { type ProductHandler struct {
handler.BaseHandler handler.BaseHandler
db *gorm.DB
} }
func NewProductHandler(app *core.AppServer, db *gorm.DB) *ProductHandler { func NewProductHandler(app *core.AppServer, db *gorm.DB) *ProductHandler {
h := ProductHandler{db: db} return &ProductHandler{BaseHandler: handler.BaseHandler{App: app, DB: db}}
h.App = app
return &h
} }
func (h *ProductHandler) Save(c *gin.Context) { func (h *ProductHandler) Save(c *gin.Context) {
@ -51,7 +48,7 @@ func (h *ProductHandler) Save(c *gin.Context) {
if item.Id > 0 { if item.Id > 0 {
item.CreatedAt = time.Unix(data.CreatedAt, 0) item.CreatedAt = time.Unix(data.CreatedAt, 0)
} }
res := h.db.Save(&item) res := h.DB.Save(&item)
if res.Error != nil { if res.Error != nil {
resp.ERROR(c, "更新数据库失败!") resp.ERROR(c, "更新数据库失败!")
return return
@ -70,12 +67,12 @@ func (h *ProductHandler) Save(c *gin.Context) {
// List 模型列表 // List 模型列表
func (h *ProductHandler) List(c *gin.Context) { func (h *ProductHandler) List(c *gin.Context) {
if err := utils.CheckPermission(c, h.db); err != nil { if err := utils.CheckPermission(c, h.DB); err != nil {
resp.NotPermission(c) resp.NotPermission(c)
return return
} }
session := h.db.Session(&gorm.Session{}) session := h.DB.Session(&gorm.Session{})
enable := h.GetBool(c, "enable") enable := h.GetBool(c, "enable")
if enable { if enable {
session = session.Where("enabled", enable) session = session.Where("enabled", enable)
@ -111,7 +108,7 @@ func (h *ProductHandler) Enable(c *gin.Context) {
return return
} }
res := h.db.Model(&model.Product{}).Where("id = ?", data.Id).Update("enabled", data.Enabled) res := h.DB.Model(&model.Product{}).Where("id = ?", data.Id).Update("enabled", data.Enabled)
if res.Error != nil { if res.Error != nil {
resp.ERROR(c, "更新数据库失败!") resp.ERROR(c, "更新数据库失败!")
return return
@ -131,7 +128,7 @@ func (h *ProductHandler) Sort(c *gin.Context) {
} }
for index, id := range data.Ids { for index, id := range data.Ids {
res := h.db.Model(&model.Product{}).Where("id = ?", id).Update("sort_num", data.Sorts[index]) res := h.DB.Model(&model.Product{}).Where("id = ?", id).Update("sort_num", data.Sorts[index])
if res.Error != nil { if res.Error != nil {
resp.ERROR(c, "更新数据库失败!") resp.ERROR(c, "更新数据库失败!")
return return
@ -145,7 +142,7 @@ func (h *ProductHandler) Remove(c *gin.Context) {
id := h.GetInt(c, "id", 0) id := h.GetInt(c, "id", 0)
if id > 0 { if id > 0 {
res := h.db.Where("id = ?", id).Delete(&model.Product{}) res := h.DB.Where("id = ?", id).Delete(&model.Product{})
if res.Error != nil { if res.Error != nil {
resp.ERROR(c, "更新数据库失败!") resp.ERROR(c, "更新数据库失败!")
return return

View File

@ -14,23 +14,20 @@ import (
type RewardHandler struct { type RewardHandler struct {
handler.BaseHandler handler.BaseHandler
db *gorm.DB
} }
func NewRewardHandler(app *core.AppServer, db *gorm.DB) *RewardHandler { func NewRewardHandler(app *core.AppServer, db *gorm.DB) *RewardHandler {
h := RewardHandler{db: db} return &RewardHandler{BaseHandler: handler.BaseHandler{App: app, DB: db}}
h.App = app
return &h
} }
func (h *RewardHandler) List(c *gin.Context) { func (h *RewardHandler) List(c *gin.Context) {
if err := utils.CheckPermission(c, h.db); err != nil { if err := utils.CheckPermission(c, h.DB); err != nil {
resp.NotPermission(c) resp.NotPermission(c)
return return
} }
var items []model.Reward var items []model.Reward
res := h.db.Order("id DESC").Find(&items) res := h.DB.Order("id DESC").Find(&items)
var rewards = make([]vo.Reward, 0) var rewards = make([]vo.Reward, 0)
if res.Error == nil { if res.Error == nil {
userIds := make([]uint, 0) userIds := make([]uint, 0)
@ -38,7 +35,7 @@ func (h *RewardHandler) List(c *gin.Context) {
userIds = append(userIds, v.UserId) userIds = append(userIds, v.UserId)
} }
var users []model.User var users []model.User
h.db.Where("id IN ?", userIds).Find(&users) h.DB.Where("id IN ?", userIds).Find(&users)
var userMap = make(map[uint]model.User) var userMap = make(map[uint]model.User)
for _, u := range users { for _, u := range users {
userMap[u.Id] = u userMap[u.Id] = u
@ -71,7 +68,7 @@ func (h *RewardHandler) Remove(c *gin.Context) {
return return
} }
if data.Id > 0 { if data.Id > 0 {
res := h.db.Where("id = ?", data.Id).Delete(&model.Reward{}) res := h.DB.Where("id = ?", data.Id).Delete(&model.Reward{})
if res.Error != nil { if res.Error != nil {
resp.ERROR(c, "更新数据库失败!") resp.ERROR(c, "更新数据库失败!")
return return

View File

@ -13,14 +13,11 @@ import (
type UploadHandler struct { type UploadHandler struct {
handler.BaseHandler handler.BaseHandler
db *gorm.DB
uploaderManager *oss.UploaderManager uploaderManager *oss.UploaderManager
} }
func NewUploadHandler(app *core.AppServer, db *gorm.DB, manager *oss.UploaderManager) *UploadHandler { func NewUploadHandler(app *core.AppServer, db *gorm.DB, manager *oss.UploaderManager) *UploadHandler {
adminHandler := &UploadHandler{db: db, uploaderManager: manager} return &UploadHandler{BaseHandler: handler.BaseHandler{DB: db, App: app}, uploaderManager: manager}
adminHandler.App = app
return adminHandler
} }
func (h *UploadHandler) Upload(c *gin.Context) { func (h *UploadHandler) Upload(c *gin.Context) {
@ -30,7 +27,7 @@ func (h *UploadHandler) Upload(c *gin.Context) {
return return
} }
userId := 0 userId := 0
res := h.db.Create(&model.File{ res := h.DB.Create(&model.File{
UserId: userId, UserId: userId,
Name: file.Name, Name: file.Name,
ObjKey: file.ObjKey, ObjKey: file.ObjKey,

View File

@ -16,18 +16,15 @@ import (
type UserHandler struct { type UserHandler struct {
handler.BaseHandler handler.BaseHandler
db *gorm.DB
} }
func NewUserHandler(app *core.AppServer, db *gorm.DB) *UserHandler { func NewUserHandler(app *core.AppServer, db *gorm.DB) *UserHandler {
h := UserHandler{db: db} return &UserHandler{BaseHandler: handler.BaseHandler{App: app, DB: db}}
h.App = app
return &h
} }
// List 用户列表 // List 用户列表
func (h *UserHandler) List(c *gin.Context) { func (h *UserHandler) List(c *gin.Context) {
if err := utils.CheckPermission(c, h.db); err != nil { if err := utils.CheckPermission(c, h.DB); err != nil {
resp.NotPermission(c) resp.NotPermission(c)
return return
} }
@ -41,7 +38,7 @@ func (h *UserHandler) List(c *gin.Context) {
var users = make([]vo.User, 0) var users = make([]vo.User, 0)
var total int64 var total int64
session := h.db.Session(&gorm.Session{}) session := h.DB.Session(&gorm.Session{})
if username != "" { if username != "" {
session = session.Where("username LIKE ?", "%"+username+"%") session = session.Where("username LIKE ?", "%"+username+"%")
} }
@ -87,7 +84,7 @@ func (h *UserHandler) Save(c *gin.Context) {
if data.Id > 0 { // 更新 if data.Id > 0 { // 更新
user.Id = data.Id user.Id = data.Id
// 此处需要用 map 更新,用结构体无法更新 0 值 // 此处需要用 map 更新,用结构体无法更新 0 值
res = h.db.Model(&user).Updates(map[string]interface{}{ res = h.DB.Model(&user).Updates(map[string]interface{}{
"username": data.Username, "username": data.Username,
"status": data.Status, "status": data.Status,
"vip": data.Vip, "vip": data.Vip,
@ -108,7 +105,7 @@ func (h *UserHandler) Save(c *gin.Context) {
ChatModels: utils.JsonEncode(data.ChatModels), ChatModels: utils.JsonEncode(data.ChatModels),
ExpiredTime: utils.Str2stamp(data.ExpiredTime), ExpiredTime: utils.Str2stamp(data.ExpiredTime),
} }
res = h.db.Create(&u) res = h.DB.Create(&u)
_ = utils.CopyObject(u, &userVo) _ = utils.CopyObject(u, &userVo)
userVo.Id = u.Id userVo.Id = u.Id
userVo.CreatedAt = u.CreatedAt.Unix() userVo.CreatedAt = u.CreatedAt.Unix()
@ -135,7 +132,7 @@ func (h *UserHandler) ResetPass(c *gin.Context) {
} }
var user model.User var user model.User
res := h.db.First(&user, data.Id) res := h.DB.First(&user, data.Id)
if res.Error != nil { if res.Error != nil {
resp.ERROR(c, "No user found") resp.ERROR(c, "No user found")
return return
@ -143,7 +140,7 @@ func (h *UserHandler) ResetPass(c *gin.Context) {
password := utils.GenPassword(data.Password, user.Salt) password := utils.GenPassword(data.Password, user.Salt)
user.Password = password user.Password = password
res = h.db.Updates(&user) res = h.DB.Updates(&user)
if res.Error != nil { if res.Error != nil {
resp.ERROR(c) resp.ERROR(c)
} else { } else {
@ -152,43 +149,33 @@ func (h *UserHandler) ResetPass(c *gin.Context) {
} }
func (h *UserHandler) Remove(c *gin.Context) { func (h *UserHandler) Remove(c *gin.Context) {
var data struct { id := h.GetInt(c, "id", 0)
Id uint if id <= 0 {
}
if err := c.ShouldBindJSON(&data); err != nil {
resp.ERROR(c, types.InvalidArgs) resp.ERROR(c, types.InvalidArgs)
return return
} }
if data.Id > 0 { // 删除用户
tx := h.db.Begin() res := h.DB.Where("id = ?", id).Delete(&model.User{})
res := h.db.Where("id = ?", data.Id).Delete(&model.User{}) if res.Error != nil {
if res.Error != nil { resp.ERROR(c, "删除失败")
resp.ERROR(c, "删除失败") return
return
}
// 删除聊天记录
res = h.db.Where("user_id = ?", data.Id).Delete(&model.ChatItem{})
if res.Error != nil {
tx.Rollback()
resp.ERROR(c, "删除失败")
return
}
// 删除聊天历史记录
res = h.db.Where("user_id = ?", data.Id).Delete(&model.ChatMessage{})
if res.Error != nil {
tx.Rollback()
resp.ERROR(c, "删除失败")
return
}
// 删除登录日志
res = h.db.Where("user_id = ?", data.Id).Delete(&model.UserLoginLog{})
if res.Error != nil {
tx.Rollback()
resp.ERROR(c, "删除失败")
return
}
tx.Commit()
} }
// 删除聊天记录
h.DB.Where("user_id = ?", id).Delete(&model.ChatItem{})
// 删除聊天历史记录
h.DB.Where("user_id = ?", id).Delete(&model.ChatMessage{})
// 删除登录日志
h.DB.Where("user_id = ?", id).Delete(&model.UserLoginLog{})
// 删除算力日志
h.DB.Where("user_id = ?", id).Delete(&model.PowerLog{})
// 删除众筹日志
h.DB.Where("user_id = ?", id).Delete(&model.Reward{})
// 删除绘图任务
h.DB.Where("user_id = ?", id).Delete(&model.MidJourneyJob{})
h.DB.Where("user_id = ?", id).Delete(&model.SdJob{})
// 删除订单
h.DB.Where("user_id = ?", id).Delete(&model.Order{})
resp.SUCCESS(c) resp.SUCCESS(c)
} }
@ -196,10 +183,10 @@ func (h *UserHandler) LoginLog(c *gin.Context) {
page := h.GetInt(c, "page", 1) page := h.GetInt(c, "page", 1)
pageSize := h.GetInt(c, "page_size", 20) pageSize := h.GetInt(c, "page_size", 20)
var total int64 var total int64
h.db.Model(&model.UserLoginLog{}).Count(&total) h.DB.Model(&model.UserLoginLog{}).Count(&total)
offset := (page - 1) * pageSize offset := (page - 1) * pageSize
var items []model.UserLoginLog var items []model.UserLoginLog
res := h.db.Offset(offset).Limit(pageSize).Order("id DESC").Find(&items) res := h.DB.Offset(offset).Limit(pageSize).Order("id DESC").Find(&items)
if res.Error != nil { if res.Error != nil {
resp.ERROR(c, "获取数据失败") resp.ERROR(c, "获取数据失败")
return return

View File

@ -4,8 +4,11 @@ import (
"chatplus/core" "chatplus/core"
"chatplus/core/types" "chatplus/core/types"
logger2 "chatplus/logger" logger2 "chatplus/logger"
"chatplus/store/model"
"chatplus/utils" "chatplus/utils"
"errors"
"fmt" "fmt"
"gorm.io/gorm"
"strings" "strings"
"github.com/gin-gonic/gin" "github.com/gin-gonic/gin"
@ -15,6 +18,7 @@ var logger = logger2.GetLogger()
type BaseHandler struct { type BaseHandler struct {
App *core.AppServer App *core.AppServer
DB *gorm.DB
} }
func (h *BaseHandler) GetTrim(c *gin.Context, key string) string { func (h *BaseHandler) GetTrim(c *gin.Context, key string) string {
@ -57,3 +61,27 @@ func (h *BaseHandler) GetLoginUserId(c *gin.Context) uint {
} }
return uint(utils.IntValue(utils.InterfaceToString(userId), 0)) return uint(utils.IntValue(utils.InterfaceToString(userId), 0))
} }
func (h *BaseHandler) IsLogin(c *gin.Context) bool {
return h.GetLoginUserId(c) > 0
}
func (h *BaseHandler) GetLoginUser(c *gin.Context) (model.User, error) {
value, exists := c.Get(types.LoginUserCache)
if exists {
return value.(model.User), nil
}
userId, ok := c.Get(types.LoginUserID)
if !ok {
return model.User{}, errors.New("user not login")
}
var user model.User
res := h.DB.First(&user, userId)
// 更新缓存
if res.Error == nil {
c.Set(types.LoginUserCache, user)
}
return user, res.Error
}

View File

@ -12,37 +12,34 @@ import (
type ChatModelHandler struct { type ChatModelHandler struct {
BaseHandler BaseHandler
db *gorm.DB
} }
func NewChatModelHandler(app *core.AppServer, db *gorm.DB) *ChatModelHandler { func NewChatModelHandler(app *core.AppServer, db *gorm.DB) *ChatModelHandler {
h := ChatModelHandler{db: db} return &ChatModelHandler{BaseHandler: BaseHandler{App: app, DB: db}}
h.App = app
return &h
} }
// List 模型列表 // List 模型列表
func (h *ChatModelHandler) List(c *gin.Context) { func (h *ChatModelHandler) List(c *gin.Context) {
var items []model.ChatModel var items []model.ChatModel
var chatModels = make([]vo.ChatModel, 0) var chatModels = make([]vo.ChatModel, 0)
// 只加载用户订阅的 AI 模型 var res *gorm.DB
user, err := utils.GetLoginUser(c, h.db) // 如果用户没有登录,则加载所有开放模型
if err != nil { if !h.IsLogin(c) {
resp.NotAuth(c) res = h.DB.Where("enabled = ?", true).Where("open =?", true).Order("sort_num ASC").Find(&items)
return } else {
user, _ := h.GetLoginUser(c)
var models []int
err := utils.JsonDecode(user.ChatModels, &models)
if err != nil {
resp.ERROR(c, "当前用户没有订阅任何模型")
return
}
// 查询用户有权限访问的模型以及所有开放的模型
res = h.DB.Where("enabled = ?", true).Where(
h.DB.Where("id IN ?", models).Or("open =?", true),
).Order("sort_num ASC").Find(&items)
} }
var models []int
err = utils.JsonDecode(user.ChatModels, &models)
if err != nil {
resp.ERROR(c, "当前用户没有订阅任何模型")
return
}
// 查询用户有权限访问的模型以及所有开放的模型
res := h.db.Where("enabled = ?", true).Where(
h.db.Where("id IN ?", models).Or("open =?", true),
).Order("sort_num ASC").Find(&items)
if res.Error == nil { if res.Error == nil {
for _, item := range items { for _, item := range items {
var cm vo.ChatModel var cm vo.ChatModel

View File

@ -14,27 +14,24 @@ import (
type ChatRoleHandler struct { type ChatRoleHandler struct {
BaseHandler BaseHandler
db *gorm.DB
} }
func NewChatRoleHandler(app *core.AppServer, db *gorm.DB) *ChatRoleHandler { func NewChatRoleHandler(app *core.AppServer, db *gorm.DB) *ChatRoleHandler {
handler := &ChatRoleHandler{db: db} return &ChatRoleHandler{BaseHandler: BaseHandler{App: app, DB: db}}
handler.App = app
return handler
} }
// List get user list // List 获取用户聊天应用列表
func (h *ChatRoleHandler) List(c *gin.Context) { func (h *ChatRoleHandler) List(c *gin.Context) {
all := h.GetBool(c, "all") userId := h.GetLoginUserId(c)
var roles []model.ChatRole var roles []model.ChatRole
res := h.db.Where("enable", true).Order("sort_num ASC").Find(&roles) res := h.DB.Where("enable", true).Order("sort_num ASC").Find(&roles)
if res.Error != nil { if res.Error != nil {
resp.ERROR(c, "No roles found,"+res.Error.Error()) resp.ERROR(c, "No roles found,"+res.Error.Error())
return return
} }
// 获取所有角色 // 获取所有角色
if all { if userId == 0 {
// 转成 vo // 转成 vo
var roleVos = make([]vo.ChatRole, 0) var roleVos = make([]vo.ChatRole, 0)
for _, r := range roles { for _, r := range roles {
@ -49,13 +46,8 @@ func (h *ChatRoleHandler) List(c *gin.Context) {
return return
} }
userId := h.GetInt(c, "user_id", 0)
if userId == 0 {
resp.NotAuth(c)
return
}
var user model.User var user model.User
h.db.First(&user, userId) h.DB.First(&user, userId)
var roleKeys []string var roleKeys []string
err := utils.JsonDecode(user.ChatRoles, &roleKeys) err := utils.JsonDecode(user.ChatRoles, &roleKeys)
if err != nil { if err != nil {
@ -80,7 +72,7 @@ func (h *ChatRoleHandler) List(c *gin.Context) {
// UpdateRole 更新用户聊天角色 // UpdateRole 更新用户聊天角色
func (h *ChatRoleHandler) UpdateRole(c *gin.Context) { func (h *ChatRoleHandler) UpdateRole(c *gin.Context) {
user, err := utils.GetLoginUser(c, h.db) user, err := h.GetLoginUser(c)
if err != nil { if err != nil {
resp.NotAuth(c) resp.NotAuth(c)
return return
@ -94,7 +86,7 @@ func (h *ChatRoleHandler) UpdateRole(c *gin.Context) {
return return
} }
res := h.db.Model(&model.User{}).Where("id = ?", user.Id).UpdateColumn("chat_roles_json", utils.JsonEncode(data.Keys)) res := h.DB.Model(&model.User{}).Where("id = ?", user.Id).UpdateColumn("chat_roles_json", utils.JsonEncode(data.Keys))
if res.Error != nil { if res.Error != nil {
logger.Error("添加应用失败:", err) logger.Error("添加应用失败:", err)
resp.ERROR(c, "更新数据库失败!") resp.ERROR(c, "更新数据库失败!")

View File

@ -136,7 +136,7 @@ func (h *ChatHandler) sendAzureMessage(
} }
historyUserMsg.CreatedAt = promptCreatedAt historyUserMsg.CreatedAt = promptCreatedAt
historyUserMsg.UpdatedAt = promptCreatedAt historyUserMsg.UpdatedAt = promptCreatedAt
res := h.db.Save(&historyUserMsg) res := h.DB.Save(&historyUserMsg)
if res.Error != nil { if res.Error != nil {
logger.Error("failed to save prompt history message: ", res.Error) logger.Error("failed to save prompt history message: ", res.Error)
} }
@ -158,7 +158,7 @@ func (h *ChatHandler) sendAzureMessage(
} }
historyReplyMsg.CreatedAt = replyCreatedAt historyReplyMsg.CreatedAt = replyCreatedAt
historyReplyMsg.UpdatedAt = replyCreatedAt historyReplyMsg.UpdatedAt = replyCreatedAt
res = h.db.Create(&historyReplyMsg) res = h.DB.Create(&historyReplyMsg)
if res.Error != nil { if res.Error != nil {
logger.Error("failed to save reply history message: ", res.Error) logger.Error("failed to save reply history message: ", res.Error)
} }
@ -168,7 +168,7 @@ func (h *ChatHandler) sendAzureMessage(
// 保存当前会话 // 保存当前会话
var chatItem model.ChatItem var chatItem model.ChatItem
res = h.db.Where("chat_id = ?", session.ChatId).First(&chatItem) res = h.DB.Where("chat_id = ?", session.ChatId).First(&chatItem)
if res.Error != nil { if res.Error != nil {
chatItem.ChatId = session.ChatId chatItem.ChatId = session.ChatId
chatItem.UserId = session.UserId chatItem.UserId = session.UserId
@ -180,7 +180,7 @@ func (h *ChatHandler) sendAzureMessage(
chatItem.Title = prompt chatItem.Title = prompt
} }
chatItem.Model = req.Model chatItem.Model = req.Model
h.db.Create(&chatItem) h.DB.Create(&chatItem)
} }
} }
} else { } else {

View File

@ -160,7 +160,7 @@ func (h *ChatHandler) sendBaiduMessage(
} }
historyUserMsg.CreatedAt = promptCreatedAt historyUserMsg.CreatedAt = promptCreatedAt
historyUserMsg.UpdatedAt = promptCreatedAt historyUserMsg.UpdatedAt = promptCreatedAt
res := h.db.Save(&historyUserMsg) res := h.DB.Save(&historyUserMsg)
if res.Error != nil { if res.Error != nil {
logger.Error("failed to save prompt history message: ", res.Error) logger.Error("failed to save prompt history message: ", res.Error)
} }
@ -182,7 +182,7 @@ func (h *ChatHandler) sendBaiduMessage(
} }
historyReplyMsg.CreatedAt = replyCreatedAt historyReplyMsg.CreatedAt = replyCreatedAt
historyReplyMsg.UpdatedAt = replyCreatedAt historyReplyMsg.UpdatedAt = replyCreatedAt
res = h.db.Create(&historyReplyMsg) res = h.DB.Create(&historyReplyMsg)
if res.Error != nil { if res.Error != nil {
logger.Error("failed to save reply history message: ", res.Error) logger.Error("failed to save reply history message: ", res.Error)
} }
@ -191,7 +191,7 @@ func (h *ChatHandler) sendBaiduMessage(
// 保存当前会话 // 保存当前会话
var chatItem model.ChatItem var chatItem model.ChatItem
res = h.db.Where("chat_id = ?", session.ChatId).First(&chatItem) res = h.DB.Where("chat_id = ?", session.ChatId).First(&chatItem)
if res.Error != nil { if res.Error != nil {
chatItem.ChatId = session.ChatId chatItem.ChatId = session.ChatId
chatItem.UserId = session.UserId chatItem.UserId = session.UserId
@ -203,7 +203,7 @@ func (h *ChatHandler) sendBaiduMessage(
chatItem.Title = prompt chatItem.Title = prompt
} }
chatItem.Model = req.Model chatItem.Model = req.Model
h.db.Create(&chatItem) h.DB.Create(&chatItem)
} }
} }
} else { } else {

View File

@ -35,19 +35,16 @@ var logger = logger2.GetLogger()
type ChatHandler struct { type ChatHandler struct {
handler.BaseHandler handler.BaseHandler
db *gorm.DB
redis *redis.Client redis *redis.Client
uploadManager *oss.UploaderManager uploadManager *oss.UploaderManager
} }
func NewChatHandler(app *core.AppServer, db *gorm.DB, redis *redis.Client, manager *oss.UploaderManager) *ChatHandler { func NewChatHandler(app *core.AppServer, db *gorm.DB, redis *redis.Client, manager *oss.UploaderManager) *ChatHandler {
h := ChatHandler{ return &ChatHandler{
db: db, BaseHandler: handler.BaseHandler{App: app, DB: db},
redis: redis, redis: redis,
uploadManager: manager, uploadManager: manager,
} }
h.App = app
return &h
} }
func (h *ChatHandler) Init() { func (h *ChatHandler) Init() {
@ -73,7 +70,7 @@ func (h *ChatHandler) ChatHandle(c *gin.Context) {
client := types.NewWsClient(ws) client := types.NewWsClient(ws)
// get model info // get model info
var chatModel model.ChatModel var chatModel model.ChatModel
res := h.db.First(&chatModel, modelId) res := h.DB.First(&chatModel, modelId)
if res.Error != nil || chatModel.Enabled == false { if res.Error != nil || chatModel.Enabled == false {
utils.ReplyMessage(client, "当前AI模型暂未启用连接已关闭") utils.ReplyMessage(client, "当前AI模型暂未启用连接已关闭")
c.Abort() c.Abort()
@ -82,7 +79,7 @@ func (h *ChatHandler) ChatHandle(c *gin.Context) {
session := h.App.ChatSession.Get(sessionId) session := h.App.ChatSession.Get(sessionId)
if session == nil { if session == nil {
user, err := utils.GetLoginUser(c, h.db) user, err := h.GetLoginUser(c)
if err != nil { if err != nil {
logger.Info("用户未登录") logger.Info("用户未登录")
c.Abort() c.Abort()
@ -99,7 +96,7 @@ func (h *ChatHandler) ChatHandle(c *gin.Context) {
// use old chat data override the chat model and role ID // use old chat data override the chat model and role ID
var chat model.ChatItem var chat model.ChatItem
res = h.db.Where("chat_id = ?", chatId).First(&chat) res = h.DB.Where("chat_id = ?", chatId).First(&chat)
if res.Error == nil { if res.Error == nil {
chatModel.Id = chat.ModelId chatModel.Id = chat.ModelId
roleId = int(chat.RoleId) roleId = int(chat.RoleId)
@ -116,7 +113,7 @@ func (h *ChatHandler) ChatHandle(c *gin.Context) {
Platform: types.Platform(chatModel.Platform)} Platform: types.Platform(chatModel.Platform)}
logger.Infof("New websocket connected, IP: %s, Username: %s", c.ClientIP(), session.Username) logger.Infof("New websocket connected, IP: %s, Username: %s", c.ClientIP(), session.Username)
var chatRole model.ChatRole var chatRole model.ChatRole
res = h.db.First(&chatRole, roleId) res = h.DB.First(&chatRole, roleId)
if res.Error != nil || !chatRole.Enable { if res.Error != nil || !chatRole.Enable {
utils.ReplyMessage(client, "当前聊天角色不存在或者未启用,连接已关闭!!!") utils.ReplyMessage(client, "当前聊天角色不存在或者未启用,连接已关闭!!!")
c.Abort() c.Abort()
@ -181,7 +178,7 @@ func (h *ChatHandler) sendMessage(ctx context.Context, session *types.ChatSessio
} }
var user model.User var user model.User
res := h.db.Model(&model.User{}).First(&user, session.UserId) res := h.DB.Model(&model.User{}).First(&user, session.UserId)
if res.Error != nil { if res.Error != nil {
utils.ReplyMessage(ws, "非法用户,请联系管理员!") utils.ReplyMessage(ws, "非法用户,请联系管理员!")
return res.Error return res.Error
@ -238,7 +235,7 @@ func (h *ChatHandler) sendMessage(ctx context.Context, session *types.ChatSessio
req.MaxTokens = session.Model.MaxTokens req.MaxTokens = session.Model.MaxTokens
// OpenAI 支持函数功能 // OpenAI 支持函数功能
var items []model.Function var items []model.Function
res := h.db.Where("enabled", true).Find(&items) res := h.DB.Where("enabled", true).Find(&items)
if res.Error != nil { if res.Error != nil {
break break
} }
@ -290,7 +287,7 @@ func (h *ChatHandler) sendMessage(ctx context.Context, session *types.ChatSessio
_ = utils.JsonDecode(role.Context, &messages) _ = utils.JsonDecode(role.Context, &messages)
if h.App.SysConfig.ContextDeep > 0 { if h.App.SysConfig.ContextDeep > 0 {
var historyMessages []model.ChatMessage var historyMessages []model.ChatMessage
res := h.db.Where("chat_id = ? and use_context = 1", session.ChatId).Limit(h.App.SysConfig.ContextDeep).Order("id DESC").Find(&historyMessages) res := h.DB.Where("chat_id = ? and use_context = 1", session.ChatId).Limit(h.App.SysConfig.ContextDeep).Order("id DESC").Find(&historyMessages)
if res.Error == nil { if res.Error == nil {
for i := len(historyMessages) - 1; i >= 0; i-- { for i := len(historyMessages) - 1; i >= 0; i-- {
msg := historyMessages[i] msg := historyMessages[i]
@ -382,7 +379,7 @@ func (h *ChatHandler) Tokens(c *gin.Context) {
if data.Text == "" && data.ChatId != "" { if data.Text == "" && data.ChatId != "" {
var item model.ChatMessage var item model.ChatMessage
userId, _ := c.Get(types.LoginUserID) userId, _ := c.Get(types.LoginUserID)
res := h.db.Where("user_id = ?", userId).Where("chat_id = ?", data.ChatId).Last(&item) res := h.DB.Where("user_id = ?", userId).Where("chat_id = ?", data.ChatId).Last(&item)
if res.Error != nil { if res.Error != nil {
resp.ERROR(c, res.Error.Error()) resp.ERROR(c, res.Error.Error())
return return
@ -433,7 +430,7 @@ func (h *ChatHandler) StopGenerate(c *gin.Context) {
// 发送请求到 OpenAI 服务器 // 发送请求到 OpenAI 服务器
// useOwnApiKey: 是否使用了用户自己的 API KEY // useOwnApiKey: 是否使用了用户自己的 API KEY
func (h *ChatHandler) doRequest(ctx context.Context, req types.ApiRequest, platform types.Platform, apiKey *model.ApiKey) (*http.Response, error) { func (h *ChatHandler) doRequest(ctx context.Context, req types.ApiRequest, platform types.Platform, apiKey *model.ApiKey) (*http.Response, error) {
res := h.db.Where("platform = ?", platform).Where("type = ?", "chat").Where("enabled = ?", true).Order("last_used_at ASC").First(apiKey) res := h.DB.Where("platform = ?", platform).Where("type = ?", "chat").Where("enabled = ?", true).Order("last_used_at ASC").First(apiKey)
if res.Error != nil { if res.Error != nil {
return nil, errors.New("no available key, please import key") return nil, errors.New("no available key, please import key")
} }
@ -459,7 +456,7 @@ func (h *ChatHandler) doRequest(ctx context.Context, req types.ApiRequest, platf
apiURL = apiKey.ApiURL apiURL = apiKey.ApiURL
} }
// 更新 API KEY 的最后使用时间 // 更新 API KEY 的最后使用时间
h.db.Model(apiKey).UpdateColumn("last_used_at", time.Now().Unix()) h.DB.Model(apiKey).UpdateColumn("last_used_at", time.Now().Unix())
// 百度文心,需要串接 access_token // 百度文心,需要串接 access_token
if platform == types.Baidu { if platform == types.Baidu {
token, err := h.getBaiduToken(apiKey.Value) token, err := h.getBaiduToken(apiKey.Value)
@ -527,10 +524,10 @@ func (h *ChatHandler) subUserPower(userVo vo.User, session *types.ChatSession, p
if session.Model.Power > 0 { if session.Model.Power > 0 {
power = session.Model.Power power = session.Model.Power
} }
res := h.db.Model(&model.User{}).Where("id = ?", userVo.Id).UpdateColumn("power", gorm.Expr("power - ?", power)) res := h.DB.Model(&model.User{}).Where("id = ?", userVo.Id).UpdateColumn("power", gorm.Expr("power - ?", power))
if res.Error == nil { if res.Error == nil {
// 记录算力消费日志 // 记录算力消费日志
h.db.Create(&model.PowerLog{ h.DB.Create(&model.PowerLog{
UserId: userVo.Id, UserId: userVo.Id,
Username: userVo.Username, Username: userVo.Username,
Type: types.PowerConsume, Type: types.PowerConsume,

View File

@ -13,28 +13,22 @@ import (
// List 获取会话列表 // List 获取会话列表
func (h *ChatHandler) List(c *gin.Context) { func (h *ChatHandler) List(c *gin.Context) {
userId := h.GetInt(c, "user_id", 0) if !h.IsLogin(c) {
if userId == 0 { resp.SUCCESS(c)
resp.ERROR(c, "The parameter 'user_id' is needed.")
return
}
// fix: 只能读取本人的消息列表
if uint(userId) != h.GetLoginUserId(c) {
resp.ERROR(c, "Hacker attempt, you can ONLY get yourself chats.")
return return
} }
userId := h.GetLoginUserId(c)
var items = make([]vo.ChatItem, 0) var items = make([]vo.ChatItem, 0)
var chats []model.ChatItem var chats []model.ChatItem
res := h.db.Where("user_id = ?", userId).Order("id DESC").Find(&chats) res := h.DB.Where("user_id = ?", userId).Order("id DESC").Find(&chats)
if res.Error == nil { if res.Error == nil {
var roleIds = make([]uint, 0) var roleIds = make([]uint, 0)
for _, chat := range chats { for _, chat := range chats {
roleIds = append(roleIds, chat.RoleId) roleIds = append(roleIds, chat.RoleId)
} }
var roles []model.ChatRole var roles []model.ChatRole
res = h.db.Find(&roles, roleIds) res = h.DB.Find(&roles, roleIds)
if res.Error == nil { if res.Error == nil {
roleMap := make(map[uint]model.ChatRole) roleMap := make(map[uint]model.ChatRole)
for _, role := range roles { for _, role := range roles {
@ -66,7 +60,7 @@ func (h *ChatHandler) Update(c *gin.Context) {
resp.ERROR(c, types.InvalidArgs) resp.ERROR(c, types.InvalidArgs)
return return
} }
res := h.db.Model(&model.ChatItem{}).Where("chat_id = ?", data.ChatId).UpdateColumn("title", data.Title) res := h.DB.Model(&model.ChatItem{}).Where("chat_id = ?", data.ChatId).UpdateColumn("title", data.Title)
if res.Error != nil { if res.Error != nil {
resp.ERROR(c, "Failed to update database") resp.ERROR(c, "Failed to update database")
return return
@ -78,14 +72,14 @@ func (h *ChatHandler) Update(c *gin.Context) {
// Clear 清空所有聊天记录 // Clear 清空所有聊天记录
func (h *ChatHandler) Clear(c *gin.Context) { func (h *ChatHandler) Clear(c *gin.Context) {
// 获取当前登录用户所有的聊天会话 // 获取当前登录用户所有的聊天会话
user, err := utils.GetLoginUser(c, h.db) user, err := h.GetLoginUser(c)
if err != nil { if err != nil {
resp.NotAuth(c) resp.NotAuth(c)
return return
} }
var chats []model.ChatItem var chats []model.ChatItem
res := h.db.Where("user_id = ?", user.Id).Find(&chats) res := h.DB.Where("user_id = ?", user.Id).Find(&chats)
if res.Error != nil { if res.Error != nil {
resp.ERROR(c, "No chats found") resp.ERROR(c, "No chats found")
return return
@ -97,13 +91,13 @@ func (h *ChatHandler) Clear(c *gin.Context) {
// 清空会话上下文 // 清空会话上下文
h.App.ChatContexts.Delete(chat.ChatId) h.App.ChatContexts.Delete(chat.ChatId)
} }
err = h.db.Transaction(func(tx *gorm.DB) error { err = h.DB.Transaction(func(tx *gorm.DB) error {
res := h.db.Where("user_id =?", user.Id).Delete(&model.ChatItem{}) res := h.DB.Where("user_id =?", user.Id).Delete(&model.ChatItem{})
if res.Error != nil { if res.Error != nil {
return res.Error return res.Error
} }
res = h.db.Where("user_id = ? AND chat_id IN ?", user.Id, chatIds).Delete(&model.ChatMessage{}) res = h.DB.Where("user_id = ? AND chat_id IN ?", user.Id, chatIds).Delete(&model.ChatMessage{})
if res.Error != nil { if res.Error != nil {
return res.Error return res.Error
} }
@ -126,7 +120,7 @@ func (h *ChatHandler) History(c *gin.Context) {
chatId := c.Query("chat_id") // 会话 ID chatId := c.Query("chat_id") // 会话 ID
var items []model.ChatMessage var items []model.ChatMessage
var messages = make([]vo.HistoryMessage, 0) var messages = make([]vo.HistoryMessage, 0)
res := h.db.Where("chat_id = ?", chatId).Find(&items) res := h.DB.Where("chat_id = ?", chatId).Find(&items)
if res.Error != nil { if res.Error != nil {
resp.ERROR(c, "No history message") resp.ERROR(c, "No history message")
return return
@ -152,20 +146,20 @@ func (h *ChatHandler) Remove(c *gin.Context) {
resp.ERROR(c, types.InvalidArgs) resp.ERROR(c, types.InvalidArgs)
return return
} }
user, err := utils.GetLoginUser(c, h.db) user, err := h.GetLoginUser(c)
if err != nil { if err != nil {
resp.NotAuth(c) resp.NotAuth(c)
return return
} }
res := h.db.Where("user_id = ? AND chat_id = ?", user.Id, chatId).Delete(&model.ChatItem{}) res := h.DB.Where("user_id = ? AND chat_id = ?", user.Id, chatId).Delete(&model.ChatItem{})
if res.Error != nil { if res.Error != nil {
resp.ERROR(c, "Failed to update database") resp.ERROR(c, "Failed to update database")
return return
} }
// 删除当前会话的聊天记录 // 删除当前会话的聊天记录
res = h.db.Where("user_id = ? AND chat_id =?", user.Id, chatId).Delete(&model.ChatItem{}) res = h.DB.Where("user_id = ? AND chat_id =?", user.Id, chatId).Delete(&model.ChatItem{})
if res.Error != nil { if res.Error != nil {
resp.ERROR(c, "Failed to remove chat from database.") resp.ERROR(c, "Failed to remove chat from database.")
return return
@ -187,7 +181,7 @@ func (h *ChatHandler) Detail(c *gin.Context) {
} }
var chatItem model.ChatItem var chatItem model.ChatItem
res := h.db.Where("chat_id = ?", chatId).First(&chatItem) res := h.DB.Where("chat_id = ?", chatId).First(&chatItem)
if res.Error != nil { if res.Error != nil {
resp.ERROR(c, "No chat found") resp.ERROR(c, "No chat found")
return return

View File

@ -139,7 +139,7 @@ func (h *ChatHandler) sendChatGLMMessage(
} }
historyUserMsg.CreatedAt = promptCreatedAt historyUserMsg.CreatedAt = promptCreatedAt
historyUserMsg.UpdatedAt = promptCreatedAt historyUserMsg.UpdatedAt = promptCreatedAt
res := h.db.Save(&historyUserMsg) res := h.DB.Save(&historyUserMsg)
if res.Error != nil { if res.Error != nil {
logger.Error("failed to save prompt history message: ", res.Error) logger.Error("failed to save prompt history message: ", res.Error)
} }
@ -161,7 +161,7 @@ func (h *ChatHandler) sendChatGLMMessage(
} }
historyReplyMsg.CreatedAt = replyCreatedAt historyReplyMsg.CreatedAt = replyCreatedAt
historyReplyMsg.UpdatedAt = replyCreatedAt historyReplyMsg.UpdatedAt = replyCreatedAt
res = h.db.Create(&historyReplyMsg) res = h.DB.Create(&historyReplyMsg)
if res.Error != nil { if res.Error != nil {
logger.Error("failed to save reply history message: ", res.Error) logger.Error("failed to save reply history message: ", res.Error)
} }
@ -171,7 +171,7 @@ func (h *ChatHandler) sendChatGLMMessage(
// 保存当前会话 // 保存当前会话
var chatItem model.ChatItem var chatItem model.ChatItem
res = h.db.Where("chat_id = ?", session.ChatId).First(&chatItem) res = h.DB.Where("chat_id = ?", session.ChatId).First(&chatItem)
if res.Error != nil { if res.Error != nil {
chatItem.ChatId = session.ChatId chatItem.ChatId = session.ChatId
chatItem.UserId = session.UserId chatItem.UserId = session.UserId
@ -183,7 +183,7 @@ func (h *ChatHandler) sendChatGLMMessage(
chatItem.Title = prompt chatItem.Title = prompt
} }
chatItem.Model = req.Model chatItem.Model = req.Model
h.db.Create(&chatItem) h.DB.Create(&chatItem)
} }
} }
} else { } else {

View File

@ -100,7 +100,7 @@ func (h *ChatHandler) sendOpenAiMessage(
} }
if !utils.IsEmptyValue(tool) { if !utils.IsEmptyValue(tool) {
res := h.db.Where("name = ?", tool.Function.Name).First(&function) res := h.DB.Where("name = ?", tool.Function.Name).First(&function)
if res.Error == nil { if res.Error == nil {
toolCall = true toolCall = true
utils.ReplyChunkMessage(ws, types.WsMessage{Type: types.WsStart}) utils.ReplyChunkMessage(ws, types.WsMessage{Type: types.WsStart})
@ -210,7 +210,7 @@ func (h *ChatHandler) sendOpenAiMessage(
} }
historyUserMsg.CreatedAt = promptCreatedAt historyUserMsg.CreatedAt = promptCreatedAt
historyUserMsg.UpdatedAt = promptCreatedAt historyUserMsg.UpdatedAt = promptCreatedAt
res := h.db.Save(&historyUserMsg) res := h.DB.Save(&historyUserMsg)
if res.Error != nil { if res.Error != nil {
logger.Error("failed to save prompt history message: ", res.Error) logger.Error("failed to save prompt history message: ", res.Error)
} }
@ -240,7 +240,7 @@ func (h *ChatHandler) sendOpenAiMessage(
} }
historyReplyMsg.CreatedAt = replyCreatedAt historyReplyMsg.CreatedAt = replyCreatedAt
historyReplyMsg.UpdatedAt = replyCreatedAt historyReplyMsg.UpdatedAt = replyCreatedAt
res = h.db.Create(&historyReplyMsg) res = h.DB.Create(&historyReplyMsg)
if res.Error != nil { if res.Error != nil {
logger.Error("failed to save reply history message: ", res.Error) logger.Error("failed to save reply history message: ", res.Error)
} }
@ -250,7 +250,7 @@ func (h *ChatHandler) sendOpenAiMessage(
// 保存当前会话 // 保存当前会话
var chatItem model.ChatItem var chatItem model.ChatItem
res = h.db.Where("chat_id = ?", session.ChatId).First(&chatItem) res = h.DB.Where("chat_id = ?", session.ChatId).First(&chatItem)
if res.Error != nil { if res.Error != nil {
chatItem.ChatId = session.ChatId chatItem.ChatId = session.ChatId
chatItem.UserId = session.UserId chatItem.UserId = session.UserId
@ -262,18 +262,19 @@ func (h *ChatHandler) sendOpenAiMessage(
chatItem.Title = prompt chatItem.Title = prompt
} }
chatItem.Model = req.Model chatItem.Model = req.Model
h.db.Create(&chatItem) h.DB.Create(&chatItem)
} }
} }
} else { } else {
body, err := io.ReadAll(response.Body) body, err := io.ReadAll(response.Body)
if err != nil { if err != nil {
utils.ReplyMessage(ws, "请求 OpenAI API 失败:"+err.Error())
return fmt.Errorf("error with reading response: %v", err) return fmt.Errorf("error with reading response: %v", err)
} }
var res types.ApiError var res types.ApiError
err = json.Unmarshal(body, &res) err = json.Unmarshal(body, &res)
if err != nil { if err != nil {
logger.Debug(string(body)) utils.ReplyMessage(ws, "请求 OpenAI API 失败:\n"+"```\n"+string(body)+"```")
return fmt.Errorf("error with decode response: %v", err) return fmt.Errorf("error with decode response: %v", err)
} }
@ -281,7 +282,7 @@ func (h *ChatHandler) sendOpenAiMessage(
if strings.Contains(res.Error.Message, "This key is associated with a deactivated account") { if strings.Contains(res.Error.Message, "This key is associated with a deactivated account") {
utils.ReplyMessage(ws, "请求 OpenAI API 失败API KEY 所关联的账户被禁用。") utils.ReplyMessage(ws, "请求 OpenAI API 失败API KEY 所关联的账户被禁用。")
// 移除当前 API key // 移除当前 API key
h.db.Where("value = ?", apiKey).Delete(&model.ApiKey{}) h.DB.Where("value = ?", apiKey).Delete(&model.ApiKey{})
} else if strings.Contains(res.Error.Message, "You exceeded your current quota") { } else if strings.Contains(res.Error.Message, "You exceeded your current quota") {
utils.ReplyMessage(ws, "请求 OpenAI API 失败API KEY 触发并发限制,请稍后再试。") utils.ReplyMessage(ws, "请求 OpenAI API 失败API KEY 触发并发限制,请稍后再试。")
} else if strings.Contains(res.Error.Message, "This model's maximum context length") { } else if strings.Contains(res.Error.Message, "This model's maximum context length") {

View File

@ -172,7 +172,7 @@ func (h *ChatHandler) sendQWenMessage(
} }
historyUserMsg.CreatedAt = promptCreatedAt historyUserMsg.CreatedAt = promptCreatedAt
historyUserMsg.UpdatedAt = promptCreatedAt historyUserMsg.UpdatedAt = promptCreatedAt
res := h.db.Save(&historyUserMsg) res := h.DB.Save(&historyUserMsg)
if res.Error != nil { if res.Error != nil {
logger.Error("failed to save prompt history message: ", res.Error) logger.Error("failed to save prompt history message: ", res.Error)
} }
@ -194,7 +194,7 @@ func (h *ChatHandler) sendQWenMessage(
} }
historyReplyMsg.CreatedAt = replyCreatedAt historyReplyMsg.CreatedAt = replyCreatedAt
historyReplyMsg.UpdatedAt = replyCreatedAt historyReplyMsg.UpdatedAt = replyCreatedAt
res = h.db.Create(&historyReplyMsg) res = h.DB.Create(&historyReplyMsg)
if res.Error != nil { if res.Error != nil {
logger.Error("failed to save reply history message: ", res.Error) logger.Error("failed to save reply history message: ", res.Error)
} }
@ -204,7 +204,7 @@ func (h *ChatHandler) sendQWenMessage(
// 保存当前会话 // 保存当前会话
var chatItem model.ChatItem var chatItem model.ChatItem
res = h.db.Where("chat_id = ?", session.ChatId).First(&chatItem) res = h.DB.Where("chat_id = ?", session.ChatId).First(&chatItem)
if res.Error != nil { if res.Error != nil {
chatItem.ChatId = session.ChatId chatItem.ChatId = session.ChatId
chatItem.UserId = session.UserId chatItem.UserId = session.UserId
@ -216,7 +216,7 @@ func (h *ChatHandler) sendQWenMessage(
chatItem.Title = prompt chatItem.Title = prompt
} }
chatItem.Model = req.Model chatItem.Model = req.Model
h.db.Create(&chatItem) h.DB.Create(&chatItem)
} }
} }
} else { } else {

View File

@ -69,13 +69,13 @@ func (h *ChatHandler) sendXunFeiMessage(
ws *types.WsClient) error { ws *types.WsClient) error {
promptCreatedAt := time.Now() // 记录提问时间 promptCreatedAt := time.Now() // 记录提问时间
var apiKey model.ApiKey var apiKey model.ApiKey
res := h.db.Where("platform = ?", session.Model.Platform).Where("type = ?", "chat").Where("enabled = ?", true).Order("last_used_at ASC").First(&apiKey) res := h.DB.Where("platform = ?", session.Model.Platform).Where("type = ?", "chat").Where("enabled = ?", true).Order("last_used_at ASC").First(&apiKey)
if res.Error != nil { if res.Error != nil {
utils.ReplyMessage(ws, "抱歉😔😔😔,系统已经没有可用的 API KEY请联系管理员") utils.ReplyMessage(ws, "抱歉😔😔😔,系统已经没有可用的 API KEY请联系管理员")
return nil return nil
} }
// 更新 API KEY 的最后使用时间 // 更新 API KEY 的最后使用时间
h.db.Model(&apiKey).UpdateColumn("last_used_at", time.Now().Unix()) h.DB.Model(&apiKey).UpdateColumn("last_used_at", time.Now().Unix())
d := websocket.Dialer{ d := websocket.Dialer{
HandshakeTimeout: 5 * time.Second, HandshakeTimeout: 5 * time.Second,
@ -200,7 +200,7 @@ func (h *ChatHandler) sendXunFeiMessage(
} }
historyUserMsg.CreatedAt = promptCreatedAt historyUserMsg.CreatedAt = promptCreatedAt
historyUserMsg.UpdatedAt = promptCreatedAt historyUserMsg.UpdatedAt = promptCreatedAt
res := h.db.Save(&historyUserMsg) res := h.DB.Save(&historyUserMsg)
if res.Error != nil { if res.Error != nil {
logger.Error("failed to save prompt history message: ", res.Error) logger.Error("failed to save prompt history message: ", res.Error)
} }
@ -222,7 +222,7 @@ func (h *ChatHandler) sendXunFeiMessage(
} }
historyReplyMsg.CreatedAt = replyCreatedAt historyReplyMsg.CreatedAt = replyCreatedAt
historyReplyMsg.UpdatedAt = replyCreatedAt historyReplyMsg.UpdatedAt = replyCreatedAt
res = h.db.Create(&historyReplyMsg) res = h.DB.Create(&historyReplyMsg)
if res.Error != nil { if res.Error != nil {
logger.Error("failed to save reply history message: ", res.Error) logger.Error("failed to save reply history message: ", res.Error)
} }
@ -232,7 +232,7 @@ func (h *ChatHandler) sendXunFeiMessage(
// 保存当前会话 // 保存当前会话
var chatItem model.ChatItem var chatItem model.ChatItem
res = h.db.Where("chat_id = ?", session.ChatId).First(&chatItem) res = h.DB.Where("chat_id = ?", session.ChatId).First(&chatItem)
if res.Error != nil { if res.Error != nil {
chatItem.ChatId = session.ChatId chatItem.ChatId = session.ChatId
chatItem.UserId = session.UserId chatItem.UserId = session.UserId
@ -244,7 +244,7 @@ func (h *ChatHandler) sendXunFeiMessage(
chatItem.Title = prompt chatItem.Title = prompt
} }
chatItem.Model = req.Model chatItem.Model = req.Model
h.db.Create(&chatItem) h.DB.Create(&chatItem)
} }
} }

View File

@ -12,20 +12,17 @@ import (
type ConfigHandler struct { type ConfigHandler struct {
BaseHandler BaseHandler
db *gorm.DB
} }
func NewConfigHandler(app *core.AppServer, db *gorm.DB) *ConfigHandler { func NewConfigHandler(app *core.AppServer, db *gorm.DB) *ConfigHandler {
h := ConfigHandler{db: db} return &ConfigHandler{BaseHandler: BaseHandler{App: app, DB: db}}
h.App = app
return &h
} }
// Get 获取指定的系统配置 // Get 获取指定的系统配置
func (h *ConfigHandler) Get(c *gin.Context) { func (h *ConfigHandler) Get(c *gin.Context) {
key := c.Query("key") key := c.Query("key")
var config model.Config var config model.Config
res := h.db.Where("marker", key).First(&config) res := h.DB.Where("marker", key).First(&config)
if res.Error != nil { if res.Error != nil {
resp.ERROR(c, res.Error.Error()) resp.ERROR(c, res.Error.Error())
return return

View File

@ -19,7 +19,6 @@ import (
type FunctionHandler struct { type FunctionHandler struct {
BaseHandler BaseHandler
db *gorm.DB
config types.ChatPlusApiConfig config types.ChatPlusApiConfig
uploadManager *oss.UploaderManager uploadManager *oss.UploaderManager
} }
@ -28,8 +27,8 @@ func NewFunctionHandler(server *core.AppServer, db *gorm.DB, config *types.AppCo
return &FunctionHandler{ return &FunctionHandler{
BaseHandler: BaseHandler{ BaseHandler: BaseHandler{
App: server, App: server,
DB: db,
}, },
db: db,
config: config.ApiConfig, config: config.ApiConfig,
uploadManager: manager, uploadManager: manager,
} }
@ -191,7 +190,7 @@ func (h *FunctionHandler) Dall3(c *gin.Context) {
logger.Debugf("绘画参数:%+v", params) logger.Debugf("绘画参数:%+v", params)
var user model.User var user model.User
tx := h.db.Where("id = ?", params["user_id"]).First(&user) tx := h.DB.Where("id = ?", params["user_id"]).First(&user)
if tx.Error != nil { if tx.Error != nil {
resp.ERROR(c, "当前用户不存在!") resp.ERROR(c, "当前用户不存在!")
return return
@ -205,7 +204,7 @@ func (h *FunctionHandler) Dall3(c *gin.Context) {
prompt := utils.InterfaceToString(params["prompt"]) prompt := utils.InterfaceToString(params["prompt"])
// get image generation API KEY // get image generation API KEY
var apiKey model.ApiKey var apiKey model.ApiKey
tx = h.db.Where("platform = ?", types.OpenAI).Where("type = ?", "img").Where("enabled = ?", true).Order("last_used_at ASC").First(&apiKey) tx = h.DB.Where("platform = ?", types.OpenAI).Where("type = ?", "img").Where("enabled = ?", true).Order("last_used_at ASC").First(&apiKey)
if tx.Error != nil { if tx.Error != nil {
resp.ERROR(c, "获取绘图 API KEY 失败: "+tx.Error.Error()) resp.ERROR(c, "获取绘图 API KEY 失败: "+tx.Error.Error())
return return
@ -213,7 +212,7 @@ func (h *FunctionHandler) Dall3(c *gin.Context) {
// translate prompt // translate prompt
const translatePromptTemplate = "Translate the following painting prompt words into English keyword phrases. Without any explanation, directly output the keyword phrases separated by commas. The content to be translated is: [%s]" const translatePromptTemplate = "Translate the following painting prompt words into English keyword phrases. Without any explanation, directly output the keyword phrases separated by commas. The content to be translated is: [%s]"
pt, err := utils.OpenAIRequest(h.db, fmt.Sprintf(translatePromptTemplate, params["prompt"])) pt, err := utils.OpenAIRequest(h.DB, fmt.Sprintf(translatePromptTemplate, params["prompt"]))
if err == nil { if err == nil {
logger.Debugf("翻译绘画提示词,原文:%s译文%s", prompt, pt) logger.Debugf("翻译绘画提示词,原文:%s译文%s", prompt, pt)
prompt = pt prompt = pt
@ -242,7 +241,7 @@ func (h *FunctionHandler) Dall3(c *gin.Context) {
return return
} }
// 更新 API KEY 的最后使用时间 // 更新 API KEY 的最后使用时间
h.db.Model(&apiKey).UpdateColumn("last_used_at", time.Now().Unix()) h.DB.Model(&apiKey).UpdateColumn("last_used_at", time.Now().Unix())
logger.Debugf("%+v", res) logger.Debugf("%+v", res)
// 存储图片 // 存储图片
imgURL, err := h.uploadManager.GetUploadHandler().PutImg(res.Data[0].Url, false) imgURL, err := h.uploadManager.GetUploadHandler().PutImg(res.Data[0].Url, false)
@ -253,10 +252,10 @@ func (h *FunctionHandler) Dall3(c *gin.Context) {
content := fmt.Sprintf("下面是根据您的描述创作的图片,它描绘了 【%s】 的场景。 \n\n![](%s)\n", prompt, imgURL) content := fmt.Sprintf("下面是根据您的描述创作的图片,它描绘了 【%s】 的场景。 \n\n![](%s)\n", prompt, imgURL)
// 更新用户算力 // 更新用户算力
tx = h.db.Model(&model.User{}).Where("id = ?", user.Id).UpdateColumn("power", gorm.Expr("power - ?", h.App.SysConfig.DallPower)) tx = h.DB.Model(&model.User{}).Where("id = ?", user.Id).UpdateColumn("power", gorm.Expr("power - ?", h.App.SysConfig.DallPower))
// 记录算力变化日志 // 记录算力变化日志
if tx.Error == nil && tx.RowsAffected > 0 { if tx.Error == nil && tx.RowsAffected > 0 {
h.db.Create(&model.PowerLog{ h.DB.Create(&model.PowerLog{
UserId: user.Id, UserId: user.Id,
Username: user.Username, Username: user.Username,
Type: types.PowerConsume, Type: types.PowerConsume,

View File

@ -15,32 +15,29 @@ import (
// InviteHandler 用户邀请 // InviteHandler 用户邀请
type InviteHandler struct { type InviteHandler struct {
BaseHandler BaseHandler
db *gorm.DB
} }
func NewInviteHandler(app *core.AppServer, db *gorm.DB) *InviteHandler { func NewInviteHandler(app *core.AppServer, db *gorm.DB) *InviteHandler {
h := InviteHandler{db: db} return &InviteHandler{BaseHandler: BaseHandler{App: app, DB: db}}
h.App = app
return &h
} }
// Code 获取当前用户邀请码 // Code 获取当前用户邀请码
func (h *InviteHandler) Code(c *gin.Context) { func (h *InviteHandler) Code(c *gin.Context) {
userId := h.GetLoginUserId(c) userId := h.GetLoginUserId(c)
var inviteCode model.InviteCode var inviteCode model.InviteCode
res := h.db.Where("user_id = ?", userId).First(&inviteCode) res := h.DB.Where("user_id = ?", userId).First(&inviteCode)
// 如果邀请码不存在,则创建一个 // 如果邀请码不存在,则创建一个
if res.Error != nil { if res.Error != nil {
code := strings.ToUpper(utils.RandString(8)) code := strings.ToUpper(utils.RandString(8))
for { for {
res = h.db.Where("code = ?", code).First(&inviteCode) res = h.DB.Where("code = ?", code).First(&inviteCode)
if res.Error != nil { // 不存在相同的邀请码则退出 if res.Error != nil { // 不存在相同的邀请码则退出
break break
} }
} }
inviteCode.UserId = userId inviteCode.UserId = userId
inviteCode.Code = code inviteCode.Code = code
h.db.Create(&inviteCode) h.DB.Create(&inviteCode)
} }
var codeVo vo.InviteCode var codeVo vo.InviteCode
@ -65,7 +62,7 @@ func (h *InviteHandler) List(c *gin.Context) {
return return
} }
userId := h.GetLoginUserId(c) userId := h.GetLoginUserId(c)
session := h.db.Session(&gorm.Session{}).Where("inviter_id = ?", userId) session := h.DB.Session(&gorm.Session{}).Where("inviter_id = ?", userId)
var total int64 var total int64
session.Model(&model.InviteLog{}).Count(&total) session.Model(&model.InviteLog{}).Count(&total)
var items []model.InviteLog var items []model.InviteLog
@ -91,6 +88,6 @@ func (h *InviteHandler) List(c *gin.Context) {
// Hits 访问邀请码 // Hits 访问邀请码
func (h *InviteHandler) Hits(c *gin.Context) { func (h *InviteHandler) Hits(c *gin.Context) {
code := c.Query("code") code := c.Query("code")
h.db.Model(&model.InviteCode{}).Where("code = ?", code).UpdateColumn("hits", gorm.Expr("hits + ?", 1)) h.DB.Model(&model.InviteCode{}).Where("code = ?", code).UpdateColumn("hits", gorm.Expr("hits + ?", 1))
resp.SUCCESS(c) resp.SUCCESS(c)
} }

View File

@ -24,25 +24,25 @@ import (
type MidJourneyHandler struct { type MidJourneyHandler struct {
BaseHandler BaseHandler
db *gorm.DB
pool *mj.ServicePool pool *mj.ServicePool
snowflake *service.Snowflake snowflake *service.Snowflake
uploader *oss.UploaderManager uploader *oss.UploaderManager
} }
func NewMidJourneyHandler(app *core.AppServer, db *gorm.DB, snowflake *service.Snowflake, pool *mj.ServicePool, manager *oss.UploaderManager) *MidJourneyHandler { func NewMidJourneyHandler(app *core.AppServer, db *gorm.DB, snowflake *service.Snowflake, pool *mj.ServicePool, manager *oss.UploaderManager) *MidJourneyHandler {
h := MidJourneyHandler{ return &MidJourneyHandler{
db: db,
snowflake: snowflake, snowflake: snowflake,
pool: pool, pool: pool,
uploader: manager, uploader: manager,
BaseHandler: BaseHandler{
App: app,
DB: db,
},
} }
h.App = app
return &h
} }
func (h *MidJourneyHandler) preCheck(c *gin.Context) bool { func (h *MidJourneyHandler) preCheck(c *gin.Context) bool {
user, err := utils.GetLoginUser(c, h.db) user, err := h.GetLoginUser(c)
if err != nil { if err != nil {
resp.NotAuth(c) resp.NotAuth(c)
return false return false
@ -172,7 +172,7 @@ func (h *MidJourneyHandler) Image(c *gin.Context) {
opt = "换脸" opt = "换脸"
} }
if res := h.db.Create(&job); res.Error != nil || res.RowsAffected == 0 { if res := h.DB.Create(&job); res.Error != nil || res.RowsAffected == 0 {
resp.ERROR(c, "添加任务失败:"+res.Error.Error()) resp.ERROR(c, "添加任务失败:"+res.Error.Error())
return return
} }
@ -193,11 +193,11 @@ func (h *MidJourneyHandler) Image(c *gin.Context) {
} }
// update user's power // update user's power
tx := h.db.Model(&model.User{}).Where("id = ?", job.UserId).UpdateColumn("power", gorm.Expr("power - ?", job.Power)) tx := h.DB.Model(&model.User{}).Where("id = ?", job.UserId).UpdateColumn("power", gorm.Expr("power - ?", job.Power))
// 记录算力变化日志 // 记录算力变化日志
if tx.Error == nil && tx.RowsAffected > 0 { if tx.Error == nil && tx.RowsAffected > 0 {
user, _ := utils.GetLoginUser(c, h.db) user, _ := h.GetLoginUser(c)
h.db.Create(&model.PowerLog{ h.DB.Create(&model.PowerLog{
UserId: user.Id, UserId: user.Id,
Username: user.Username, Username: user.Username,
Type: types.PowerConsume, Type: types.PowerConsume,
@ -248,7 +248,7 @@ func (h *MidJourneyHandler) Upscale(c *gin.Context) {
Prompt: data.Prompt, Prompt: data.Prompt,
CreatedAt: time.Now(), CreatedAt: time.Now(),
} }
if res := h.db.Create(&job); res.Error != nil || res.RowsAffected == 0 { if res := h.DB.Create(&job); res.Error != nil || res.RowsAffected == 0 {
resp.ERROR(c, "添加任务失败:"+res.Error.Error()) resp.ERROR(c, "添加任务失败:"+res.Error.Error())
return return
} }
@ -299,7 +299,7 @@ func (h *MidJourneyHandler) Variation(c *gin.Context) {
Power: h.App.SysConfig.MjPower, Power: h.App.SysConfig.MjPower,
CreatedAt: time.Now(), CreatedAt: time.Now(),
} }
if res := h.db.Create(&job); res.Error != nil || res.RowsAffected == 0 { if res := h.DB.Create(&job); res.Error != nil || res.RowsAffected == 0 {
resp.ERROR(c, "添加任务失败:"+res.Error.Error()) resp.ERROR(c, "添加任务失败:"+res.Error.Error())
return return
} }
@ -322,11 +322,11 @@ func (h *MidJourneyHandler) Variation(c *gin.Context) {
} }
// update user's power // update user's power
tx := h.db.Model(&model.User{}).Where("id = ?", job.UserId).UpdateColumn("power", gorm.Expr("power - ?", job.Power)) tx := h.DB.Model(&model.User{}).Where("id = ?", job.UserId).UpdateColumn("power", gorm.Expr("power - ?", job.Power))
// 记录算力变化日志 // 记录算力变化日志
if tx.Error == nil && tx.RowsAffected > 0 { if tx.Error == nil && tx.RowsAffected > 0 {
user, _ := utils.GetLoginUser(c, h.db) user, _ := h.GetLoginUser(c)
h.db.Create(&model.PowerLog{ h.DB.Create(&model.PowerLog{
UserId: user.Id, UserId: user.Id,
Username: user.Username, Username: user.Username,
Type: types.PowerConsume, Type: types.PowerConsume,
@ -373,7 +373,7 @@ func (h *MidJourneyHandler) JobList(c *gin.Context) {
// JobList 获取 MJ 任务列表 // JobList 获取 MJ 任务列表
func (h *MidJourneyHandler) getData(finish bool, userId uint, page int, pageSize int, publish bool) (error, []vo.MidJourneyJob) { func (h *MidJourneyHandler) getData(finish bool, userId uint, page int, pageSize int, publish bool) (error, []vo.MidJourneyJob) {
session := h.db.Session(&gorm.Session{}) session := h.DB.Session(&gorm.Session{})
if finish { if finish {
session = session.Where("progress = ?", 100).Order("id DESC") session = session.Where("progress = ?", 100).Order("id DESC")
} else { } else {
@ -434,7 +434,7 @@ func (h *MidJourneyHandler) Remove(c *gin.Context) {
} }
// remove job recode // remove job recode
res := h.db.Delete(&model.MidJourneyJob{Id: data.Id}) res := h.DB.Delete(&model.MidJourneyJob{Id: data.Id})
if res.Error != nil { if res.Error != nil {
resp.ERROR(c, res.Error.Error()) resp.ERROR(c, res.Error.Error())
return return
@ -486,7 +486,7 @@ func (h *MidJourneyHandler) Publish(c *gin.Context) {
return return
} }
res := h.db.Model(&model.MidJourneyJob{Id: data.Id}).UpdateColumn("publish", data.Action) res := h.DB.Model(&model.MidJourneyJob{Id: data.Id}).UpdateColumn("publish", data.Action)
if res.Error != nil { if res.Error != nil {
resp.ERROR(c, "更新数据库失败") resp.ERROR(c, "更新数据库失败")
return return

View File

@ -14,13 +14,10 @@ import (
type OrderHandler struct { type OrderHandler struct {
BaseHandler BaseHandler
db *gorm.DB
} }
func NewOrderHandler(app *core.AppServer, db *gorm.DB) *OrderHandler { func NewOrderHandler(app *core.AppServer, db *gorm.DB) *OrderHandler {
h := OrderHandler{db: db} return &OrderHandler{BaseHandler: BaseHandler{App: app, DB: db}}
h.App = app
return &h
} }
func (h *OrderHandler) List(c *gin.Context) { func (h *OrderHandler) List(c *gin.Context) {
@ -33,7 +30,7 @@ func (h *OrderHandler) List(c *gin.Context) {
return return
} }
userId := h.GetLoginUserId(c) userId := h.GetLoginUserId(c)
session := h.db.Session(&gorm.Session{}).Where("user_id = ? AND status = ?", userId, types.OrderPaidSuccess) session := h.DB.Session(&gorm.Session{}).Where("user_id = ? AND status = ?", userId, types.OrderPaidSuccess)
var total int64 var total int64
session.Model(&model.Order{}).Count(&total) session.Model(&model.Order{}).Count(&total)
var items []model.Order var items []model.Order

View File

@ -35,7 +35,6 @@ type PaymentHandler struct {
huPiPayService *payment.HuPiPayService huPiPayService *payment.HuPiPayService
js *payment.PayJS js *payment.PayJS
snowflake *service.Snowflake snowflake *service.Snowflake
db *gorm.DB
fs embed.FS fs embed.FS
lock sync.Mutex lock sync.Mutex
} }
@ -45,20 +44,21 @@ func NewPaymentHandler(
alipayService *payment.AlipayService, alipayService *payment.AlipayService,
huPiPayService *payment.HuPiPayService, huPiPayService *payment.HuPiPayService,
js *payment.PayJS, js *payment.PayJS,
snowflake *service.Snowflake,
db *gorm.DB, db *gorm.DB,
snowflake *service.Snowflake,
fs embed.FS) *PaymentHandler { fs embed.FS) *PaymentHandler {
h := PaymentHandler{ return &PaymentHandler{
alipayService: alipayService, alipayService: alipayService,
huPiPayService: huPiPayService, huPiPayService: huPiPayService,
js: js, js: js,
snowflake: snowflake, snowflake: snowflake,
fs: fs, fs: fs,
db: db,
lock: sync.Mutex{}, lock: sync.Mutex{},
BaseHandler: BaseHandler{
App: server,
DB: db,
},
} }
h.App = server
return &h
} }
func (h *PaymentHandler) DoPay(c *gin.Context) { func (h *PaymentHandler) DoPay(c *gin.Context) {
@ -71,7 +71,7 @@ func (h *PaymentHandler) DoPay(c *gin.Context) {
} }
var order model.Order var order model.Order
res := h.db.Where("order_no = ?", orderNo).First(&order) res := h.DB.Where("order_no = ?", orderNo).First(&order)
if res.Error != nil { if res.Error != nil {
resp.ERROR(c, "Order not found") resp.ERROR(c, "Order not found")
return return
@ -84,7 +84,7 @@ func (h *PaymentHandler) DoPay(c *gin.Context) {
} }
// 更新扫码状态 // 更新扫码状态
h.db.Model(&order).UpdateColumn("status", types.OrderScanned) h.DB.Model(&order).UpdateColumn("status", types.OrderScanned)
if payWay == "alipay" { // 支付宝 if payWay == "alipay" { // 支付宝
// 生成支付链接 // 生成支付链接
notifyURL := h.App.Config.AlipayConfig.NotifyURL notifyURL := h.App.Config.AlipayConfig.NotifyURL
@ -130,7 +130,7 @@ func (h *PaymentHandler) OrderQuery(c *gin.Context) {
} }
var order model.Order var order model.Order
res := h.db.Where("order_no = ?", data.OrderNo).First(&order) res := h.DB.Where("order_no = ?", data.OrderNo).First(&order)
if res.Error != nil { if res.Error != nil {
resp.ERROR(c, "Order not found") resp.ERROR(c, "Order not found")
return return
@ -145,7 +145,7 @@ func (h *PaymentHandler) OrderQuery(c *gin.Context) {
for { for {
time.Sleep(time.Second) time.Sleep(time.Second)
var item model.Order var item model.Order
h.db.Where("order_no = ?", data.OrderNo).First(&item) h.DB.Where("order_no = ?", data.OrderNo).First(&item)
if counter >= 15 || item.Status == types.OrderPaidSuccess || item.Status != order.Status { if counter >= 15 || item.Status == types.OrderPaidSuccess || item.Status != order.Status {
order.Status = item.Status order.Status = item.Status
break break
@ -169,7 +169,7 @@ func (h *PaymentHandler) PayQrcode(c *gin.Context) {
} }
var product model.Product var product model.Product
res := h.db.First(&product, data.ProductId) res := h.DB.First(&product, data.ProductId)
if res.Error != nil { if res.Error != nil {
resp.ERROR(c, "Product not found") resp.ERROR(c, "Product not found")
return return
@ -181,7 +181,7 @@ func (h *PaymentHandler) PayQrcode(c *gin.Context) {
return return
} }
var user model.User var user model.User
res = h.db.First(&user, data.UserId) res = h.DB.First(&user, data.UserId)
if res.Error != nil { if res.Error != nil {
resp.ERROR(c, "Invalid user ID") resp.ERROR(c, "Invalid user ID")
return return
@ -221,7 +221,7 @@ func (h *PaymentHandler) PayQrcode(c *gin.Context) {
PayWay: payWay, PayWay: payWay,
Remark: utils.JsonEncode(remark), Remark: utils.JsonEncode(remark),
} }
res = h.db.Create(&order) res = h.DB.Create(&order)
if res.Error != nil || res.RowsAffected == 0 { if res.Error != nil || res.RowsAffected == 0 {
resp.ERROR(c, "error with create order: "+res.Error.Error()) resp.ERROR(c, "error with create order: "+res.Error.Error())
return return
@ -291,7 +291,7 @@ func (h *PaymentHandler) Mobile(c *gin.Context) {
} }
var product model.Product var product model.Product
res := h.db.First(&product, data.ProductId) res := h.DB.First(&product, data.ProductId)
if res.Error != nil { if res.Error != nil {
resp.ERROR(c, "Product not found") resp.ERROR(c, "Product not found")
return return
@ -303,7 +303,7 @@ func (h *PaymentHandler) Mobile(c *gin.Context) {
return return
} }
var user model.User var user model.User
res = h.db.First(&user, data.UserId) res = h.DB.First(&user, data.UserId)
if res.Error != nil { if res.Error != nil {
resp.ERROR(c, "Invalid user ID") resp.ERROR(c, "Invalid user ID")
return return
@ -343,7 +343,7 @@ func (h *PaymentHandler) Mobile(c *gin.Context) {
PayWay: payWay, PayWay: payWay,
Remark: utils.JsonEncode(remark), Remark: utils.JsonEncode(remark),
} }
res = h.db.Create(&order) res = h.DB.Create(&order)
if res.Error != nil || res.RowsAffected == 0 { if res.Error != nil || res.RowsAffected == 0 {
resp.ERROR(c, "error with create order: "+res.Error.Error()) resp.ERROR(c, "error with create order: "+res.Error.Error())
return return
@ -402,7 +402,7 @@ func (h *PaymentHandler) Mobile(c *gin.Context) {
// 异步通知回调公共逻辑 // 异步通知回调公共逻辑
func (h *PaymentHandler) notify(orderNo string, tradeNo string) error { func (h *PaymentHandler) notify(orderNo string, tradeNo string) error {
var order model.Order var order model.Order
res := h.db.Where("order_no = ?", orderNo).First(&order) res := h.DB.Where("order_no = ?", orderNo).First(&order)
if res.Error != nil { if res.Error != nil {
err := fmt.Errorf("error with fetch order: %v", res.Error) err := fmt.Errorf("error with fetch order: %v", res.Error)
logger.Error(err) logger.Error(err)
@ -418,7 +418,7 @@ func (h *PaymentHandler) notify(orderNo string, tradeNo string) error {
} }
var user model.User var user model.User
res = h.db.First(&user, order.UserId) res = h.DB.First(&user, order.UserId)
if res.Error != nil { if res.Error != nil {
err := fmt.Errorf("error with fetch user info: %v", res.Error) err := fmt.Errorf("error with fetch user info: %v", res.Error)
logger.Error(err) logger.Error(err)
@ -444,7 +444,7 @@ func (h *PaymentHandler) notify(orderNo string, tradeNo string) error {
power = remark.Power power = remark.Power
} }
} else { // 非 VIP 用户 } else { // 非 VIP 用户
if remark.Days > 0 { // vip 套餐days > 0, power == 0 if remark.Days > 0 { // vip 套餐days > 0, power == 0
user.ExpiredTime = time.Now().AddDate(0, 0, remark.Days).Unix() user.ExpiredTime = time.Now().AddDate(0, 0, remark.Days).Unix()
user.Power += h.App.SysConfig.VipMonthPower user.Power += h.App.SysConfig.VipMonthPower
@ -459,7 +459,7 @@ func (h *PaymentHandler) notify(orderNo string, tradeNo string) error {
} }
// 更新用户信息 // 更新用户信息
res = h.db.Updates(&user) res = h.DB.Updates(&user)
if res.Error != nil { if res.Error != nil {
err := fmt.Errorf("error with update user info: %v", res.Error) err := fmt.Errorf("error with update user info: %v", res.Error)
logger.Error(err) logger.Error(err)
@ -470,7 +470,7 @@ func (h *PaymentHandler) notify(orderNo string, tradeNo string) error {
order.PayTime = time.Now().Unix() order.PayTime = time.Now().Unix()
order.Status = types.OrderPaidSuccess order.Status = types.OrderPaidSuccess
order.TradeNo = tradeNo order.TradeNo = tradeNo
res = h.db.Updates(&order) res = h.DB.Updates(&order)
if res.Error != nil { if res.Error != nil {
err := fmt.Errorf("error with update order info: %v", res.Error) err := fmt.Errorf("error with update order info: %v", res.Error)
logger.Error(err) logger.Error(err)
@ -478,11 +478,11 @@ func (h *PaymentHandler) notify(orderNo string, tradeNo string) error {
} }
// 更新产品销量 // 更新产品销量
h.db.Model(&model.Product{}).Where("id = ?", order.ProductId).UpdateColumn("sales", gorm.Expr("sales + ?", 1)) h.DB.Model(&model.Product{}).Where("id = ?", order.ProductId).UpdateColumn("sales", gorm.Expr("sales + ?", 1))
// 记录算力充值日志 // 记录算力充值日志
if opt != "" { if opt != "" {
h.db.Create(&model.PowerLog{ h.DB.Create(&model.PowerLog{
UserId: user.Id, UserId: user.Id,
Username: user.Username, Username: user.Username,
Type: types.PowerRecharge, Type: types.PowerRecharge,

View File

@ -12,20 +12,17 @@ import (
type ProductHandler struct { type ProductHandler struct {
BaseHandler BaseHandler
db *gorm.DB
} }
func NewProductHandler(app *core.AppServer, db *gorm.DB) *ProductHandler { func NewProductHandler(app *core.AppServer, db *gorm.DB) *ProductHandler {
h := ProductHandler{db: db} return &ProductHandler{BaseHandler: BaseHandler{App: app, DB: db}}
h.App = app
return &h
} }
// List 模型列表 // List 模型列表
func (h *ProductHandler) List(c *gin.Context) { func (h *ProductHandler) List(c *gin.Context) {
var items []model.Product var items []model.Product
var list = make([]vo.Product, 0) var list = make([]vo.Product, 0)
res := h.db.Where("enabled", true).Order("sort_num ASC").Find(&items) res := h.DB.Where("enabled", true).Order("sort_num ASC").Find(&items)
if res.Error == nil { if res.Error == nil {
for _, item := range items { for _, item := range items {
var product vo.Product var product vo.Product

View File

@ -16,13 +16,10 @@ const translatePromptTemplate = "Translate the following painting prompt words i
type PromptHandler struct { type PromptHandler struct {
BaseHandler BaseHandler
db *gorm.DB
} }
func NewPromptHandler(app *core.AppServer, db *gorm.DB) *PromptHandler { func NewPromptHandler(app *core.AppServer, db *gorm.DB) *PromptHandler {
h := &PromptHandler{db: db} return &PromptHandler{BaseHandler: BaseHandler{App: app, DB: db}}
h.App = app
return h
} }
// Rewrite translate and rewrite prompt with ChatGPT // Rewrite translate and rewrite prompt with ChatGPT
@ -35,7 +32,7 @@ func (h *PromptHandler) Rewrite(c *gin.Context) {
return return
} }
content, err := utils.OpenAIRequest(h.db, fmt.Sprintf(rewritePromptTemplate, data.Prompt)) content, err := utils.OpenAIRequest(h.DB, fmt.Sprintf(rewritePromptTemplate, data.Prompt))
if err != nil { if err != nil {
resp.ERROR(c, err.Error()) resp.ERROR(c, err.Error())
return return
@ -53,7 +50,7 @@ func (h *PromptHandler) Translate(c *gin.Context) {
return return
} }
content, err := utils.OpenAIRequest(h.db, fmt.Sprintf(translatePromptTemplate, data.Prompt)) content, err := utils.OpenAIRequest(h.DB, fmt.Sprintf(translatePromptTemplate, data.Prompt))
if err != nil { if err != nil {
resp.ERROR(c, err.Error()) resp.ERROR(c, err.Error())
return return

View File

@ -18,14 +18,11 @@ import (
type RewardHandler struct { type RewardHandler struct {
BaseHandler BaseHandler
db *gorm.DB
lock sync.Mutex lock sync.Mutex
} }
func NewRewardHandler(server *core.AppServer, db *gorm.DB) *RewardHandler { func NewRewardHandler(app *core.AppServer, db *gorm.DB) *RewardHandler {
h := RewardHandler{db: db, lock: sync.Mutex{}} return &RewardHandler{BaseHandler: BaseHandler{App: app, DB: db}}
h.App = server
return &h
} }
// Verify 打赏码核销 // Verify 打赏码核销
@ -38,7 +35,7 @@ func (h *RewardHandler) Verify(c *gin.Context) {
return return
} }
user, err := utils.GetLoginUser(c, h.db) user, err := h.GetLoginUser(c)
if err != nil { if err != nil {
resp.HACKER(c) resp.HACKER(c)
return return
@ -51,7 +48,7 @@ func (h *RewardHandler) Verify(c *gin.Context) {
defer h.lock.Unlock() defer h.lock.Unlock()
var item model.Reward var item model.Reward
res := h.db.Where("tx_id = ?", data.TxId).First(&item) res := h.DB.Where("tx_id = ?", data.TxId).First(&item)
if res.Error != nil { if res.Error != nil {
resp.ERROR(c, "无效的众筹交易流水号!") resp.ERROR(c, "无效的众筹交易流水号!")
return return
@ -62,7 +59,7 @@ func (h *RewardHandler) Verify(c *gin.Context) {
return return
} }
tx := h.db.Begin() tx := h.DB.Begin()
exchange := vo.RewardExchange{} exchange := vo.RewardExchange{}
power := math.Ceil(item.Amount / h.App.SysConfig.PowerPrice) power := math.Ceil(item.Amount / h.App.SysConfig.PowerPrice)
exchange.Power = int(power) exchange.Power = int(power)
@ -85,7 +82,7 @@ func (h *RewardHandler) Verify(c *gin.Context) {
} }
// 记录算力充值日志 // 记录算力充值日志
h.db.Create(&model.PowerLog{ h.DB.Create(&model.PowerLog{
UserId: user.Id, UserId: user.Id,
Username: user.Username, Username: user.Username,
Type: types.PowerReward, Type: types.PowerReward,

View File

@ -24,19 +24,19 @@ import (
type SdJobHandler struct { type SdJobHandler struct {
BaseHandler BaseHandler
redis *redis.Client redis *redis.Client
db *gorm.DB
pool *sd.ServicePool pool *sd.ServicePool
uploader *oss.UploaderManager uploader *oss.UploaderManager
} }
func NewSdJobHandler(app *core.AppServer, db *gorm.DB, pool *sd.ServicePool, manager *oss.UploaderManager) *SdJobHandler { func NewSdJobHandler(app *core.AppServer, db *gorm.DB, pool *sd.ServicePool, manager *oss.UploaderManager) *SdJobHandler {
h := SdJobHandler{ return &SdJobHandler{
db: db,
pool: pool, pool: pool,
uploader: manager, uploader: manager,
BaseHandler: BaseHandler{
App: app,
DB: db,
},
} }
h.App = app
return &h
} }
// Client WebSocket 客户端,用于通知任务状态变更 // Client WebSocket 客户端,用于通知任务状态变更
@ -61,7 +61,7 @@ func (h *SdJobHandler) Client(c *gin.Context) {
} }
func (h *SdJobHandler) checkLimits(c *gin.Context) bool { func (h *SdJobHandler) checkLimits(c *gin.Context) bool {
user, err := utils.GetLoginUser(c, h.db) user, err := h.GetLoginUser(c)
if err != nil { if err != nil {
resp.NotAuth(c) resp.NotAuth(c)
return false return false
@ -143,7 +143,7 @@ func (h *SdJobHandler) Image(c *gin.Context) {
Power: h.App.SysConfig.SdPower, Power: h.App.SysConfig.SdPower,
CreatedAt: time.Now(), CreatedAt: time.Now(),
} }
res := h.db.Create(&job) res := h.DB.Create(&job)
if res.Error != nil { if res.Error != nil {
resp.ERROR(c, "error with save job: "+res.Error.Error()) resp.ERROR(c, "error with save job: "+res.Error.Error())
return return
@ -164,11 +164,11 @@ func (h *SdJobHandler) Image(c *gin.Context) {
} }
// update user's power // update user's power
tx := h.db.Model(&model.User{}).Where("id = ?", job.UserId).UpdateColumn("power", gorm.Expr("power - ?", job.Power)) tx := h.DB.Model(&model.User{}).Where("id = ?", job.UserId).UpdateColumn("power", gorm.Expr("power - ?", job.Power))
// 记录算力变化日志 // 记录算力变化日志
if tx.Error == nil && tx.RowsAffected > 0 { if tx.Error == nil && tx.RowsAffected > 0 {
user, _ := utils.GetLoginUser(c, h.db) user, _ := h.GetLoginUser(c)
h.db.Create(&model.PowerLog{ h.DB.Create(&model.PowerLog{
UserId: user.Id, UserId: user.Id,
Username: user.Username, Username: user.Username,
Type: types.PowerConsume, Type: types.PowerConsume,
@ -217,7 +217,7 @@ func (h *SdJobHandler) JobList(c *gin.Context) {
// JobList 获取 MJ 任务列表 // JobList 获取 MJ 任务列表
func (h *SdJobHandler) getData(finish bool, userId uint, page int, pageSize int, publish bool) (error, []vo.SdJob) { func (h *SdJobHandler) getData(finish bool, userId uint, page int, pageSize int, publish bool) (error, []vo.SdJob) {
session := h.db.Session(&gorm.Session{}) session := h.DB.Session(&gorm.Session{})
if finish { if finish {
session = session.Where("progress = ?", 100).Order("id DESC") session = session.Where("progress = ?", 100).Order("id DESC")
} else { } else {
@ -274,7 +274,7 @@ func (h *SdJobHandler) Remove(c *gin.Context) {
} }
// remove job recode // remove job recode
res := h.db.Delete(&model.SdJob{Id: data.Id}) res := h.DB.Delete(&model.SdJob{Id: data.Id})
if res.Error != nil { if res.Error != nil {
resp.ERROR(c, res.Error.Error()) resp.ERROR(c, res.Error.Error())
return return
@ -305,7 +305,7 @@ func (h *SdJobHandler) Publish(c *gin.Context) {
return return
} }
res := h.db.Model(&model.SdJob{Id: data.Id}).UpdateColumn("publish", true) res := h.DB.Model(&model.SdJob{Id: data.Id}).UpdateColumn("publish", true)
if res.Error != nil { if res.Error != nil {
resp.ERROR(c, "更新数据库失败") resp.ERROR(c, "更新数据库失败")
return return

View File

@ -29,9 +29,12 @@ func NewSmsHandler(
sms *sms.ServiceManager, sms *sms.ServiceManager,
smtp *service.SmtpService, smtp *service.SmtpService,
captcha *service.CaptchaService) *SmsHandler { captcha *service.CaptchaService) *SmsHandler {
handler := &SmsHandler{redis: client, sms: sms, captcha: captcha, smtp: smtp} return &SmsHandler{
handler.App = app redis: client,
return handler sms: sms,
captcha: captcha,
smtp: smtp,
BaseHandler: BaseHandler{App: app}}
} }
// SendCode 发送验证码 // SendCode 发送验证码

View File

@ -3,12 +3,6 @@ package handler
import ( import (
"chatplus/service" "chatplus/service"
"chatplus/service/payment" "chatplus/service/payment"
"chatplus/store/model"
"chatplus/utils"
"chatplus/utils/resp"
"fmt"
"github.com/gin-gonic/gin"
"github.com/imroc/req/v3"
"gorm.io/gorm" "gorm.io/gorm"
) )
@ -21,208 +15,3 @@ type TestHandler struct {
func NewTestHandler(db *gorm.DB, snowflake *service.Snowflake, js *payment.PayJS) *TestHandler { func NewTestHandler(db *gorm.DB, snowflake *service.Snowflake, js *payment.PayJS) *TestHandler {
return &TestHandler{db: db, snowflake: snowflake, js: js} return &TestHandler{db: db, snowflake: snowflake, js: js}
} }
type reqBody struct {
BotType string `json:"botType"`
Prompt string `json:"prompt"`
Base64Array []interface{} `json:"base64Array,omitempty"`
AccountFilter struct {
InstanceId string `json:"instanceId"`
Modes []interface{} `json:"modes"`
Remix bool `json:"remix"`
RemixAutoConsidered bool `json:"remixAutoConsidered"`
} `json:"accountFilter,omitempty"`
NotifyHook string `json:"notifyHook"`
State string `json:"state,omitempty"`
}
type resBody struct {
Code int `json:"code"`
Description string `json:"description"`
Properties struct {
} `json:"properties"`
Result string `json:"result"`
}
func (h *TestHandler) Test(c *gin.Context) {
image(c)
}
func upscale(c *gin.Context) {
apiURL := "https://api.openai1s.cn/mj/submit/action"
token := "sk-QpBaQn9Z5vngsjJaFdDfC9Db90C845EaB5E764578a7d292a"
body := map[string]string{
"customId": "MJ::JOB::upsample::1::c80a8eb1-f2d1-4f40-8785-97eb99b7ba0a",
"taskId": "1704880156226095",
"notifyHook": "http://r9it.com:6004/api/test/mj",
}
var res resBody
var resErr errRes
r, err := req.C().R().
SetHeader("Authorization", "Bearer "+token).
SetBody(body).
SetSuccessResult(&res).
SetErrorResult(&resErr).
Post(apiURL)
if err != nil {
resp.ERROR(c, "请求出错:"+err.Error())
return
}
if r.IsErrorState() {
resp.ERROR(c, "返回错误状态:"+resErr.Error.Message)
return
}
resp.SUCCESS(c, res)
}
type queryRes struct {
Action string `json:"action"`
Buttons []struct {
CustomId string `json:"customId"`
Emoji string `json:"emoji"`
Label string `json:"label"`
Style int `json:"style"`
Type int `json:"type"`
} `json:"buttons"`
Description string `json:"description"`
FailReason string `json:"failReason"`
FinishTime int `json:"finishTime"`
Id string `json:"id"`
ImageUrl string `json:"imageUrl"`
Progress string `json:"progress"`
Prompt string `json:"prompt"`
PromptEn string `json:"promptEn"`
Properties struct {
} `json:"properties"`
StartTime int `json:"startTime"`
State string `json:"state"`
Status string `json:"status"`
SubmitTime int `json:"submitTime"`
}
func query(c *gin.Context) {
apiURL := "https://api.openai1s.cn/mj/task/1704960661008372/fetch"
token := "sk-QpBaQn9Z5vngsjJaFdDfC9Db90C845EaB5E764578a7d292a"
var res queryRes
r, err := req.C().R().SetHeader("Authorization", "Bearer "+token).
SetSuccessResult(&res).
Get(apiURL)
if err != nil {
resp.ERROR(c, "请求出错:"+err.Error())
return
}
if r.IsErrorState() {
resp.ERROR(c, "返回错误状态:"+r.Status)
return
}
resp.SUCCESS(c, res)
}
type errRes struct {
Error struct {
Message string `json:"message"`
} `json:"error"`
}
func image(c *gin.Context) {
apiURL := "https://api.openai1s.cn/mj-fast/mj/submit/imagine"
token := "sk-QpBaQn9Z5vngsjJaFdDfC9Db90C845EaB5E764578a7d292a"
body := reqBody{
BotType: "MID_JOURNEY",
Prompt: "一个中国美女,手上拿着一桶爆米花,脸上带着迷人的微笑,白色衣服 --s 750 --v 6",
NotifyHook: "http://r9it.com:6004/api/test/mj",
}
var res resBody
var resErr errRes
r, err := req.C().R().
SetHeader("Authorization", "Bearer "+token).
SetBody(body).
SetSuccessResult(&res).
SetErrorResult(&resErr).
Post(apiURL)
if err != nil {
resp.ERROR(c, "请求出错:"+err.Error())
return
}
if r.IsErrorState() {
resp.ERROR(c, "返回错误状态:"+resErr.Error.Message)
return
}
resp.SUCCESS(c, res)
}
type cbReq struct {
Id string `json:"id"`
Action string `json:"action"`
Status string `json:"status"`
Prompt string `json:"prompt"`
PromptEn string `json:"promptEn"`
Description string `json:"description"`
SubmitTime int64 `json:"submitTime"`
StartTime int64 `json:"startTime"`
FinishTime int64 `json:"finishTime"`
Progress string `json:"progress"`
ImageUrl string `json:"imageUrl"`
FailReason interface{} `json:"failReason"`
Properties struct {
FinalPrompt string `json:"finalPrompt"`
} `json:"properties"`
}
func (h *TestHandler) Mj(c *gin.Context) {
var data cbReq
if err := c.ShouldBindJSON(&data); err != nil {
logger.Error(err)
}
logger.Debugf("任务ID%s,任务进度:%s,图片地址:%s, 最终提示词:%s", data.Id, data.Progress, data.ImageUrl, data.Properties.FinalPrompt)
apiURL := "https://api.openai1s.cn/mj/task/" + data.Id + "/fetch"
token := "sk-QpBaQn9Z5vngsjJaFdDfC9Db90C845EaB5E764578a7d292a"
var res queryRes
_, _ = req.C().R().SetHeader("Authorization", "Bearer "+token).
SetSuccessResult(&res).
Get(apiURL)
fmt.Println(res.State, ",", res.ImageUrl, ",", res.Progress)
}
func (h *TestHandler) initUserNickname(c *gin.Context) {
var users []model.User
tx := h.db.Find(&users)
if tx.Error != nil {
resp.ERROR(c, tx.Error.Error())
return
}
for _, u := range users {
u.Nickname = fmt.Sprintf("极客学长@%d", utils.RandomNumber(6))
h.db.Updates(&u)
}
resp.SUCCESS(c)
}
func (h *TestHandler) initMjTaskId(c *gin.Context) {
var jobs []model.MidJourneyJob
tx := h.db.Find(&jobs)
if tx.Error != nil {
resp.ERROR(c, tx.Error.Error())
return
}
for _, job := range jobs {
id, _ := h.snowflake.Next(true)
job.TaskId = id
h.db.Updates(&job)
}
resp.SUCCESS(c)
}

View File

@ -14,14 +14,11 @@ import (
type UploadHandler struct { type UploadHandler struct {
BaseHandler BaseHandler
db *gorm.DB
uploaderManager *oss.UploaderManager uploaderManager *oss.UploaderManager
} }
func NewUploadHandler(app *core.AppServer, db *gorm.DB, manager *oss.UploaderManager) *UploadHandler { func NewUploadHandler(app *core.AppServer, db *gorm.DB, manager *oss.UploaderManager) *UploadHandler {
handler := &UploadHandler{db: db, uploaderManager: manager} return &UploadHandler{BaseHandler: BaseHandler{App: app, DB: db}, uploaderManager: manager}
handler.App = app
return handler
} }
func (h *UploadHandler) Upload(c *gin.Context) { func (h *UploadHandler) Upload(c *gin.Context) {
@ -32,7 +29,7 @@ func (h *UploadHandler) Upload(c *gin.Context) {
} }
userId := h.GetLoginUserId(c) userId := h.GetLoginUserId(c)
res := h.db.Create(&model.File{ res := h.DB.Create(&model.File{
UserId: int(userId), UserId: int(userId),
Name: file.Name, Name: file.Name,
ObjKey: file.ObjKey, ObjKey: file.ObjKey,
@ -53,7 +50,7 @@ func (h *UploadHandler) List(c *gin.Context) {
userId := h.GetLoginUserId(c) userId := h.GetLoginUserId(c)
var items []model.File var items []model.File
var files = make([]vo.File, 0) var files = make([]vo.File, 0)
h.db.Where("user_id = ?", userId).Find(&items) h.DB.Where("user_id = ?", userId).Find(&items)
if len(items) > 0 { if len(items) > 0 {
for _, v := range items { for _, v := range items {
var file vo.File var file vo.File
@ -75,14 +72,14 @@ func (h *UploadHandler) Remove(c *gin.Context) {
userId := h.GetLoginUserId(c) userId := h.GetLoginUserId(c)
id := h.GetInt(c, "id", 0) id := h.GetInt(c, "id", 0)
var file model.File var file model.File
tx := h.db.Where("user_id = ? AND id = ?", userId, id).First(&file) tx := h.DB.Where("user_id = ? AND id = ?", userId, id).First(&file)
if tx.Error != nil || file.Id == 0 { if tx.Error != nil || file.Id == 0 {
resp.ERROR(c, "file not existed") resp.ERROR(c, "file not existed")
return return
} }
// remove database // remove database
tx = h.db.Model(&model.File{}).Delete("id = ?", id) tx = h.DB.Model(&model.File{}).Delete("id = ?", id)
if tx.Error != nil || tx.RowsAffected == 0 { if tx.Error != nil || tx.RowsAffected == 0 {
resp.ERROR(c, "failed to update database") resp.ERROR(c, "failed to update database")
return return

View File

@ -21,7 +21,6 @@ import (
type UserHandler struct { type UserHandler struct {
BaseHandler BaseHandler
db *gorm.DB
searcher *xdb.Searcher searcher *xdb.Searcher
redis *redis.Client redis *redis.Client
} }
@ -31,15 +30,14 @@ func NewUserHandler(
db *gorm.DB, db *gorm.DB,
searcher *xdb.Searcher, searcher *xdb.Searcher,
client *redis.Client) *UserHandler { client *redis.Client) *UserHandler {
handler := &UserHandler{db: db, searcher: searcher, redis: client} return &UserHandler{BaseHandler: BaseHandler{DB: db, App: app}, searcher: searcher, redis: client}
handler.App = app
return handler
} }
// Register user register // Register user register
func (h *UserHandler) Register(c *gin.Context) { func (h *UserHandler) Register(c *gin.Context) {
// parameters process // parameters process
var data struct { var data struct {
RegWay string `json:"reg_way"`
Username string `json:"username"` Username string `json:"username"`
Password string `json:"password"` Password string `json:"password"`
Code string `json:"code"` Code string `json:"code"`
@ -57,8 +55,7 @@ func (h *UserHandler) Register(c *gin.Context) {
// 检查验证码 // 检查验证码
var key string var key string
if utils.ContainsStr(h.App.SysConfig.RegisterWays, "email") || if data.RegWay == "email" || data.RegWay == "mobile" {
utils.ContainsStr(h.App.SysConfig.RegisterWays, "mobile") {
key = CodeStorePrefix + data.Username key = CodeStorePrefix + data.Username
code, err := h.redis.Get(c, key).Result() code, err := h.redis.Get(c, key).Result()
if err != nil || code != data.Code { if err != nil || code != data.Code {
@ -70,7 +67,7 @@ func (h *UserHandler) Register(c *gin.Context) {
// 验证邀请码 // 验证邀请码
inviteCode := model.InviteCode{} inviteCode := model.InviteCode{}
if data.InviteCode != "" { if data.InviteCode != "" {
res := h.db.Where("code = ?", data.InviteCode).First(&inviteCode) res := h.DB.Where("code = ?", data.InviteCode).First(&inviteCode)
if res.Error != nil { if res.Error != nil {
resp.ERROR(c, "无效的邀请码") resp.ERROR(c, "无效的邀请码")
return return
@ -79,7 +76,7 @@ func (h *UserHandler) Register(c *gin.Context) {
// check if the username is exists // check if the username is exists
var item model.User var item model.User
res := h.db.Where("username = ?", data.Username).First(&item) res := h.DB.Where("username = ?", data.Username).First(&item)
if item.Id > 0 { if item.Id > 0 {
resp.ERROR(c, "该用户名已经被注册") resp.ERROR(c, "该用户名已经被注册")
return return
@ -98,7 +95,7 @@ func (h *UserHandler) Register(c *gin.Context) {
Power: h.App.SysConfig.InitPower, Power: h.App.SysConfig.InitPower,
} }
res = h.db.Create(&user) res = h.DB.Create(&user)
if res.Error != nil { if res.Error != nil {
resp.ERROR(c, "保存数据失败") resp.ERROR(c, "保存数据失败")
logger.Error(res.Error) logger.Error(res.Error)
@ -108,13 +105,13 @@ func (h *UserHandler) Register(c *gin.Context) {
// 记录邀请关系 // 记录邀请关系
if data.InviteCode != "" { if data.InviteCode != "" {
// 增加邀请数量 // 增加邀请数量
h.db.Model(&model.InviteCode{}).Where("code = ?", data.InviteCode).UpdateColumn("reg_num", gorm.Expr("reg_num + ?", 1)) h.DB.Model(&model.InviteCode{}).Where("code = ?", data.InviteCode).UpdateColumn("reg_num", gorm.Expr("reg_num + ?", 1))
if h.App.SysConfig.InvitePower > 0 { if h.App.SysConfig.InvitePower > 0 {
h.db.Model(&model.User{}).Where("id = ?", inviteCode.UserId).UpdateColumn("power", gorm.Expr("power + ?", h.App.SysConfig.InvitePower)) h.DB.Model(&model.User{}).Where("id = ?", inviteCode.UserId).UpdateColumn("power", gorm.Expr("power + ?", h.App.SysConfig.InvitePower))
} }
// 添加邀请记录 // 添加邀请记录
h.db.Create(&model.InviteLog{ h.DB.Create(&model.InviteLog{
InviterId: inviteCode.UserId, InviterId: inviteCode.UserId,
UserId: user.Id, UserId: user.Id,
Username: user.Username, Username: user.Username,
@ -155,7 +152,7 @@ func (h *UserHandler) Login(c *gin.Context) {
return return
} }
var user model.User var user model.User
res := h.db.Where("username = ?", data.Username).First(&user) res := h.DB.Where("username = ?", data.Username).First(&user)
if res.Error != nil { if res.Error != nil {
resp.ERROR(c, "用户名不存在") resp.ERROR(c, "用户名不存在")
return return
@ -175,9 +172,9 @@ func (h *UserHandler) Login(c *gin.Context) {
// 更新最后登录时间和IP // 更新最后登录时间和IP
user.LastLoginIp = c.ClientIP() user.LastLoginIp = c.ClientIP()
user.LastLoginAt = time.Now().Unix() user.LastLoginAt = time.Now().Unix()
h.db.Model(&user).Updates(user) h.DB.Model(&user).Updates(user)
h.db.Create(&model.UserLoginLog{ h.DB.Create(&model.UserLoginLog{
UserId: user.Id, UserId: user.Id,
Username: user.Username, Username: user.Username,
LoginIp: c.ClientIP(), LoginIp: c.ClientIP(),
@ -222,7 +219,7 @@ func (h *UserHandler) Logout(c *gin.Context) {
// Session 获取/验证会话 // Session 获取/验证会话
func (h *UserHandler) Session(c *gin.Context) { func (h *UserHandler) Session(c *gin.Context) {
user, err := utils.GetLoginUser(c, h.db) user, err := h.GetLoginUser(c)
if err == nil { if err == nil {
var userVo vo.User var userVo vo.User
err := utils.CopyObject(user, &userVo) err := utils.CopyObject(user, &userVo)
@ -248,13 +245,13 @@ type userProfile struct {
} }
func (h *UserHandler) Profile(c *gin.Context) { func (h *UserHandler) Profile(c *gin.Context) {
user, err := utils.GetLoginUser(c, h.db) user, err := h.GetLoginUser(c)
if err != nil { if err != nil {
resp.NotAuth(c) resp.NotAuth(c)
return return
} }
h.db.First(&user, user.Id) h.DB.First(&user, user.Id)
var profile userProfile var profile userProfile
err = utils.CopyObject(user, &profile) err = utils.CopyObject(user, &profile)
if err != nil { if err != nil {
@ -274,15 +271,15 @@ func (h *UserHandler) ProfileUpdate(c *gin.Context) {
return return
} }
user, err := utils.GetLoginUser(c, h.db) user, err := h.GetLoginUser(c)
if err != nil { if err != nil {
resp.NotAuth(c) resp.NotAuth(c)
return return
} }
h.db.First(&user, user.Id) h.DB.First(&user, user.Id)
user.Avatar = data.Avatar user.Avatar = data.Avatar
user.Nickname = data.Nickname user.Nickname = data.Nickname
res := h.db.Updates(&user) res := h.DB.Updates(&user)
if res.Error != nil { if res.Error != nil {
resp.ERROR(c, "更新用户信息失败") resp.ERROR(c, "更新用户信息失败")
return return
@ -307,7 +304,7 @@ func (h *UserHandler) UpdatePass(c *gin.Context) {
return return
} }
user, err := utils.GetLoginUser(c, h.db) user, err := h.GetLoginUser(c)
if err != nil { if err != nil {
resp.NotAuth(c) resp.NotAuth(c)
return return
@ -321,7 +318,7 @@ func (h *UserHandler) UpdatePass(c *gin.Context) {
} }
newPass := utils.GenPassword(data.Password, user.Salt) newPass := utils.GenPassword(data.Password, user.Salt)
res := h.db.Model(&user).UpdateColumn("password", newPass) res := h.DB.Model(&user).UpdateColumn("password", newPass)
if res.Error != nil { if res.Error != nil {
logger.Error("更新数据库失败: ", res.Error) logger.Error("更新数据库失败: ", res.Error)
resp.ERROR(c, "更新数据库失败") resp.ERROR(c, "更新数据库失败")
@ -344,7 +341,7 @@ func (h *UserHandler) ResetPass(c *gin.Context) {
} }
var user model.User var user model.User
res := h.db.Where("username", data.Username).First(&user) res := h.DB.Where("username", data.Username).First(&user)
if res.Error != nil { if res.Error != nil {
resp.ERROR(c, "用户不存在!") resp.ERROR(c, "用户不存在!")
return return
@ -360,7 +357,7 @@ func (h *UserHandler) ResetPass(c *gin.Context) {
password := utils.GenPassword(data.Password, user.Salt) password := utils.GenPassword(data.Password, user.Salt)
user.Password = password user.Password = password
res = h.db.Updates(&user) res = h.DB.Updates(&user)
if res.Error != nil { if res.Error != nil {
resp.ERROR(c) resp.ERROR(c)
} else { } else {
@ -390,19 +387,19 @@ func (h *UserHandler) BindUsername(c *gin.Context) {
// 检查手机号是否被其他账号绑定 // 检查手机号是否被其他账号绑定
var item model.User var item model.User
res := h.db.Where("username = ?", data.Username).First(&item) res := h.DB.Where("username = ?", data.Username).First(&item)
if res.Error == nil { if res.Error == nil {
resp.ERROR(c, "该账号已经被其他账号绑定") resp.ERROR(c, "该账号已经被其他账号绑定")
return return
} }
user, err := utils.GetLoginUser(c, h.db) user, err := h.GetLoginUser(c)
if err != nil { if err != nil {
resp.NotAuth(c) resp.NotAuth(c)
return return
} }
res = h.db.Model(&user).UpdateColumn("username", data.Username) res = h.DB.Model(&user).UpdateColumn("username", data.Username)
if res.Error != nil { if res.Error != nil {
resp.ERROR(c, "更新数据库失败") resp.ERROR(c, "更新数据库失败")
return return

View File

@ -284,7 +284,7 @@ func main() {
group := s.Engine.Group("/api/admin/user/") group := s.Engine.Group("/api/admin/user/")
group.GET("list", h.List) group.GET("list", h.List)
group.POST("save", h.Save) group.POST("save", h.Save)
group.POST("remove", h.Remove) group.GET("remove", h.Remove)
group.GET("loginLog", h.LoginLog) group.GET("loginLog", h.LoginLog)
group.POST("resetPass", h.ResetPass) group.POST("resetPass", h.ResetPass)
}), }),
@ -386,32 +386,6 @@ func main() {
s.Engine.POST("/api/admin/upload", h.Upload) s.Engine.POST("/api/admin/upload", h.Upload)
}), }),
// 系统管理员
fx.Provide(admin.NewSysUserHandler),
fx.Invoke(func(s *core.AppServer, h *admin.SysUserHandler) {
group := s.Engine.Group("/api/admin/sysUser/")
group.POST("save", h.Save)
group.GET("list", h.List)
group.POST("remove", h.Remove)
group.POST("resetPass", h.ResetPass)
}),
// 权限
fx.Provide(admin.NewSysPermissionHandler),
fx.Invoke(func(s *core.AppServer, h *admin.SysPermissionHandler) {
group := s.Engine.Group("/api/admin/sysPermission/")
group.GET("list", h.List)
group.POST("save", h.Save)
group.POST("remove", h.Remove)
}),
// 角色
fx.Provide(admin.NewSysRoleHandler),
fx.Invoke(func(s *core.AppServer, h *admin.SysRoleHandler) {
group := s.Engine.Group("/api/admin/sysRole/")
group.GET("list", h.List)
group.POST("save", h.Save)
group.POST("remove", h.Remove)
}),
fx.Provide(handler.NewFunctionHandler), fx.Provide(handler.NewFunctionHandler),
fx.Invoke(func(s *core.AppServer, h *handler.FunctionHandler) { fx.Invoke(func(s *core.AppServer, h *handler.FunctionHandler) {
group := s.Engine.Group("/api/function/") group := s.Engine.Group("/api/function/")
@ -429,8 +403,6 @@ func main() {
}), }),
fx.Provide(handler.NewTestHandler), fx.Provide(handler.NewTestHandler),
fx.Invoke(func(s *core.AppServer, h *handler.TestHandler) { fx.Invoke(func(s *core.AppServer, h *handler.TestHandler) {
s.Engine.GET("/api/test", h.Test)
s.Engine.POST("/api/test/mj", h.Mj)
}), }),
fx.Invoke(func(s *core.AppServer, db *gorm.DB) { fx.Invoke(func(s *core.AppServer, db *gorm.DB) {
err := s.Run(db) err := s.Run(db)

View File

@ -1,13 +0,0 @@
package model
import "time"
type AdminPermission struct {
Id int `gorm:"primarykey;column:id"`
Name string
Slug string
Sort int
Pid int
CreatedAt time.Time
UpdatedAt time.Time
}

View File

@ -1,11 +0,0 @@
package model
import "time"
type AdminRole struct {
Id int `gorm:"primarykey;column:id"`
Name string
Description string
CreatedAt time.Time
UpdatedAt time.Time
}

View File

@ -1,11 +0,0 @@
package model
import "time"
type AdminRolePermission struct {
Id int `gorm:"primarykey;column:id"`
RoleId int
PermissionId int
CreatedAt time.Time
UpdatedAt time.Time
}

View File

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

View File

@ -1,10 +0,0 @@
package vo
type AdminPermission struct {
Id int `json:"id"`
Name string `json:"name"`
Slug string `json:"slug"`
Sort int `json:"sort"`
Pid int `json:"pid"`
Children []AdminPermission `json:"children"`
}

View File

@ -1,9 +0,0 @@
package vo
type AdminRole struct {
Id int `json:"id"`
Name string `json:"name"`
Description string `json:"description"`
Permissions interface{} `json:"permissions"`
CreatedAt string `json:"created_at"`
}

View File

@ -1,49 +1,22 @@
package main package main
import ( import "fmt"
"fmt"
"regexp" type Person struct {
) Name string
Age int
}
type Student struct {
Person
School string
}
func main() { func main() {
text := `
> search("Shenzhen weather January 15, 2024")
> mclick([0, 9, 16]) stu := Student{Person: Person{
Name: "xiaoming",
> **end-searching** Age: 12,
}, School: "xxxxx soll"}
今天深圳的天气情况如下 fmt.Println(stu.Name, stu.Age, stu.School)
- 白天气温预计在21°C至24°C之间天气晴朗
- 晚上气温预计在21°C左右云量较多可能会有间断性小雨
- 风向主要是东南风风速大约在6至12公里每小时之间
这些信息表明深圳今天的天气相对舒适适合户外活动晚上可能需要带伞以应对间断性小雨温度较为宜人早晚可能稍微凉爽一些[Shenzhen weather in January 2024 | Shenzhen 14 day weather](https://www.weather25.com/asia/china/guangdong/shenzhen?page=month&month=January)】【[Hourly forecast for Shenzhen, Guangdong, China](https://www.timeanddate.com/weather/china/shenzhen/hourly)】【[Shenzhen Guangdong China 15 Day Weather Forecast](https://www.weatheravenue.com/en/asia/cn/guangdong/shenzhen-weather-15-days.html)】。
我将根据这些信息生成一张气象图展示深圳今天的天气情况
{"prompt":"A detailed weather map for Shenzhen, China, on January 15, 2024. The map shows a sunny day with clear skies during the day and partly cloudy skies at night. Temperatures range from 21\u00b0C to 24\u00b0C during the day and around 21\u00b0C at night. There are indications of light southeast winds during the day and evening, with wind speeds ranging from 6 to 12 km/h. The map includes symbols for sunshine, light clouds, and wind direction arrows, along with temperature readings for different times of the day. The layout is clear, with a focus on Shenzhen's geographical location and the surrounding region.","size":"1024x1024"}
![image1](https://filesystem.site/cdn/20240115/XD6EjyPDGCD4X3AQt3h3FijRmSb6fB.webp)
![下载1](https://filesystem.site/cdn/download/20240115/XD6EjyPDGCD4X3AQt3h3FijRmSb6fB.webp)
And here is another image link: ![another image](https://example.com/another-image.png).
这是根据今天深圳的天气情况制作的气象图图中展示了白天晴朗夜间部分多云的天气以及相关的温度和风向信息`
pattern := `!\[([^\]]*)]\(([^)]+)\)`
// 编译正则表达式
re := regexp.MustCompile(pattern)
// 查找匹配的字符串
matches := re.FindAllStringSubmatch(text, -1)
// 提取链接并打印
for _, match := range matches {
fmt.Println(match[2])
}
} }

View File

@ -1,30 +0,0 @@
package utils
import (
"chatplus/core/types"
"chatplus/store/model"
"errors"
"github.com/gin-gonic/gin"
"gorm.io/gorm"
)
func GetLoginUser(c *gin.Context, db *gorm.DB) (model.User, error) {
value, exists := c.Get(types.LoginUserCache)
if exists {
return value.(model.User), nil
}
userId, ok := c.Get(types.LoginUserID)
if !ok {
return model.User{}, errors.New("user not login")
}
var user model.User
res := db.First(&user, userId)
// 更新缓存
if res.Error == nil {
c.Set(types.LoginUserCache, user)
}
return user, res.Error
}

View File

@ -61,76 +61,6 @@ CREATE TABLE `chatgpt_admin_users` (
INSERT INTO `chatgpt_admin_users` VALUES (1, 'admin', '6d17e80c87d209efb84ca4b2e0824f549d09fac8b2e1cc698de5bb5e1d75dfd0', 'mmrql75o', 1, 1710238055, '172.22.11.29', '2024-03-11 16:30:20', '2024-03-12 18:07:35'); INSERT INTO `chatgpt_admin_users` VALUES (1, 'admin', '6d17e80c87d209efb84ca4b2e0824f549d09fac8b2e1cc698de5bb5e1d75dfd0', 'mmrql75o', 1, 1710238055, '172.22.11.29', '2024-03-11 16:30:20', '2024-03-12 18:07:35');
CREATE TABLE `chatgpt_admin_user_roles` (
`id` int NOT NULL AUTO_INCREMENT COMMENT 'ID',
`admin_id` int NOT NULL COMMENT '用户ID',
`role_id` int NOT NULL COMMENT '角色ID',
`created_at` datetime NOT NULL,
`updated_at` datetime NOT NULL,
PRIMARY KEY (`id`) USING BTREE,
KEY `idx_admin_id` (`admin_id`),
KEY `idx_role_id` (`role_id`) USING BTREE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci COMMENT='用户角色表';
CREATE TABLE `chatgpt_admin_roles` (
`id` int NOT NULL AUTO_INCREMENT COMMENT 'ID',
`name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL DEFAULT '' COMMENT '角色名称',
`description` varchar(255) DEFAULT '' COMMENT '描述',
`created_at` datetime NOT NULL,
`updated_at` datetime NOT NULL,
PRIMARY KEY (`id`) USING BTREE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci COMMENT='角色表';
CREATE TABLE `chatgpt_admin_role_permissions` (
`id` int NOT NULL AUTO_INCREMENT COMMENT 'ID',
`role_id` int NOT NULL COMMENT '角色ID',
`permission_id` int NOT NULL COMMENT '权限ID',
`created_at` datetime NOT NULL,
`updated_at` datetime NOT NULL,
PRIMARY KEY (`id`) USING BTREE,
KEY `idx_role_id` (`role_id`),
KEY `idx_permission_id` (`permission_id`) USING BTREE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci COMMENT='用户角色表';
CREATE TABLE `chatgpt_admin_permissions` (
`id` int unsigned NOT NULL AUTO_INCREMENT COMMENT 'ID',
`name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL DEFAULT '' COMMENT '权限名称(模块@菜单名称@方法)',
`slug` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL DEFAULT '' COMMENT '前端权限模块',
`sort` int NOT NULL DEFAULT '1' COMMENT '排序(越大排越靠前)',
`pid` int NOT NULL DEFAULT '0' COMMENT '父节点',
`created_at` datetime DEFAULT NULL,
`updated_at` datetime DEFAULT NULL,
PRIMARY KEY (`id`),
KEY `idx_slug` (`slug`) USING BTREE
) ENGINE=InnoDB AUTO_INCREMENT=35 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci COMMENT='权限表';
INSERT INTO `chatgpt_admin_permissions` VALUES (6, '用户管理', '', 2, 0, '2024-03-14 10:47:41', '2024-03-14 10:48:41');
INSERT INTO `chatgpt_admin_permissions` VALUES (7, '列表', 'api_admin_user_list', 1, 6, '2024-03-14 10:53:36', '2024-03-14 10:53:36');
INSERT INTO `chatgpt_admin_permissions` VALUES (10, '角色模型', '', 3, 0, '2024-03-14 11:02:45', '2024-03-14 11:02:45');
INSERT INTO `chatgpt_admin_permissions` VALUES (11, '列表', 'api_admin_role_list', 1, 10, '2024-03-14 11:03:43', '2024-03-14 11:03:45');
INSERT INTO `chatgpt_admin_permissions` VALUES (12, '语言模型', '', 4, 0, '2024-03-14 11:05:00', '2024-03-14 11:05:00');
INSERT INTO `chatgpt_admin_permissions` VALUES (13, '列表', 'api_admin_model_list', 1, 12, '2024-03-14 11:05:36', '2024-03-14 11:05:36');
INSERT INTO `chatgpt_admin_permissions` VALUES (14, '充值产品', '', 5, 0, '2024-03-14 11:16:37', '2024-03-14 11:16:37');
INSERT INTO `chatgpt_admin_permissions` VALUES (15, '列表', 'api_admin_product_list', 1, 14, '2024-03-14 11:17:05', '2024-03-14 11:17:05');
INSERT INTO `chatgpt_admin_permissions` VALUES (16, 'APIKEY', '', 6, 0, '2024-03-14 11:17:16', '2024-03-14 11:17:16');
INSERT INTO `chatgpt_admin_permissions` VALUES (17, '列表', 'api_admin_apikey_list', 1, 16, '2024-03-14 11:17:53', '2024-03-14 11:18:02');
INSERT INTO `chatgpt_admin_permissions` VALUES (18, '充值订单', '', 7, 0, '2024-03-14 11:18:20', '2024-03-14 11:18:20');
INSERT INTO `chatgpt_admin_permissions` VALUES (19, '列表', 'api_admin_order_list', 1, 18, '2024-03-14 11:18:44', '2024-03-14 11:18:44');
INSERT INTO `chatgpt_admin_permissions` VALUES (20, '众筹管理', '', 8, 0, '2024-03-14 11:18:59', '2024-03-14 11:18:59');
INSERT INTO `chatgpt_admin_permissions` VALUES (21, '列表', 'api_admin_reward_list', 1, 20, '2024-03-14 11:19:28', '2024-03-14 11:19:28');
INSERT INTO `chatgpt_admin_permissions` VALUES (22, '函数管理', '', 9, 0, '2024-03-14 11:19:42', '2024-03-14 11:19:42');
INSERT INTO `chatgpt_admin_permissions` VALUES (23, '列表', 'api_admin_function_list', 1, 22, '2024-03-14 11:20:07', '2024-03-14 11:20:07');
INSERT INTO `chatgpt_admin_permissions` VALUES (24, '对话管理', '', 10, 0, '2024-03-14 11:20:30', '2024-03-14 11:20:30');
INSERT INTO `chatgpt_admin_permissions` VALUES (25, '列表', 'api_admin_chat_list', 1, 24, '2024-03-14 11:20:51', '2024-03-14 11:20:51');
INSERT INTO `chatgpt_admin_permissions` VALUES (26, '网站设置', '', 11, 0, '2024-03-14 11:21:05', '2024-03-14 11:21:05');
INSERT INTO `chatgpt_admin_permissions` VALUES (27, '配置列表', 'api_admin_config_get', 1, 26, '2024-03-14 11:21:53', '2024-03-14 11:21:53');
INSERT INTO `chatgpt_admin_permissions` VALUES (28, '系统配置', '', 12, 0, '2024-03-14 11:22:07', '2024-03-14 15:28:22');
INSERT INTO `chatgpt_admin_permissions` VALUES (29, '列表', 'api_admin_sysUser_list', 1, 30, '2024-03-14 11:22:36', '2024-03-14 15:28:52');
INSERT INTO `chatgpt_admin_permissions` VALUES (30, '系统管理员', '', 1, 28, '2024-03-14 15:28:43', '2024-03-14 15:28:43');
INSERT INTO `chatgpt_admin_permissions` VALUES (31, '权限配置', '', 2, 28, '2024-03-14 15:29:05', '2024-03-14 15:29:05');
INSERT INTO `chatgpt_admin_permissions` VALUES (32, '角色配置', '', 3, 28, '2024-03-14 15:29:15', '2024-03-14 15:29:15');
INSERT INTO `chatgpt_admin_permissions` VALUES (33, '列表', 'api_admin_sysPermission_list', 1, 31, '2024-03-14 15:29:52', '2024-03-14 15:29:52');
INSERT INTO `chatgpt_admin_permissions` VALUES (34, '列表', 'api_admin_sysRole_list', 1, 32, '2024-03-14 15:30:21', '2024-03-14 15:30:21');
ALTER TABLE `chatgpt_api_keys` CHANGE `use_proxy` `proxy_url` VARCHAR(100) NULL DEFAULT NULL COMMENT '代理地址'; ALTER TABLE `chatgpt_api_keys` CHANGE `use_proxy` `proxy_url` VARCHAR(100) NULL DEFAULT NULL COMMENT '代理地址';
-- 重置 proxy_url -- 重置 proxy_url

View File

@ -6,55 +6,20 @@
:show-close="false" :show-close="false"
:before-close="close" :before-close="close"
> >
<template #header="{ close, titleId, titleClass }"> <template #header="{titleId, titleClass }">
<div class="header"> <div class="header">
<div class="title">用户登录</div> <div class="title" v-if="login">用户登录</div>
<div class="title" v-else>用户注册</div>
<div class="close-icon"> <div class="close-icon">
<el-icon> <el-icon @click="close">
<Close/> <Close/>
</el-icon> </el-icon>
</div> </div>
</div> </div>
</template> </template>
<div class="login-box"> <div class="login-box" v-if="login">
<el-form label-width="75px"> <el-form :model="data" label-width="120px" class="form">
<el-form-item>
<template #label>
<div class="label">
<el-icon>
<User/>
</el-icon>
<span>账号</span>
</div>
</template>
<template #default>
<el-input v-model="data.username" size="large" placeholder="账号"/>
</template>
</el-form-item>
<el-form-item>
<template #label>
<div class="label">
<el-icon>
<Lock/>
</el-icon>
<span>密码</span>
</div>
</template>
<template #default>
<el-input v-model="data.password" type="password" size="large" placeholder="密码"/>
</template>
</el-form-item>
<div class="login-btn">
<el-button type="primary" @click="submit" size="large" round>登录</el-button>
<el-button plain @click="submit" size="large" round>注册</el-button>
</div>
</el-form>
</div>
<div class="register-box">
<el-form :model="data" label-width="120px" ref="formRef">
<div class="block"> <div class="block">
<el-input placeholder="账号" <el-input placeholder="账号"
size="large" size="large"
@ -81,6 +46,119 @@
</el-input> </el-input>
</div> </div>
<el-row class="btn-row" :gutter="20">
<el-col :span="12">
<el-button class="login-btn" type="primary" size="large" @click="submitLogin">登录</el-button>
</el-col>
<el-col :span="12">
<div class="text">
还没有账号
<el-tag @click="login = false">注册</el-tag>
</div>
</el-col>
</el-row>
</el-form>
</div>
<div class="register-box" v-else>
<el-form :model="data" class="form" v-if="enableRegister">
<el-tabs v-model="activeName" class="demo-tabs">
<el-tab-pane label="手机注册" name="mobile" v-if="enableMobile">
<div class="block">
<el-input placeholder="手机号码"
size="large"
v-model="data.username"
autocomplete="off">
<template #prefix>
<el-icon>
<Iphone/>
</el-icon>
</template>
</el-input>
</div>
<div class="block">
<el-row :gutter="10">
<el-col :span="12">
<el-input placeholder="验证码"
size="large" maxlength="30"
v-model="data.code"
autocomplete="off">
<template #prefix>
<el-icon>
<Checked/>
</el-icon>
</template>
</el-input>
</el-col>
<el-col :span="12">
<send-msg size="large" :receiver="data.username"/>
</el-col>
</el-row>
</div>
</el-tab-pane>
<el-tab-pane label="邮箱注册" name="email" v-if="enableEmail">
<div class="block">
<el-input placeholder="邮箱地址"
size="large"
v-model="data.username"
autocomplete="off">
<template #prefix>
<el-icon>
<Iphone/>
</el-icon>
</template>
</el-input>
</div>
<div class="block">
<el-row :gutter="10">
<el-col :span="12">
<el-input placeholder="验证码"
size="large" maxlength="30"
v-model="data.code"
autocomplete="off">
<template #prefix>
<el-icon>
<Checked/>
</el-icon>
</template>
</el-input>
</el-col>
<el-col :span="12">
<send-msg size="large" :receiver="data.username"/>
</el-col>
</el-row>
</div>
</el-tab-pane>
<el-tab-pane label="用户名注册" name="username" v-if="enableUser">
<div class="block">
<el-input placeholder="用户名"
size="large"
v-model="data.username"
autocomplete="off">
<template #prefix>
<el-icon>
<Iphone/>
</el-icon>
</template>
</el-input>
</div>
</el-tab-pane>
</el-tabs>
<div class="block">
<el-input placeholder="请输入密码(8-16位)"
maxlength="16" size="large"
v-model="data.password" show-password
autocomplete="off">
<template #prefix>
<el-icon>
<Lock/>
</el-icon>
</template>
</el-input>
</div>
<div class="block"> <div class="block">
<el-input placeholder="重复密码(8-16位)" <el-input placeholder="重复密码(8-16位)"
size="large" maxlength="16" v-model="data.repass" show-password size="large" maxlength="16" v-model="data.repass" show-password
@ -93,26 +171,6 @@
</el-input> </el-input>
</div> </div>
<div class="block">
<el-row :gutter="10">
<el-col :span="12">
<el-input placeholder="验证码"
size="large" maxlength="30"
v-model="data.code"
autocomplete="off">
<template #prefix>
<el-icon>
<Checked/>
</el-icon>
</template>
</el-input>
</el-col>
<el-col :span="12">
<send-msg size="large" :receiver="data.username"/>
</el-col>
</el-row>
</div>
<div class="block"> <div class="block">
<el-input placeholder="邀请码(可选)" <el-input placeholder="邀请码(可选)"
size="large" size="large"
@ -126,27 +184,51 @@
</el-input> </el-input>
</div> </div>
<el-row class="btn-row"> <el-row class="btn-row" :gutter="20">
<el-button class="login-btn" type="primary" @click="">注册</el-button> <el-col :span="12">
</el-row> <el-button class="login-btn" type="primary" size="large" @click="submitRegister">注册</el-button>
</el-col>
<el-col :span="12">
<div class="text">
已有账号
<el-tag @click="login = true">登录</el-tag>
</div>
</el-col>
<el-row class="text-line">
已经有账号
<el-link type="primary" @click="">登录</el-link>
</el-row> </el-row>
</el-form> </el-form>
<div class="tip-result" v-else>
<el-row :gutter="20">
<el-col :span="12">
<el-result icon="error" title="注册功能已关闭">
<template #sub-title>
<p>抱歉系统已关闭注册功能请联系管理员添加账号</p>
</template>
</el-result>
</el-col>
<el-col :span="12">
<div class="wechat-card">
<el-image :src="wxImg"/>
</div>
</el-col>
</el-row>
</div>
</div> </div>
</el-dialog> </el-dialog>
</template> </template>
<script setup> <script setup>
import {computed, ref} from "vue" import {computed, ref} from "vue"
import {httpPost} from "@/utils/http"; import {httpGet, httpPost} from "@/utils/http";
import {ElMessage} from "element-plus"; import {ElMessage} from "element-plus";
import {setUserToken} from "@/store/session"; import {setUserToken} from "@/store/session";
import {validateMobile} from "@/utils/validate"; import {validateEmail, validateMobile} from "@/utils/validate";
import {Checked, Close, Iphone, Lock, Message, Position, User} from "@element-plus/icons-vue"; import {Checked, Close, Iphone, Lock, Message, Position, User} from "@element-plus/icons-vue";
import SendMsg from "@/components/SendMsg.vue"; import SendMsg from "@/components/SendMsg.vue";
import {arrayContains} from "@/utils/libs";
import {useRouter} from "vue-router";
// eslint-disable-next-line no-undef // eslint-disable-next-line no-undef
const props = defineProps({ const props = defineProps({
@ -155,21 +237,106 @@ const props = defineProps({
const showDialog = computed(() => { const showDialog = computed(() => {
return props.show return props.show
}) })
const login = ref(true)
const data = ref({ const data = ref({
username: "", username: "",
password: "" password: "",
repass: "",
code: "",
invite_code: ""
}) })
const enableMobile = ref(false)
const enableEmail = ref(false)
const enableUser = ref(false)
const enableRegister = ref(false)
const activeName = ref("mobile")
const wxImg = ref("/images/wx.png")
// eslint-disable-next-line no-undef // eslint-disable-next-line no-undef
const emits = defineEmits(['hide']); const emits = defineEmits(['hide', 'success']);
const submit = function () {
httpGet("/api/config/get?key=system").then(res => {
if (res.data) {
const registerWays = res.data['register_ways']
if (arrayContains(registerWays, "mobile")) {
enableMobile.value = true
}
if (arrayContains(registerWays, "email")) {
enableEmail.value = true
}
if (arrayContains(registerWays, "username")) {
enableUser.value = true
}
//
enableRegister.value = res.data['enabled_register']
// 使
if (res.data['wechat_card_url'] !== '') {
wxImg.value = res.data['wechat_card_url']
}
}
}).catch(e => {
ElMessage.error("获取系统配置失败:" + e.message)
})
//
const submitLogin = () => {
if (data.value.username === '') {
return ElMessage.error('请输入用户名');
}
if (data.value.password === '') {
return ElMessage.error('请输入密码');
}
httpPost('/api/user/login', data.value).then((res) => { httpPost('/api/user/login', data.value).then((res) => {
setUserToken(res.data) setUserToken(res.data)
ElMessage.success("登录成功!") ElMessage.success("登录成功!")
emits("hide") emits("hide")
emits('success')
}).catch((e) => { }).catch((e) => {
ElMessage.error('登录失败,' + e.message) ElMessage.error('登录失败,' + e.message)
}) })
} }
//
const submitRegister = () => {
if (data.value.username === '') {
return ElMessage.error('请输入用户名');
}
if (activeName.value === 'mobile' && !validateMobile(data.value.username)) {
return ElMessage.error('请输入合法的手机号');
}
if (activeName.value === 'email' && !validateEmail(data.value.username)) {
return ElMessage.error('请输入合法的邮箱地址');
}
if (data.value.password.length < 8) {
return ElMessage.error('密码的长度为8-16个字符');
}
if (data.value.repass !== data.value.password) {
return ElMessage.error('两次输入密码不一致');
}
if ((activeName.value === 'mobile' || activeName.value === 'email') && data.value.code === '') {
return ElMessage.error('请输入验证码');
}
data.value.reg_way = activeName.value
httpPost('/api/user/register', data.value).then((res) => {
setUserToken(res.data)
ElMessage.success({
"message": "注册成功!",
onClose: () => {
emits("hide")
emits('success')
},
duration: 1000
})
}).catch((e) => {
ElMessage.error('注册失败,' + e.message)
})
}
const close = function () { const close = function () {
emits('hide', false); emits('hide', false);
} }
@ -191,7 +358,7 @@ const close = function () {
.close-icon { .close-icon {
cursor pointer cursor pointer
position absolute position absolute
right 0 right -10px
top 0 top 0
font-weight normal font-weight normal
font-size 20px font-size 20px
@ -202,31 +369,37 @@ const close = function () {
} }
} }
.login-box {
.label {
padding-top 3px
.el-icon { .el-dialog__body {
position relative padding 10px 20px 20px 20px
font-size 20px }
margin-right 6px
top 4px
}
span { .form {
font-size 16px .block {
} margin-bottom 10px
} }
.login-btn { .btn-row {
display flex display flex
padding-top 10px
justify-content center
.el-button { .el-button {
font-size 16px width 100%
width 100px
} }
.text {
line-height 40px
.el-tag {
cursor pointer
}
}
}
}
.register-box {
.wechat-card {
text-align center
} }
} }

View File

@ -83,7 +83,7 @@
<div class="chat-head"> <div class="chat-head">
<div class="chat-config"> <div class="chat-config">
<!-- <span class="role-select-label">聊天角色</span>--> <!-- <span class="role-select-label">聊天角色</span>-->
<el-select v-model="roleId" filterable placeholder="角色" class="role-select" @change="newChat"> <el-select v-model="roleId" filterable placeholder="角色" class="role-select" @change="_newChat">
<el-option <el-option
v-for="item in roles" v-for="item in roles"
:key="item.id" :key="item.id"
@ -97,7 +97,7 @@
</el-option> </el-option>
</el-select> </el-select>
<el-select v-model="modelID" placeholder="模型" @change="newChat"> <el-select v-model="modelID" placeholder="模型" @change="_newChat">
<el-option <el-option
v-for="item in models" v-for="item in models"
:key="item.id" :key="item.id"
@ -238,7 +238,7 @@
<config-dialog v-if="isLogin" :show="showConfigDialog" :models="models" @hide="showConfigDialog = false"/> <config-dialog v-if="isLogin" :show="showConfigDialog" :models="models" @hide="showConfigDialog = false"/>
<login-dialog :show="true"/> <login-dialog :show="showLoginDialog" @hide="showLoginDialog = false" @success="initData"/>
</div> </div>
@ -292,6 +292,7 @@ const roleId = ref(0)
const newChatItem = ref(null); const newChatItem = ref(null);
const router = useRouter(); const router = useRouter();
const showConfigDialog = ref(false); const showConfigDialog = ref(false);
const showLoginDialog = ref(false)
const isLogin = ref(false) const isLogin = ref(false)
const showHello = ref(true) const showHello = ref(true)
const textInput = ref(null) const textInput = ref(null)
@ -303,26 +304,65 @@ if (isMobile()) {
router.replace("/mobile") router.replace("/mobile")
} }
//
httpGet("/api/config/get?key=system").then(res => {
title.value = res.data.title
}).catch(e => {
ElMessage.error("获取系统配置失败:" + e.message)
})
//
httpGet("/api/config/get?key=notice").then(res => {
notice.value = md.render(res.data['content'])
const oldNotice = localStorage.getItem(noticeKey.value);
//
if (oldNotice !== notice.value && notice.value.length > 10) {
showNotice.value = true
}
}).catch(e => {
ElMessage.error("获取系统配置失败:" + e.message)
})
onMounted(() => { onMounted(() => {
resizeElement(); resizeElement();
initData()
const clipboard = new Clipboard('.copy-reply, .copy-code-btn');
clipboard.on('success', () => {
ElMessage.success('复制成功!');
})
clipboard.on('error', () => {
ElMessage.error('复制失败!');
})
window.onresize = () => resizeElement();
});
//
const initData = () => {
//
checkSession().then((user) => { checkSession().then((user) => {
loginUser.value = user loginUser.value = user
isLogin.value = true isLogin.value = true
// //
httpGet("/api/chat/list?user_id=" + loginUser.value.id).then((res) => { httpGet("/api/chat/list").then((res) => {
if (res.data) { if (res.data) {
chatList.value = res.data; chatList.value = res.data;
allChats.value = res.data; allChats.value = res.data;
} }
// //
httpGet('/api/model/list?enable=1').then(res => { httpGet('/api/model/list').then(res => {
models.value = res.data models.value = res.data
modelID.value = models.value[0].id modelID.value = models.value[0].id
// //
httpGet(`/api/role/list?user_id=${user.id}`).then((res) => { httpGet(`/api/role/list`).then((res) => {
roles.value = res.data; roles.value = res.data;
roleId.value = roles.value[0]['id']; roleId.value = roles.value[0]['id'];
const chatId = localStorage.getItem("chat_id") const chatId = localStorage.getItem("chat_id")
const chat = getChatById(chatId) const chat = getChatById(chatId)
if (chat === null) { if (chat === null) {
@ -338,45 +378,38 @@ onMounted(() => {
}).catch(e => { }).catch(e => {
ElMessage.error("加载模型失败: " + e.message) ElMessage.error("加载模型失败: " + e.message)
}) })
}).catch(() => { }).catch(() => {
// TODO: ElMessage.error("加载会话列表失败!")
})
}).catch(() => {
loading.value = false
//
httpGet("/api/chat/list").then((res) => {
if (res.data) {
chatList.value = res.data;
allChats.value = res.data;
}
}).catch(() => {
ElMessage.error("加载会话列表失败!") ElMessage.error("加载会话列表失败!")
}) })
// //
httpGet("/api/config/get?key=system").then(res => { httpGet('/api/model/list').then(res => {
title.value = res.data.title models.value = res.data
modelID.value = models.value[0].id
}).catch(e => { }).catch(e => {
ElMessage.error("获取系统配置失败:" + e.message) ElMessage.error("加载模型失败: " + e.message)
}) })
// //
httpGet("/api/config/get?key=notice").then(res => { httpGet(`/api/role/list`).then((res) => {
notice.value = md.render(res.data['content']) roles.value = res.data;
const oldNotice = localStorage.getItem(noticeKey.value); roleId.value = roles.value[0]['id'];
// }).catch((e) => {
if (oldNotice !== notice.value && notice.value.length > 10) { ElMessage.error('获取聊天角色失败: ' + e.messages)
showNotice.value = true
}
}).catch(e => {
ElMessage.error("获取系统配置失败:" + e.message)
}) })
}).catch(() => {
router.push('/login')
});
const clipboard = new Clipboard('.copy-reply, .copy-code-btn');
clipboard.on('success', () => {
ElMessage.success('复制成功!');
}) })
}
clipboard.on('error', () => {
ElMessage.error('复制失败!');
})
window.onresize = () => resizeElement();
});
const getRoleById = function (rid) { const getRoleById = function (rid) {
for (let i = 0; i < roles.value.length; i++) { for (let i = 0; i < roles.value.length; i++) {
@ -393,8 +426,17 @@ const resizeElement = function () {
leftBoxHeight.value = window.innerHeight - 43 - 47 - 45; leftBoxHeight.value = window.innerHeight - 43 - 47 - 45;
}; };
const _newChat = () => {
if (isLogin.value) {
newChat()
}
}
// //
const newChat = function () { const newChat = () => {
if (!isLogin.value) {
showLoginDialog.value = true
return;
}
// //
if (newChatItem.value !== null && newChatItem.value['role_id'] === roles.value[0]['role_id']) { if (newChatItem.value !== null && newChatItem.value['role_id'] === roles.value[0]['role_id']) {
return; return;
@ -707,6 +749,11 @@ const autofillPrompt = (text) => {
} }
// //
const sendMessage = function () { const sendMessage = function () {
if (!isLogin.value) {
showLoginDialog.value = true
return;
}
if (canSend.value === false) { if (canSend.value === false) {
ElMessage.warning("AI 正在作答中,请稍后..."); ElMessage.warning("AI 正在作答中,请稍后...");
return return
@ -769,8 +816,8 @@ const clearAllChats = function () {
const logout = function () { const logout = function () {
activelyClose.value = true; activelyClose.value = true;
httpGet('/api/user/logout').then(() => { httpGet('/api/user/logout').then(() => {
removeUserToken(); removeUserToken()
router.push('/login'); location.reload()
}).catch(() => { }).catch(() => {
ElMessage.error('注销失败!'); ElMessage.error('注销失败!');
}) })

View File

@ -62,6 +62,7 @@
<el-checkbox-group v-model="system['register_ways']"> <el-checkbox-group v-model="system['register_ways']">
<el-checkbox label="mobile">手机注册</el-checkbox> <el-checkbox label="mobile">手机注册</el-checkbox>
<el-checkbox label="email">邮箱注册</el-checkbox> <el-checkbox label="email">邮箱注册</el-checkbox>
<el-checkbox label="username">用户名注册</el-checkbox>
</el-checkbox-group> </el-checkbox-group>
</el-form-item> </el-form-item>