🎉 初始化项目

This commit is contained in:
2026-03-03 06:05:51 +08:00
commit e1c70fe218
241 changed files with 148285 additions and 0 deletions

View File

@@ -0,0 +1,6 @@
package system
type ServiceGroup struct {
UserService UserService
ApiService ApiService
}

View File

@@ -0,0 +1,155 @@
package system
import (
"errors"
"git.echol.cn/loser/ai_proxy/server/global"
"git.echol.cn/loser/ai_proxy/server/model/system"
"git.echol.cn/loser/ai_proxy/server/model/system/request"
"git.echol.cn/loser/ai_proxy/server/model/system/response"
"gorm.io/gorm"
)
type ApiService struct{}
// CreateApi 创建API
func (s *ApiService) CreateApi(req *request.CreateApiRequest) error {
// 检查是否已存在相同的 API
var count int64
err := global.GVA_DB.Model(&system.SysApi{}).
Where("path = ? AND method = ?", req.Path, req.Method).
Count(&count).Error
if err != nil {
return err
}
if count > 0 {
return errors.New("API已存在")
}
api := system.SysApi{
Path: req.Path,
Description: req.Description,
ApiGroup: req.ApiGroup,
Method: req.Method,
}
return global.GVA_DB.Create(&api).Error
}
// UpdateApi 更新API
func (s *ApiService) UpdateApi(req *request.UpdateApiRequest) error {
var api system.SysApi
if err := global.GVA_DB.First(&api, req.ID).Error; err != nil {
if errors.Is(err, gorm.ErrRecordNotFound) {
return errors.New("API不存在")
}
return err
}
// 检查是否有其他相同的 API
var count int64
err := global.GVA_DB.Model(&system.SysApi{}).
Where("path = ? AND method = ? AND id != ?", req.Path, req.Method, req.ID).
Count(&count).Error
if err != nil {
return err
}
if count > 0 {
return errors.New("API已存在")
}
updates := map[string]interface{}{
"path": req.Path,
"description": req.Description,
"api_group": req.ApiGroup,
"method": req.Method,
}
return global.GVA_DB.Model(&api).Updates(updates).Error
}
// DeleteApi 删除API
func (s *ApiService) DeleteApi(id uint) error {
var api system.SysApi
if err := global.GVA_DB.First(&api, id).Error; err != nil {
if errors.Is(err, gorm.ErrRecordNotFound) {
return errors.New("API不存在")
}
return err
}
return global.GVA_DB.Delete(&api).Error
}
// GetApiList 获取API列表
func (s *ApiService) GetApiList(req *request.GetApiListRequest) (list []response.ApiInfo, total int64, err error) {
db := global.GVA_DB.Model(&system.SysApi{})
// 条件查询
if req.Path != "" {
db = db.Where("path LIKE ?", "%"+req.Path+"%")
}
if req.ApiGroup != "" {
db = db.Where("api_group = ?", req.ApiGroup)
}
if req.Method != "" {
db = db.Where("method = ?", req.Method)
}
// 获取总数
err = db.Count(&total).Error
if err != nil {
return nil, 0, err
}
// 分页查询
if req.Page > 0 && req.PageSize > 0 {
offset := (req.Page - 1) * req.PageSize
db = db.Offset(offset).Limit(req.PageSize)
}
var apis []system.SysApi
err = db.Order("created_at DESC").Find(&apis).Error
if err != nil {
return nil, 0, err
}
// 转换为响应格式
list = make([]response.ApiInfo, len(apis))
for i, api := range apis {
list[i] = response.ApiInfo{
ID: api.ID,
Path: api.Path,
Description: api.Description,
ApiGroup: api.ApiGroup,
Method: api.Method,
CreatedAt: api.CreatedAt,
UpdatedAt: api.UpdatedAt,
}
}
return list, total, nil
}
// GetApiById 根据ID获取API
func (s *ApiService) GetApiById(id uint) (info response.ApiInfo, err error) {
var api system.SysApi
if err = global.GVA_DB.First(&api, id).Error; err != nil {
if errors.Is(err, gorm.ErrRecordNotFound) {
return info, errors.New("API不存在")
}
return info, err
}
info = response.ApiInfo{
ID: api.ID,
Path: api.Path,
Description: api.Description,
ApiGroup: api.ApiGroup,
Method: api.Method,
CreatedAt: api.CreatedAt,
UpdatedAt: api.UpdatedAt,
}
return info, nil
}

View File

