101 lines
2.5 KiB
Go
101 lines
2.5 KiB
Go
package admin
|
|
|
|
import (
|
|
"context"
|
|
"time"
|
|
|
|
"github.com/qianfree/team-api/api/admin/v1"
|
|
"github.com/qianfree/team-api/internal/dao"
|
|
"github.com/qianfree/team-api/internal/logic/common"
|
|
"github.com/qianfree/team-api/internal/logic/relay"
|
|
)
|
|
|
|
// TestChannel 测试渠道可用性(发送最小请求验证)
|
|
func (s *sAdmin) TestChannel(ctx context.Context, req *v1.ChannelTestReq) (*v1.ChannelTestRes, error) {
|
|
channelID := req.ID
|
|
|
|
// 获取渠道信息
|
|
type channelRow struct {
|
|
ID int64 `json:"id"`
|
|
Name string `json:"name"`
|
|
Type int `json:"type"`
|
|
BaseURL string `json:"base_url"`
|
|
TestModel string `json:"test_model"`
|
|
Status string `json:"status"`
|
|
}
|
|
|
|
var ch *channelRow
|
|
err := dao.ChnChannels.Ctx(ctx).
|
|
Where("id", channelID).
|
|
Fields("id, name, type, base_url, test_model, status").
|
|
Scan(&ch)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
if ch == nil {
|
|
return nil, common.NewNotFoundError("渠道")
|
|
}
|
|
if ch.Status == "disabled" {
|
|
return nil, common.NewBadRequestError("渠道已禁用")
|
|
}
|
|
|
|
testModel := req.ModelName
|
|
if testModel == "" {
|
|
testModel = ch.TestModel
|
|
}
|
|
if testModel == "" {
|
|
return nil, common.NewBadRequestError("请指定测试模型名")
|
|
}
|
|
|
|
// 获取渠道的 API Key
|
|
type keyRow struct {
|
|
EncryptedKey string `json:"encrypted_key"`
|
|
}
|
|
var keyInfo *keyRow
|
|
err = dao.ChnChannelKeys.Ctx(ctx).
|
|
Where("channel_id", channelID).
|
|
Where("status", "active").
|
|
Fields("encrypted_key").
|
|
OrderAsc("last_used_at").
|
|
Limit(1).
|
|
Scan(&keyInfo)
|
|
if err != nil || keyInfo == nil || keyInfo.EncryptedKey == "" {
|
|
return nil, common.NewNotFoundError("渠道没有可用的 API Key")
|
|
}
|
|
|
|
encKey := relay.GetEncryptionKey()
|
|
apiKey, err := relay.DecryptChannelKey(encKey, keyInfo.EncryptedKey)
|
|
if err != nil {
|
|
return nil, common.NewBadRequestError("解密 API Key 失败")
|
|
}
|
|
|
|
// 发送最小测试请求
|
|
startTime := time.Now()
|
|
result := sendTestRequest(ctx, ch.Type, ch.BaseURL, apiKey, testModel)
|
|
latencyMs := time.Since(startTime).Milliseconds()
|
|
|
|
// 更新健康度
|
|
if result.Success {
|
|
relay.UpdateHealthScoreDirect(ctx, channelID, true, float64(latencyMs))
|
|
} else {
|
|
relay.UpdateHealthScoreDirect(ctx, channelID, false, float64(latencyMs))
|
|
}
|
|
|
|
return &v1.ChannelTestRes{
|
|
Success: result.Success,
|
|
Latency: latencyMs,
|
|
ModelName: testModel,
|
|
Error: result.Error,
|
|
Request: result.Request,
|
|
Response: result.Response,
|
|
}, nil
|
|
}
|
|
|
|
// testResult 测试结果
|
|
type testResult struct {
|
|
Success bool
|
|
Error string
|
|
Response string
|
|
Request *v1.ChannelTestReqDetail
|
|
}
|