mirror of
https://github.com/songquanpeng/one-api.git
synced 2025-11-16 13:13:41 +08:00
✨ feat: add telegram bot (#71)
This commit is contained in:
@@ -40,7 +40,7 @@ var allowedChannelOrderFields = map[string]bool{
|
||||
"priority": true,
|
||||
}
|
||||
|
||||
func GetChannelsList(params *GenericParams) (*DataResult, error) {
|
||||
func GetChannelsList(params *GenericParams) (*DataResult[Channel], error) {
|
||||
var channels []*Channel
|
||||
|
||||
db := DB.Omit("key")
|
||||
@@ -52,7 +52,7 @@ func GetChannelsList(params *GenericParams) (*DataResult, error) {
|
||||
db = db.Where("id = ? or name LIKE ? or "+keyCol+" = ?", common.String2Int(params.Keyword), params.Keyword+"%", params.Keyword)
|
||||
}
|
||||
|
||||
return PaginateAndOrder(db, ¶ms.PaginationParams, &channels, allowedChannelOrderFields)
|
||||
return PaginateAndOrder[Channel](db, ¶ms.PaginationParams, &channels, allowedChannelOrderFields)
|
||||
}
|
||||
|
||||
func GetAllChannels() ([]*Channel, error) {
|
||||
|
||||
@@ -8,6 +8,10 @@ import (
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
type modelable interface {
|
||||
any
|
||||
}
|
||||
|
||||
type GenericParams struct {
|
||||
PaginationParams
|
||||
Keyword string `form:"keyword"`
|
||||
@@ -19,14 +23,14 @@ type PaginationParams struct {
|
||||
Order string `form:"order"`
|
||||
}
|
||||
|
||||
type DataResult struct {
|
||||
Data interface{} `json:"data"`
|
||||
Page int `json:"page"`
|
||||
Size int `json:"size"`
|
||||
TotalCount int64 `json:"total_count"`
|
||||
type DataResult[T modelable] struct {
|
||||
Data *[]*T `json:"data"`
|
||||
Page int `json:"page"`
|
||||
Size int `json:"size"`
|
||||
TotalCount int64 `json:"total_count"`
|
||||
}
|
||||
|
||||
func PaginateAndOrder(db *gorm.DB, params *PaginationParams, result interface{}, allowedOrderFields map[string]bool) (*DataResult, error) {
|
||||
func PaginateAndOrder[T modelable](db *gorm.DB, params *PaginationParams, result *[]*T, allowedOrderFields map[string]bool) (*DataResult[T], error) {
|
||||
// 获取总数
|
||||
var totalCount int64
|
||||
err := db.Model(result).Count(&totalCount).Error
|
||||
@@ -34,8 +38,6 @@ func PaginateAndOrder(db *gorm.DB, params *PaginationParams, result interface{},
|
||||
return nil, err
|
||||
}
|
||||
|
||||
fmt.Println("totalCount", totalCount)
|
||||
|
||||
// 分页
|
||||
if params.Page < 1 {
|
||||
params.Page = 1
|
||||
@@ -80,7 +82,7 @@ func PaginateAndOrder(db *gorm.DB, params *PaginationParams, result interface{},
|
||||
}
|
||||
|
||||
// 返回结果
|
||||
return &DataResult{
|
||||
return &DataResult[T]{
|
||||
Data: result,
|
||||
Page: params.Page,
|
||||
Size: params.Size,
|
||||
|
||||
@@ -94,7 +94,7 @@ var allowedLogsOrderFields = map[string]bool{
|
||||
"type": true,
|
||||
}
|
||||
|
||||
func GetLogsList(params *LogsListParams) (*DataResult, error) {
|
||||
func GetLogsList(params *LogsListParams) (*DataResult[Log], error) {
|
||||
var tx *gorm.DB
|
||||
var logs []*Log
|
||||
|
||||
@@ -122,10 +122,10 @@ func GetLogsList(params *LogsListParams) (*DataResult, error) {
|
||||
tx = tx.Where("channel_id = ?", params.Channel)
|
||||
}
|
||||
|
||||
return PaginateAndOrder(tx, ¶ms.PaginationParams, &logs, allowedLogsOrderFields)
|
||||
return PaginateAndOrder[Log](tx, ¶ms.PaginationParams, &logs, allowedLogsOrderFields)
|
||||
}
|
||||
|
||||
func GetUserLogsList(userId int, params *LogsListParams) (*DataResult, error) {
|
||||
func GetUserLogsList(userId int, params *LogsListParams) (*DataResult[Log], error) {
|
||||
var logs []*Log
|
||||
|
||||
tx := DB.Where("user_id = ?", userId).Omit("id")
|
||||
@@ -146,7 +146,7 @@ func GetUserLogsList(userId int, params *LogsListParams) (*DataResult, error) {
|
||||
tx = tx.Where("created_at <= ?", params.EndTimestamp)
|
||||
}
|
||||
|
||||
return PaginateAndOrder(tx, ¶ms.PaginationParams, &logs, allowedLogsOrderFields)
|
||||
return PaginateAndOrder[Log](tx, ¶ms.PaginationParams, &logs, allowedLogsOrderFields)
|
||||
}
|
||||
|
||||
func SearchAllLogs(keyword string) (logs []*Log, err error) {
|
||||
|
||||
@@ -2,14 +2,15 @@ package model
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"gorm.io/driver/mysql"
|
||||
"gorm.io/driver/postgres"
|
||||
"gorm.io/driver/sqlite"
|
||||
"gorm.io/gorm"
|
||||
"one-api/common"
|
||||
"os"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"gorm.io/driver/mysql"
|
||||
"gorm.io/driver/postgres"
|
||||
"gorm.io/driver/sqlite"
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
var DB *gorm.DB
|
||||
@@ -113,6 +114,10 @@ func InitDB() (err error) {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
err = db.AutoMigrate(&TelegramMenu{})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
common.SysLog("database migrated")
|
||||
err = createRootAccountIfNeed()
|
||||
return err
|
||||
|
||||
@@ -29,14 +29,14 @@ var allowedRedemptionslOrderFields = map[string]bool{
|
||||
"redeemed_time": true,
|
||||
}
|
||||
|
||||
func GetRedemptionsList(params *GenericParams) (*DataResult, error) {
|
||||
func GetRedemptionsList(params *GenericParams) (*DataResult[Redemption], error) {
|
||||
var redemptions []*Redemption
|
||||
db := DB
|
||||
if params.Keyword != "" {
|
||||
db = db.Where("id = ? or name LIKE ?", common.String2Int(params.Keyword), params.Keyword+"%")
|
||||
}
|
||||
|
||||
return PaginateAndOrder(db, ¶ms.PaginationParams, &redemptions, allowedRedemptionslOrderFields)
|
||||
return PaginateAndOrder[Redemption](db, ¶ms.PaginationParams, &redemptions, allowedRedemptionslOrderFields)
|
||||
}
|
||||
|
||||
func GetRedemptionById(id int) (*Redemption, error) {
|
||||
|
||||
73
model/telegram_menu.go
Normal file
73
model/telegram_menu.go
Normal file
@@ -0,0 +1,73 @@
|
||||
package model
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"one-api/common"
|
||||
)
|
||||
|
||||
type TelegramMenu struct {
|
||||
Id int `json:"id"`
|
||||
Command string `json:"command" gorm:"type:varchar(32);uniqueIndex"`
|
||||
Description string `json:"description" gorm:"type:varchar(255);default:''"`
|
||||
ParseMode string `json:"parse_mode" gorm:"type:varchar(255);default:'MarkdownV2'"`
|
||||
ReplyMessage string `json:"reply_message"`
|
||||
}
|
||||
|
||||
var allowedTelegramMenusOrderFields = map[string]bool{
|
||||
"id": true,
|
||||
"command": true,
|
||||
}
|
||||
|
||||
func GetTelegramMenusList(params *GenericParams) (*DataResult[TelegramMenu], error) {
|
||||
var menus []*TelegramMenu
|
||||
db := DB
|
||||
if params.Keyword != "" {
|
||||
db = db.Where("id = ? or command LIKE ?", common.String2Int(params.Keyword), params.Keyword+"%")
|
||||
}
|
||||
|
||||
return PaginateAndOrder[TelegramMenu](db, ¶ms.PaginationParams, &menus, allowedTelegramMenusOrderFields)
|
||||
}
|
||||
|
||||
// 查询菜单列表 只查询command和description
|
||||
func GetTelegramMenus() ([]*TelegramMenu, error) {
|
||||
var menus []*TelegramMenu
|
||||
err := DB.Select("command, description").Find(&menus).Error
|
||||
return menus, err
|
||||
}
|
||||
|
||||
// 根据command查询菜单
|
||||
func GetTelegramMenuByCommand(command string) (*TelegramMenu, error) {
|
||||
menu := &TelegramMenu{}
|
||||
err := DB.Where("command = ?", command).First(menu).Error
|
||||
return menu, err
|
||||
}
|
||||
|
||||
func GetTelegramMenuById(id int) (*TelegramMenu, error) {
|
||||
if id == 0 {
|
||||
return nil, errors.New("id 为空!")
|
||||
}
|
||||
telegramMenu := TelegramMenu{Id: id}
|
||||
var err error = nil
|
||||
err = DB.First(&telegramMenu, "id = ?", id).Error
|
||||
return &telegramMenu, err
|
||||
}
|
||||
|
||||
func IsTelegramCommandAlreadyTaken(command string, id int) bool {
|
||||
query := DB.Where("command = ?", command)
|
||||
if id != 0 {
|
||||
query = query.Not("id", id)
|
||||
}
|
||||
return query.Find(&TelegramMenu{}).RowsAffected == 1
|
||||
}
|
||||
|
||||
func (menu *TelegramMenu) Insert() error {
|
||||
return DB.Create(menu).Error
|
||||
}
|
||||
|
||||
func (menu *TelegramMenu) Update() error {
|
||||
return DB.Model(menu).Updates(menu).Error
|
||||
}
|
||||
|
||||
func (menu *TelegramMenu) Delete() error {
|
||||
return DB.Delete(menu).Error
|
||||
}
|
||||
@@ -32,7 +32,7 @@ var allowedTokenOrderFields = map[string]bool{
|
||||
"used_quota": true,
|
||||
}
|
||||
|
||||
func GetUserTokensList(userId int, params *GenericParams) (*DataResult, error) {
|
||||
func GetUserTokensList(userId int, params *GenericParams) (*DataResult[Token], error) {
|
||||
var tokens []*Token
|
||||
db := DB.Where("user_id = ?", userId)
|
||||
|
||||
@@ -40,7 +40,13 @@ func GetUserTokensList(userId int, params *GenericParams) (*DataResult, error) {
|
||||
db = db.Where("name LIKE ?", params.Keyword+"%")
|
||||
}
|
||||
|
||||
return PaginateAndOrder(db, ¶ms.PaginationParams, &tokens, allowedTokenOrderFields)
|
||||
return PaginateAndOrder[Token](db, ¶ms.PaginationParams, &tokens, allowedTokenOrderFields)
|
||||
}
|
||||
|
||||
// 获取状态为可用的令牌
|
||||
func GetUserEnabledTokens(userId int) (tokens []*Token, err error) {
|
||||
err = DB.Where("user_id = ? and status = ?", userId, common.TokenStatusEnabled).Find(&tokens).Error
|
||||
return tokens, err
|
||||
}
|
||||
|
||||
func ValidateUserToken(key string) (token *Token, err error) {
|
||||
|
||||
@@ -21,6 +21,7 @@ type User struct {
|
||||
Email string `json:"email" gorm:"index" validate:"max=50"`
|
||||
GitHubId string `json:"github_id" gorm:"column:github_id;index"`
|
||||
WeChatId string `json:"wechat_id" gorm:"column:wechat_id;index"`
|
||||
TelegramId int64 `json:"telegram_id" gorm:"bigint,column:telegram_id;default:0;"`
|
||||
VerificationCode string `json:"verification_code" gorm:"-:all"` // this field is only for Email verification, don't save it to database!
|
||||
AccessToken string `json:"access_token" gorm:"type:char(32);column:access_token;uniqueIndex"` // this token is for system management
|
||||
Quota int `json:"quota" gorm:"type:int;default:0"`
|
||||
@@ -32,6 +33,8 @@ type User struct {
|
||||
CreatedTime int64 `json:"created_time" gorm:"bigint"`
|
||||
}
|
||||
|
||||
type UserUpdates func(*User)
|
||||
|
||||
func GetMaxUserId() int {
|
||||
var user User
|
||||
DB.Last(&user)
|
||||
@@ -46,14 +49,14 @@ var allowedUserOrderFields = map[string]bool{
|
||||
"created_time": true,
|
||||
}
|
||||
|
||||
func GetUsersList(params *GenericParams) (*DataResult, error) {
|
||||
func GetUsersList(params *GenericParams) (*DataResult[User], error) {
|
||||
var users []*User
|
||||
db := DB.Omit("password")
|
||||
if params.Keyword != "" {
|
||||
db = db.Where("id = ? or username LIKE ? or email LIKE ? or display_name LIKE ?", common.String2Int(params.Keyword), params.Keyword+"%", params.Keyword+"%", params.Keyword+"%")
|
||||
}
|
||||
|
||||
return PaginateAndOrder(db, ¶ms.PaginationParams, &users, allowedUserOrderFields)
|
||||
return PaginateAndOrder[User](db, ¶ms.PaginationParams, &users, allowedUserOrderFields)
|
||||
}
|
||||
|
||||
func GetUserById(id int, selectAll bool) (*User, error) {
|
||||
@@ -70,6 +73,17 @@ func GetUserById(id int, selectAll bool) (*User, error) {
|
||||
return &user, err
|
||||
}
|
||||
|
||||
func GetUserByTelegramId(telegramId int64) (*User, error) {
|
||||
if telegramId == 0 {
|
||||
return nil, errors.New("telegramId 为空!")
|
||||
}
|
||||
|
||||
var user User
|
||||
err := DB.First(&user, "telegram_id = ?", telegramId).Error
|
||||
|
||||
return &user, err
|
||||
}
|
||||
|
||||
func GetUserIdByAffCode(affCode string) (int, error) {
|
||||
if affCode == "" {
|
||||
return 0, errors.New("affCode 为空!")
|
||||
@@ -131,6 +145,10 @@ func (user *User) Update(updatePassword bool) error {
|
||||
return err
|
||||
}
|
||||
|
||||
func UpdateUser(id int, fields map[string]interface{}) error {
|
||||
return DB.Model(&User{}).Where("id = ?", id).Updates(fields).Error
|
||||
}
|
||||
|
||||
func (user *User) Delete() error {
|
||||
if user.Id == 0 {
|
||||
return errors.New("id 为空!")
|
||||
@@ -216,6 +234,10 @@ func IsGitHubIdAlreadyTaken(githubId string) bool {
|
||||
return DB.Where("github_id = ?", githubId).Find(&User{}).RowsAffected == 1
|
||||
}
|
||||
|
||||
func IsTelegramIdAlreadyTaken(telegramId int64) bool {
|
||||
return DB.Where("telegram_id = ?", telegramId).Find(&User{}).RowsAffected == 1
|
||||
}
|
||||
|
||||
func IsUsernameAlreadyTaken(username string) bool {
|
||||
return DB.Where("username = ?", username).Find(&User{}).RowsAffected == 1
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user