ai_config_service.go 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228
  1. package service
  2. import (
  3. "errors"
  4. "fmt"
  5. "github.com/2930134478/AI-CS/backend/models"
  6. "github.com/2930134478/AI-CS/backend/repository"
  7. "github.com/2930134478/AI-CS/backend/utils"
  8. )
  9. // AIConfigService AI 配置服务(负责管理 AI 配置)
  10. type AIConfigService struct {
  11. aiConfigRepo *repository.AIConfigRepository
  12. userRepo *repository.UserRepository
  13. }
  14. // NewAIConfigService 创建 AI 配置服务实例。
  15. func NewAIConfigService(
  16. aiConfigRepo *repository.AIConfigRepository,
  17. userRepo *repository.UserRepository,
  18. ) *AIConfigService {
  19. return &AIConfigService{
  20. aiConfigRepo: aiConfigRepo,
  21. userRepo: userRepo,
  22. }
  23. }
  24. // CreateAIConfigInput 创建 AI 配置的输入参数。
  25. type CreateAIConfigInput struct {
  26. UserID uint
  27. Provider string
  28. APIURL string
  29. APIKey string // 明文 API Key(会被加密存储)
  30. Model string
  31. ModelType string
  32. IsActive bool
  33. IsPublic bool // 是否开放给访客使用
  34. Description string
  35. }
  36. // UpdateAIConfigInput 更新 AI 配置的输入参数。
  37. type UpdateAIConfigInput struct {
  38. ID uint
  39. Provider *string
  40. APIURL *string
  41. APIKey *string // 明文 API Key(如果提供,会被加密存储)
  42. Model *string
  43. ModelType *string
  44. IsActive *bool
  45. IsPublic *bool // 是否开放给访客使用
  46. Description *string
  47. }
  48. // AIConfigResult AI 配置返回结果(不包含加密的 API Key)。
  49. type AIConfigResult struct {
  50. ID uint `json:"id"`
  51. UserID uint `json:"user_id"`
  52. Provider string `json:"provider"`
  53. APIURL string `json:"api_url"`
  54. Model string `json:"model"`
  55. ModelType string `json:"model_type"`
  56. Protocol string `json:"protocol"`
  57. IsActive bool `json:"is_active"`
  58. IsPublic bool `json:"is_public"`
  59. Description string `json:"description"`
  60. CreatedAt string `json:"created_at"`
  61. UpdatedAt string `json:"updated_at"`
  62. }
  63. // CreateAIConfig 创建 AI 配置。
  64. func (s *AIConfigService) CreateAIConfig(input CreateAIConfigInput) (*AIConfigResult, error) {
  65. // 验证用户是否存在
  66. _, err := s.userRepo.GetByID(input.UserID)
  67. if err != nil {
  68. return nil, errors.New("用户不存在")
  69. }
  70. // 验证 API Key 不能为空
  71. if input.APIKey == "" {
  72. return nil, errors.New("API Key 不能为空")
  73. }
  74. // 加密 API Key
  75. encryptedKey, err := utils.EncryptAPIKey(input.APIKey)
  76. if err != nil {
  77. return nil, fmt.Errorf("加密 API Key 失败: %v", err)
  78. }
  79. // 设置默认值
  80. modelType := input.ModelType
  81. if modelType == "" {
  82. modelType = "text"
  83. }
  84. // 创建配置
  85. config := &models.AIConfig{
  86. UserID: input.UserID,
  87. Provider: input.Provider,
  88. APIURL: input.APIURL,
  89. APIKey: encryptedKey,
  90. Model: input.Model,
  91. ModelType: modelType,
  92. IsActive: input.IsActive,
  93. IsPublic: input.IsPublic,
  94. Description: input.Description,
  95. }
  96. if err := s.aiConfigRepo.Create(config); err != nil {
  97. return nil, err
  98. }
  99. return s.toResult(config), nil
  100. }
  101. // GetAIConfig 获取 AI 配置(不返回加密的 API Key)。
  102. func (s *AIConfigService) GetAIConfig(id uint) (*AIConfigResult, error) {
  103. config, err := s.aiConfigRepo.GetByID(id)
  104. if err != nil {
  105. return nil, err
  106. }
  107. return s.toResult(config), nil
  108. }
  109. // ListAIConfigs 获取指定用户的所有 AI 配置。
  110. func (s *AIConfigService) ListAIConfigs(userID uint) ([]AIConfigResult, error) {
  111. configs, err := s.aiConfigRepo.ListByUserID(userID)
  112. if err != nil {
  113. return nil, err
  114. }
  115. results := make([]AIConfigResult, 0, len(configs))
  116. for _, config := range configs {
  117. results = append(results, *s.toResult(&config))
  118. }
  119. return results, nil
  120. }
  121. // UpdateAIConfig 更新 AI 配置。
  122. func (s *AIConfigService) UpdateAIConfig(input UpdateAIConfigInput) (*AIConfigResult, error) {
  123. // 检查配置是否存在
  124. _, err := s.aiConfigRepo.GetByID(input.ID)
  125. if err != nil {
  126. return nil, errors.New("AI 配置不存在")
  127. }
  128. // 构建更新字段
  129. updates := make(map[string]interface{})
  130. if input.Provider != nil {
  131. updates["provider"] = *input.Provider
  132. }
  133. if input.APIURL != nil {
  134. updates["api_url"] = *input.APIURL
  135. }
  136. if input.APIKey != nil {
  137. // 验证 API Key 不能为空
  138. if *input.APIKey == "" {
  139. return nil, errors.New("API Key 不能为空")
  140. }
  141. // 如果提供了新的 API Key,需要加密
  142. encryptedKey, err := utils.EncryptAPIKey(*input.APIKey)
  143. if err != nil {
  144. return nil, fmt.Errorf("加密 API Key 失败: %v", err)
  145. }
  146. updates["api_key"] = encryptedKey
  147. }
  148. if input.Model != nil {
  149. updates["model"] = *input.Model
  150. }
  151. if input.ModelType != nil {
  152. updates["model_type"] = *input.ModelType
  153. }
  154. if input.IsActive != nil {
  155. updates["is_active"] = *input.IsActive
  156. }
  157. if input.IsPublic != nil {
  158. updates["is_public"] = *input.IsPublic
  159. }
  160. if input.Description != nil {
  161. updates["description"] = *input.Description
  162. }
  163. if err := s.aiConfigRepo.UpdateFields(input.ID, updates); err != nil {
  164. return nil, err
  165. }
  166. // 返回更新后的配置
  167. return s.GetAIConfig(input.ID)
  168. }
  169. // DeleteAIConfig 删除 AI 配置。
  170. func (s *AIConfigService) DeleteAIConfig(id uint) error {
  171. return s.aiConfigRepo.Delete(id)
  172. }
  173. // GetPublicModels 获取所有开放的模型配置(供访客选择)。
  174. func (s *AIConfigService) GetPublicModels(modelType string) ([]AIConfigResult, error) {
  175. configs, err := s.aiConfigRepo.ListPublic(modelType)
  176. if err != nil {
  177. return nil, err
  178. }
  179. results := make([]AIConfigResult, 0, len(configs))
  180. for _, config := range configs {
  181. results = append(results, *s.toResult(&config))
  182. }
  183. return results, nil
  184. }
  185. // toResult 将模型转换为返回结果(不包含加密的 API Key)。
  186. func (s *AIConfigService) toResult(config *models.AIConfig) *AIConfigResult {
  187. return &AIConfigResult{
  188. ID: config.ID,
  189. UserID: config.UserID,
  190. Provider: config.Provider,
  191. APIURL: config.APIURL,
  192. Model: config.Model,
  193. ModelType: config.ModelType,
  194. IsActive: config.IsActive,
  195. IsPublic: config.IsPublic,
  196. Description: config.Description,
  197. CreatedAt: config.CreatedAt.Format("2006-01-02 15:04:05"),
  198. UpdatedAt: config.UpdatedAt.Format("2006-01-02 15:04:05"),
  199. }
  200. }