2934b1d0bc
- 移除预检查算力点步骤,改为请求前预扣算力点 - 添加请求失败时自动返还算力点的功能 - 修改copyAIResponse函数参数以支持失败回调处理 - 在响应状态异常时也执行算力点返还操作 - 从auth服务中移除EnsureUserCredits方法 - 新增RefundUserCredits方法用于返还用户算力点 - 添加AI_REFUND算力点日志类型常量 - 更新算力点日志类型说明及展示标签
186 lines
4.6 KiB
Go
186 lines
4.6 KiB
Go
package repository
|
|
|
|
import (
|
|
"errors"
|
|
"strings"
|
|
|
|
"github.com/basketikun/infinite-canvas/model"
|
|
"gorm.io/gorm"
|
|
)
|
|
|
|
// ListUsers 分页查询用户。
|
|
func ListUsers(q model.Query) ([]model.User, int64, error) {
|
|
db, err := DB()
|
|
if err != nil {
|
|
return nil, 0, err
|
|
}
|
|
q.Normalize()
|
|
tx := db.Model(&model.User{})
|
|
if keyword := strings.TrimSpace(q.Keyword); keyword != "" {
|
|
like := "%" + keyword + "%"
|
|
tx = tx.Where("username LIKE ? OR display_name LIKE ? OR email LIKE ? OR linux_do_id LIKE ?", like, like, like, like)
|
|
}
|
|
|
|
var total int64
|
|
if err := tx.Count(&total).Error; err != nil {
|
|
return nil, 0, err
|
|
}
|
|
|
|
var users []model.User
|
|
err = tx.Order("created_at desc").Offset(q.Offset()).Limit(q.PageSize).Find(&users).Error
|
|
return users, total, err
|
|
}
|
|
|
|
// CountUsers 返回用户总数。
|
|
func CountUsers() (int64, error) {
|
|
db, err := DB()
|
|
if err != nil {
|
|
return 0, err
|
|
}
|
|
var total int64
|
|
return total, db.Model(&model.User{}).Count(&total).Error
|
|
}
|
|
|
|
// HasAdmin 判断系统中是否存在管理员。
|
|
func HasAdmin() (bool, error) {
|
|
db, err := DB()
|
|
if err != nil {
|
|
return false, err
|
|
}
|
|
var total int64
|
|
err = db.Model(&model.User{}).Where("role = ?", model.UserRoleAdmin).Count(&total).Error
|
|
return total > 0, err
|
|
}
|
|
|
|
// GetUserByID 根据 ID 查询用户。
|
|
func GetUserByID(id string) (model.User, bool, error) {
|
|
db, err := DB()
|
|
if err != nil {
|
|
return model.User{}, false, err
|
|
}
|
|
return findUser(db, "id = ?", id)
|
|
}
|
|
|
|
// GetUserByUsername 根据用户名查询用户。
|
|
func GetUserByUsername(username string) (model.User, bool, error) {
|
|
db, err := DB()
|
|
if err != nil {
|
|
return model.User{}, false, err
|
|
}
|
|
return findUser(db, "username = ?", username)
|
|
}
|
|
|
|
// SaveUser 保存用户信息。
|
|
func SaveUser(user model.User) (model.User, error) {
|
|
db, err := DB()
|
|
if err != nil {
|
|
return user, err
|
|
}
|
|
return user, db.Save(&user).Error
|
|
}
|
|
|
|
func ConsumeUserCredits(id string, credits int, now string) (model.User, bool, error) {
|
|
db, err := DB()
|
|
if err != nil {
|
|
return model.User{}, false, err
|
|
}
|
|
if credits <= 0 {
|
|
user, ok, err := GetUserByID(id)
|
|
return user, ok, err
|
|
}
|
|
tx := db.Model(&model.User{}).Where("id = ? AND credits >= ?", id, credits).Updates(map[string]any{
|
|
"credits": gorm.Expr("credits - ?", credits),
|
|
"updated_at": now,
|
|
})
|
|
if tx.Error != nil {
|
|
return model.User{}, false, tx.Error
|
|
}
|
|
user, ok, err := GetUserByID(id)
|
|
return user, ok && tx.RowsAffected > 0, err
|
|
}
|
|
|
|
func RefundUserCredits(id string, credits int, now string) (model.User, bool, error) {
|
|
db, err := DB()
|
|
if err != nil {
|
|
return model.User{}, false, err
|
|
}
|
|
if credits <= 0 {
|
|
user, ok, err := GetUserByID(id)
|
|
return user, ok, err
|
|
}
|
|
tx := db.Model(&model.User{}).Where("id = ?", id).Updates(map[string]any{
|
|
"credits": gorm.Expr("credits + ?", credits),
|
|
"updated_at": now,
|
|
})
|
|
if tx.Error != nil {
|
|
return model.User{}, false, tx.Error
|
|
}
|
|
user, ok, err := GetUserByID(id)
|
|
return user, ok && tx.RowsAffected > 0, err
|
|
}
|
|
|
|
// SaveCreditLog 保存算力点变更流水。
|
|
func SaveCreditLog(log model.CreditLog) (model.CreditLog, error) {
|
|
db, err := DB()
|
|
if err != nil {
|
|
return log, err
|
|
}
|
|
return log, db.Save(&log).Error
|
|
}
|
|
|
|
func ListCreditLogs(q model.Query) ([]model.CreditLog, int64, error) {
|
|
db, err := DB()
|
|
if err != nil {
|
|
return nil, 0, err
|
|
}
|
|
q.Normalize()
|
|
tx := db.Model(&model.CreditLog{})
|
|
if keyword := strings.TrimSpace(q.Keyword); keyword != "" {
|
|
like := "%" + keyword + "%"
|
|
tx = tx.Where("user_id LIKE ? OR type LIKE ? OR remark LIKE ? OR related_id LIKE ?", like, like, like, like)
|
|
}
|
|
var total int64
|
|
if err := tx.Count(&total).Error; err != nil {
|
|
return nil, 0, err
|
|
}
|
|
var logs []model.CreditLog
|
|
err = tx.Order("created_at desc").Offset(q.Offset()).Limit(q.PageSize).Find(&logs).Error
|
|
return logs, total, err
|
|
}
|
|
|
|
func DeleteCreditLog(id string) error {
|
|
db, err := DB()
|
|
if err != nil {
|
|
return err
|
|
}
|
|
return db.Delete(&model.CreditLog{}, "id = ?", id).Error
|
|
}
|
|
|
|
// DeleteUser 删除指定用户。
|
|
func DeleteUser(id string) error {
|
|
db, err := DB()
|
|
if err != nil {
|
|
return err
|
|
}
|
|
return db.Delete(&model.User{}, "id = ?", id).Error
|
|
}
|
|
|
|
// GetUserByLinuxDoID 根据 Linux.do ID 查询用户。
|
|
func GetUserByLinuxDoID(id string) (model.User, bool, error) {
|
|
db, err := DB()
|
|
if err != nil {
|
|
return model.User{}, false, err
|
|
}
|
|
return findUser(db, "linux_do_id = ?", id)
|
|
}
|
|
|
|
// findUser 查询单个用户,并将未命中转换为 ok=false。
|
|
func findUser(db *gorm.DB, query string, args ...any) (model.User, bool, error) {
|
|
user := model.User{}
|
|
err := db.Where(query, args...).First(&user).Error
|
|
if errors.Is(err, gorm.ErrRecordNotFound) {
|
|
return model.User{}, false, nil
|
|
}
|
|
return user, err == nil, err
|
|
}
|