@@ -0,0 +1,207 @@
package system
import (
"errors"
"time"
"git.echol.cn/loser/ai_proxy/server/global"
"git.echol.cn/loser/ai_proxy/server/model/system"
"git.echol.cn/loser/ai_proxy/server/model/system/request"
"git.echol.cn/loser/ai_proxy/server/model/system/response"
"git.echol.cn/loser/ai_proxy/server/utils"
"github.com/golang-jwt/jwt/v5"
"golang.org/x/crypto/bcrypt"
)
type UserService struct{}
// Login 用户登录
func (s *UserService) Login(req *request.LoginRequest) (resp response.LoginResponse, err error) {
var user system.SysUser
err = global.GVA_DB.Where("username = ?", req.Username).First(&user).Error
if err != nil {
return resp, errors.New("用户名或密码错误")
}
// 验证密码
err = bcrypt.CompareHashAndPassword([]byte(user.Password), []byte(req.Password))
if err != nil {
return resp, errors.New("用户名或密码错误")
}
// 检查用户状态
if user.Status != "active" {
return resp, errors.New("用户已被禁用")
}
// 生成 JWT Token
token, err := s.generateToken(user.ID, user.Username, user.Role)
if err != nil {
return resp, errors.New("生成Token失败")
}
resp.Token = token
resp.User = response.UserInfo{
ID: user.ID,
Username: user.Username,
Nickname: user.Nickname,
Email: user.Email,
Phone: user.Phone,
Avatar: user.Avatar,
Role: user.Role,
Status: user.Status,
}
return resp, nil
}
// Register 用户注册
func (s *UserService) Register(req *request.RegisterRequest) (user system.SysUser, err error) {
// 检查用户名是否存在
var count int64
global.GVA_DB.Model(&system.SysUser{}).Where("username = ?", req.Username).Count(&count)
if count > 0 {
return user, errors.New("用户名已存在")
}
// 加密密码
hashedPassword, err := bcrypt.GenerateFromPassword([]byte(req.Password), bcrypt.DefaultCost)
if err != nil {
return user, errors.New("密码加密失败")
}
// 生成 API Key
apiKey, err := utils.GenerateRandomString(32)
if err != nil {
return user, errors.New("生成API Key失败")
}
apiKey = "ak-" + apiKey
user = system.SysUser{
Username: req.Username,
Password: string(hashedPassword),
Email: req.Email,
Role: "user",
Status: "active",
APIKey: apiKey,
}
err = global.GVA_DB.Create(&user).Error
return user, err
}
// GetUserInfo 获取用户信息
func (s *UserService) GetUserInfo(userID uint) (info response.UserInfo, err error) {
var user system.SysUser
err = global.GVA_DB.First(&user, userID).Error
if err != nil {
return info, errors.New("用户不存在")
}
info = response.UserInfo{
ID: user.ID,
Username: user.Username,
Nickname: user.Nickname,
Email: user.Email,
Phone: user.Phone,
Avatar: user.Avatar,
Role: user.Role,
Status: user.Status,
}
return info, nil
}
// GetUserList 获取用户列表
func (s *UserService) GetUserList(page, pageSize int) (list []response.UserInfo, total int64, err error) {
var users []system.SysUser
offset := (page - 1) * pageSize
db := global.GVA_DB.Model(&system.SysUser{})
err = db.Count(&total).Error
if err != nil {
return
}
err = db.Limit(pageSize).Offset(offset).Order("created_at DESC").Find(&users).Error
if err != nil {
return
}
for _, user := range users {
list = append(list, response.UserInfo{
ID: user.ID,
Username: user.Username,
Nickname: user.Nickname,
Email: user.Email,
Phone: user.Phone,
Avatar: user.Avatar,
Role: user.Role,
Status: user.Status,
})
}
return list, total, nil
}
// UpdateUser 更新用户
func (s *UserService) UpdateUser(req *request.UpdateUserRequest) error {
updates := map[string]interface{}{}
if req.Nickname != "" {
updates["nickname"] = req.Nickname
}
if req.Email != "" {
updates["email"] = req.Email
}
if req.Phone != "" {
updates["phone"] = req.Phone
}
if req.Avatar != "" {
updates["avatar"] = req.Avatar
}
if req.Role != "" {
updates["role"] = req.Role
}
if req.Status != "" {
updates["status"] = req.Status
}
return global.GVA_DB.Model(&system.SysUser{}).Where("id = ?", req.ID).Updates(updates).Error
}
// DeleteUser 删除用户
func (s *UserService) DeleteUser(userID uint) error {
return global.GVA_DB.Delete(&system.SysUser{}, userID).Error
}
// GetAPIKey 获取用户的 API Key
func (s *UserService) GetAPIKey(userID uint) (string, error) {
var user system.SysUser
err := global.GVA_DB.Select("api_key").First(&user, userID).Error
return user.APIKey, err
}
// RegenerateAPIKey 重新生成 API Key
func (s *UserService) RegenerateAPIKey(userID uint) (string, error) {
randomStr, err := utils.GenerateRandomString(32)
if err != nil {
return "", errors.New("生成API Key失败")
}
apiKey := "ak-" + randomStr
err = global.GVA_DB.Model(&system.SysUser{}).Where("id = ?", userID).Update("api_key", apiKey).Error
return apiKey, err
}
// generateToken 生成 JWT Token
func (s *UserService) generateToken(userID uint, username, role string) (string, error) {
claims := jwt.MapClaims{
"user_id": userID,
"username": username,
"role": role,
"exp": time.Now().Add(24 * time.Hour).Unix(),
}
token := jwt.NewWithClaims(jwt.SigningMethodHS256, claims)
return token.SignedString([]byte(global.GVA_CONFIG.JWT.SigningKey))
}