Update Context for store
This commit is contained in:
@@ -2,6 +2,7 @@
|
||||
package handlers
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"gemini-balancer/internal/errors"
|
||||
@@ -31,7 +32,6 @@ func NewKeyGroupHandler(gm *service.GroupManager, s store.Store, qs *service.Das
|
||||
}
|
||||
}
|
||||
|
||||
// DTOs & 辅助函数
|
||||
func isValidGroupName(name string) bool {
|
||||
if name == "" {
|
||||
return false
|
||||
@@ -40,7 +40,6 @@ func isValidGroupName(name string) bool {
|
||||
return match
|
||||
}
|
||||
|
||||
// KeyGroupOperationalSettings defines the shared operational settings for a key group.
|
||||
type KeyGroupOperationalSettings struct {
|
||||
EnableKeyCheck *bool `json:"enable_key_check"`
|
||||
KeyCheckIntervalMinutes *int `json:"key_check_interval_minutes"`
|
||||
@@ -52,7 +51,6 @@ type KeyGroupOperationalSettings struct {
|
||||
MaxRetries *int `json:"max_retries"`
|
||||
EnableSmartGateway *bool `json:"enable_smart_gateway"`
|
||||
}
|
||||
|
||||
type CreateKeyGroupRequest struct {
|
||||
Name string `json:"name" binding:"required"`
|
||||
DisplayName string `json:"display_name"`
|
||||
@@ -60,11 +58,8 @@ type CreateKeyGroupRequest struct {
|
||||
PollingStrategy string `json:"polling_strategy" binding:"omitempty,oneof=sequential random weighted"`
|
||||
EnableProxy bool `json:"enable_proxy"`
|
||||
ChannelType string `json:"channel_type"`
|
||||
|
||||
// Embed shared operational settings
|
||||
KeyGroupOperationalSettings
|
||||
}
|
||||
|
||||
type UpdateKeyGroupRequest struct {
|
||||
Name *string `json:"name"`
|
||||
DisplayName *string `json:"display_name"`
|
||||
@@ -72,15 +67,10 @@ type UpdateKeyGroupRequest struct {
|
||||
PollingStrategy *string `json:"polling_strategy" binding:"omitempty,oneof=sequential random weighted"`
|
||||
EnableProxy *bool `json:"enable_proxy"`
|
||||
ChannelType *string `json:"channel_type"`
|
||||
|
||||
// Embed shared operational settings
|
||||
KeyGroupOperationalSettings
|
||||
|
||||
// M:N associations
|
||||
AllowedUpstreams []string `json:"allowed_upstreams"`
|
||||
AllowedModels []string `json:"allowed_models"`
|
||||
}
|
||||
|
||||
type KeyGroupResponse struct {
|
||||
ID uint `json:"id"`
|
||||
Name string `json:"name"`
|
||||
@@ -96,36 +86,30 @@ type KeyGroupResponse struct {
|
||||
AllowedModels []string `json:"allowed_models"`
|
||||
AllowedUpstreams []string `json:"allowed_upstreams"`
|
||||
}
|
||||
|
||||
// [NEW] Define the detailed response structure for a single group.
|
||||
type KeyGroupDetailsResponse struct {
|
||||
KeyGroupResponse
|
||||
Settings *models.GroupSettings `json:"settings,omitempty"`
|
||||
RequestConfig *models.RequestConfig `json:"request_config,omitempty"`
|
||||
}
|
||||
|
||||
// transformModelsToStrings converts a slice of GroupModelMapping pointers to a slice of model names.
|
||||
func transformModelsToStrings(mappings []*models.GroupModelMapping) []string {
|
||||
modelNames := make([]string, 0, len(mappings))
|
||||
for _, mapping := range mappings {
|
||||
if mapping != nil { // Safety check
|
||||
if mapping != nil {
|
||||
modelNames = append(modelNames, mapping.ModelName)
|
||||
}
|
||||
}
|
||||
return modelNames
|
||||
}
|
||||
|
||||
// transformUpstreamsToStrings converts a slice of UpstreamEndpoint pointers to a slice of URLs.
|
||||
func transformUpstreamsToStrings(upstreams []*models.UpstreamEndpoint) []string {
|
||||
urls := make([]string, 0, len(upstreams))
|
||||
for _, upstream := range upstreams {
|
||||
if upstream != nil { // Safety check
|
||||
if upstream != nil {
|
||||
urls = append(urls, upstream.URL)
|
||||
}
|
||||
}
|
||||
return urls
|
||||
}
|
||||
|
||||
func (h *KeyGroupHandler) newKeyGroupResponse(group *models.KeyGroup, keyCount int64) KeyGroupResponse {
|
||||
return KeyGroupResponse{
|
||||
ID: group.ID,
|
||||
@@ -139,13 +123,10 @@ func (h *KeyGroupHandler) newKeyGroupResponse(group *models.KeyGroup, keyCount i
|
||||
CreatedAt: group.CreatedAt,
|
||||
UpdatedAt: group.UpdatedAt,
|
||||
Order: group.Order,
|
||||
AllowedModels: transformModelsToStrings(group.AllowedModels), // Call the new helper
|
||||
AllowedUpstreams: transformUpstreamsToStrings(group.AllowedUpstreams), // Call the new helper
|
||||
AllowedModels: transformModelsToStrings(group.AllowedModels),
|
||||
AllowedUpstreams: transformUpstreamsToStrings(group.AllowedUpstreams),
|
||||
}
|
||||
}
|
||||
|
||||
// packGroupSettings is a helper to convert request-level operational settings
|
||||
// into the model-level settings struct.
|
||||
func packGroupSettings(settings KeyGroupOperationalSettings) *models.KeyGroupSettings {
|
||||
return &models.KeyGroupSettings{
|
||||
EnableKeyCheck: settings.EnableKeyCheck,
|
||||
@@ -159,7 +140,6 @@ func packGroupSettings(settings KeyGroupOperationalSettings) *models.KeyGroupSet
|
||||
EnableSmartGateway: settings.EnableSmartGateway,
|
||||
}
|
||||
}
|
||||
|
||||
func (h *KeyGroupHandler) getGroupFromContext(c *gin.Context) (*models.KeyGroup, *errors.APIError) {
|
||||
id, err := strconv.Atoi(c.Param("id"))
|
||||
if err != nil {
|
||||
@@ -171,7 +151,6 @@ func (h *KeyGroupHandler) getGroupFromContext(c *gin.Context) (*models.KeyGroup,
|
||||
}
|
||||
return group, nil
|
||||
}
|
||||
|
||||
func applyUpdateRequestToGroup(req *UpdateKeyGroupRequest, group *models.KeyGroup) {
|
||||
if req.Name != nil {
|
||||
group.Name = *req.Name
|
||||
@@ -197,9 +176,10 @@ func applyUpdateRequestToGroup(req *UpdateKeyGroupRequest, group *models.KeyGrou
|
||||
// publishGroupChangeEvent encapsulates the logic for marshaling and publishing a group change event.
|
||||
func (h *KeyGroupHandler) publishGroupChangeEvent(groupID uint, reason string) {
|
||||
go func() {
|
||||
ctx := context.Background()
|
||||
event := models.KeyStatusChangedEvent{GroupID: groupID, ChangeReason: reason}
|
||||
eventData, _ := json.Marshal(event)
|
||||
h.store.Publish(models.TopicKeyStatusChanged, eventData)
|
||||
_ = h.store.Publish(ctx, models.TopicKeyStatusChanged, eventData)
|
||||
}()
|
||||
}
|
||||
|
||||
@@ -216,7 +196,6 @@ func (h *KeyGroupHandler) CreateKeyGroup(c *gin.Context) {
|
||||
return
|
||||
}
|
||||
|
||||
// The core logic remains, as it's specific to creation.
|
||||
p := bluemonday.StripTagsPolicy()
|
||||
sanitizedDisplayName := p.Sanitize(req.DisplayName)
|
||||
sanitizedDescription := p.Sanitize(req.Description)
|
||||
@@ -244,11 +223,9 @@ func (h *KeyGroupHandler) CreateKeyGroup(c *gin.Context) {
|
||||
response.Created(c, h.newKeyGroupResponse(keyGroup, 0))
|
||||
}
|
||||
|
||||
// 统一的处理器可以处理两种情况:
|
||||
// 1. GET /keygroups - 返回所有组的列表
|
||||
// 2. GET /keygroups/:id - 返回指定ID的单个组
|
||||
func (h *KeyGroupHandler) GetKeyGroups(c *gin.Context) {
|
||||
// Case 1: Get a single group
|
||||
if idStr := c.Param("id"); idStr != "" {
|
||||
group, apiErr := h.getGroupFromContext(c)
|
||||
if apiErr != nil {
|
||||
@@ -265,7 +242,6 @@ func (h *KeyGroupHandler) GetKeyGroups(c *gin.Context) {
|
||||
response.Success(c, detailedResponse)
|
||||
return
|
||||
}
|
||||
// Case 2: Get all groups
|
||||
allGroups := h.groupManager.GetAllGroups()
|
||||
responses := make([]KeyGroupResponse, 0, len(allGroups))
|
||||
for _, group := range allGroups {
|
||||
@@ -275,7 +251,6 @@ func (h *KeyGroupHandler) GetKeyGroups(c *gin.Context) {
|
||||
response.Success(c, responses)
|
||||
}
|
||||
|
||||
// UpdateKeyGroup
|
||||
func (h *KeyGroupHandler) UpdateKeyGroup(c *gin.Context) {
|
||||
group, apiErr := h.getGroupFromContext(c)
|
||||
if apiErr != nil {
|
||||
@@ -304,7 +279,6 @@ func (h *KeyGroupHandler) UpdateKeyGroup(c *gin.Context) {
|
||||
response.Success(c, h.newKeyGroupResponse(freshGroup, keyCount))
|
||||
}
|
||||
|
||||
// DeleteKeyGroup
|
||||
func (h *KeyGroupHandler) DeleteKeyGroup(c *gin.Context) {
|
||||
group, apiErr := h.getGroupFromContext(c)
|
||||
if apiErr != nil {
|
||||
@@ -320,14 +294,14 @@ func (h *KeyGroupHandler) DeleteKeyGroup(c *gin.Context) {
|
||||
response.Success(c, gin.H{"message": fmt.Sprintf("Group '%s' and its associated keys deleted successfully", groupName)})
|
||||
}
|
||||
|
||||
// GetKeyGroupStats
|
||||
func (h *KeyGroupHandler) GetKeyGroupStats(c *gin.Context) {
|
||||
group, apiErr := h.getGroupFromContext(c)
|
||||
if apiErr != nil {
|
||||
response.Error(c, apiErr)
|
||||
return
|
||||
}
|
||||
stats, err := h.queryService.GetGroupStats(group.ID)
|
||||
|
||||
stats, err := h.queryService.GetGroupStats(c.Request.Context(), group.ID)
|
||||
if err != nil {
|
||||
response.Error(c, errors.NewAPIError(errors.ErrDatabase, err.Error()))
|
||||
return
|
||||
@@ -350,7 +324,6 @@ func (h *KeyGroupHandler) CloneKeyGroup(c *gin.Context) {
|
||||
response.Created(c, h.newKeyGroupResponse(clonedGroup, keyCount))
|
||||
}
|
||||
|
||||
// 更新分组排序
|
||||
func (h *KeyGroupHandler) UpdateKeyGroupOrder(c *gin.Context) {
|
||||
var payload []service.UpdateOrderPayload
|
||||
if err := c.ShouldBindJSON(&payload); err != nil {
|
||||
|
||||
Reference in New Issue
Block a user