| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228 |
- package service
- import (
- "errors"
- "fmt"
- "github.com/2930134478/AI-CS/backend/models"
- "github.com/2930134478/AI-CS/backend/repository"
- "github.com/2930134478/AI-CS/backend/utils"
- )
- // AIConfigService AI 配置服务(负责管理 AI 配置)
- type AIConfigService struct {
- aiConfigRepo *repository.AIConfigRepository
- userRepo *repository.UserRepository
- }
- // NewAIConfigService 创建 AI 配置服务实例。
- func NewAIConfigService(
- aiConfigRepo *repository.AIConfigRepository,
- userRepo *repository.UserRepository,
- ) *AIConfigService {
- return &AIConfigService{
- aiConfigRepo: aiConfigRepo,
- userRepo: userRepo,
- }
- }
- // CreateAIConfigInput 创建 AI 配置的输入参数。
- type CreateAIConfigInput struct {
- UserID uint
- Provider string
- APIURL string
- APIKey string // 明文 API Key(会被加密存储)
- Model string
- ModelType string
- IsActive bool
- IsPublic bool // 是否开放给访客使用
- Description string
- }
- // UpdateAIConfigInput 更新 AI 配置的输入参数。
- type UpdateAIConfigInput struct {
- ID uint
- Provider *string
- APIURL *string
- APIKey *string // 明文 API Key(如果提供,会被加密存储)
- Model *string
- ModelType *string
- IsActive *bool
- IsPublic *bool // 是否开放给访客使用
- Description *string
- }
- // AIConfigResult AI 配置返回结果(不包含加密的 API Key)。
- type AIConfigResult struct {
- ID uint `json:"id"`
- UserID uint `json:"user_id"`
- Provider string `json:"provider"`
- APIURL string `json:"api_url"`
- Model string `json:"model"`
- ModelType string `json:"model_type"`
- Protocol string `json:"protocol"`
- IsActive bool `json:"is_active"`
- IsPublic bool `json:"is_public"`
- Description string `json:"description"`
- CreatedAt string `json:"created_at"`
- UpdatedAt string `json:"updated_at"`
- }
- // CreateAIConfig 创建 AI 配置。
- func (s *AIConfigService) CreateAIConfig(input CreateAIConfigInput) (*AIConfigResult, error) {
- // 验证用户是否存在
- _, err := s.userRepo.GetByID(input.UserID)
- if err != nil {
- return nil, errors.New("用户不存在")
- }
- // 验证 API Key 不能为空
- if input.APIKey == "" {
- return nil, errors.New("API Key 不能为空")
- }
- // 加密 API Key
- encryptedKey, err := utils.EncryptAPIKey(input.APIKey)
- if err != nil {
- return nil, fmt.Errorf("加密 API Key 失败: %v", err)
- }
- // 设置默认值
- modelType := input.ModelType
- if modelType == "" {
- modelType = "text"
- }
- // 创建配置
- config := &models.AIConfig{
- UserID: input.UserID,
- Provider: input.Provider,
- APIURL: input.APIURL,
- APIKey: encryptedKey,
- Model: input.Model,
- ModelType: modelType,
- IsActive: input.IsActive,
- IsPublic: input.IsPublic,
- Description: input.Description,
- }
- if err := s.aiConfigRepo.Create(config); err != nil {
- return nil, err
- }
- return s.toResult(config), nil
- }
- // GetAIConfig 获取 AI 配置(不返回加密的 API Key)。
- func (s *AIConfigService) GetAIConfig(id uint) (*AIConfigResult, error) {
- config, err := s.aiConfigRepo.GetByID(id)
- if err != nil {
- return nil, err
- }
- return s.toResult(config), nil
- }
- // ListAIConfigs 获取指定用户的所有 AI 配置。
- func (s *AIConfigService) ListAIConfigs(userID uint) ([]AIConfigResult, error) {
- configs, err := s.aiConfigRepo.ListByUserID(userID)
- if err != nil {
- return nil, err
- }
- results := make([]AIConfigResult, 0, len(configs))
- for _, config := range configs {
- results = append(results, *s.toResult(&config))
- }
- return results, nil
- }
- // UpdateAIConfig 更新 AI 配置。
- func (s *AIConfigService) UpdateAIConfig(input UpdateAIConfigInput) (*AIConfigResult, error) {
- // 检查配置是否存在
- _, err := s.aiConfigRepo.GetByID(input.ID)
- if err != nil {
- return nil, errors.New("AI 配置不存在")
- }
- // 构建更新字段
- updates := make(map[string]interface{})
- if input.Provider != nil {
- updates["provider"] = *input.Provider
- }
- if input.APIURL != nil {
- updates["api_url"] = *input.APIURL
- }
- if input.APIKey != nil {
- // 验证 API Key 不能为空
- if *input.APIKey == "" {
- return nil, errors.New("API Key 不能为空")
- }
- // 如果提供了新的 API Key,需要加密
- encryptedKey, err := utils.EncryptAPIKey(*input.APIKey)
- if err != nil {
- return nil, fmt.Errorf("加密 API Key 失败: %v", err)
- }
- updates["api_key"] = encryptedKey
- }
- if input.Model != nil {
- updates["model"] = *input.Model
- }
- if input.ModelType != nil {
- updates["model_type"] = *input.ModelType
- }
- if input.IsActive != nil {
- updates["is_active"] = *input.IsActive
- }
- if input.IsPublic != nil {
- updates["is_public"] = *input.IsPublic
- }
- if input.Description != nil {
- updates["description"] = *input.Description
- }
- if err := s.aiConfigRepo.UpdateFields(input.ID, updates); err != nil {
- return nil, err
- }
- // 返回更新后的配置
- return s.GetAIConfig(input.ID)
- }
- // DeleteAIConfig 删除 AI 配置。
- func (s *AIConfigService) DeleteAIConfig(id uint) error {
- return s.aiConfigRepo.Delete(id)
- }
- // GetPublicModels 获取所有开放的模型配置(供访客选择)。
- func (s *AIConfigService) GetPublicModels(modelType string) ([]AIConfigResult, error) {
- configs, err := s.aiConfigRepo.ListPublic(modelType)
- if err != nil {
- return nil, err
- }
-
- results := make([]AIConfigResult, 0, len(configs))
- for _, config := range configs {
- results = append(results, *s.toResult(&config))
- }
-
- return results, nil
- }
- // toResult 将模型转换为返回结果(不包含加密的 API Key)。
- func (s *AIConfigService) toResult(config *models.AIConfig) *AIConfigResult {
- return &AIConfigResult{
- ID: config.ID,
- UserID: config.UserID,
- Provider: config.Provider,
- APIURL: config.APIURL,
- Model: config.Model,
- ModelType: config.ModelType,
- IsActive: config.IsActive,
- IsPublic: config.IsPublic,
- Description: config.Description,
- CreatedAt: config.CreatedAt.Format("2006-01-02 15:04:05"),
- UpdatedAt: config.UpdatedAt.Format("2006-01-02 15:04:05"),
- }
- }
|