refactor: 认证系统重构 + DevTools CLI 重写 + 文档全面更新
- auth: Login 简化为管理员始终通过 .env 验证,GetProfile 修正 admin DB 查询 - devtools: .sh/.bat 同步重写为完整 CLI (start/stop/status/logs/build/db:*) - docs: 新增 devtools.md,重写 Deploy.md (三种方式+Windows说明),更新 README/gateway-api - voice-service: DashScope 实时流式 STT 支持 - gateway: Phase 6 多模型配置 + 多端客户端管理 + WebSocket 增强 Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,110 @@
|
||||
package config
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"os"
|
||||
"path/filepath"
|
||||
)
|
||||
|
||||
// ModelsJSON 映射 models.json 文件结构(仅提取语音相关字段)。
|
||||
type ModelsJSON struct {
|
||||
Providers map[string]ModelsProvider `json:"providers"`
|
||||
Models map[string]ModelsModel `json:"models"`
|
||||
Routing map[string]ModelsRouting `json:"routing"`
|
||||
}
|
||||
|
||||
type ModelsProvider struct {
|
||||
Name string `json:"name"`
|
||||
BaseURL string `json:"base_url"`
|
||||
APIKey string `json:"api_key"`
|
||||
}
|
||||
|
||||
type ModelsModel struct {
|
||||
ID string `json:"id"`
|
||||
Name string `json:"name"`
|
||||
Provider string `json:"provider"`
|
||||
}
|
||||
|
||||
type ModelsRouting struct {
|
||||
Purpose string `json:"purpose"`
|
||||
FallbackChain []string `json:"fallback_chain"`
|
||||
}
|
||||
|
||||
// LoadModelsConfig 从 backend/models.json 加载模型配置。
|
||||
// 返回 provider API key 和 ASR 模型名称。如果文件不存在则返回零值。
|
||||
func LoadModelsConfig() (apiKey string, offlineModel string, realtimeModel string) {
|
||||
// 尝试多个可能的路径
|
||||
candidates := []string{
|
||||
"models.json",
|
||||
"../models.json",
|
||||
"../../models.json",
|
||||
filepath.Join("..", "models.json"),
|
||||
}
|
||||
|
||||
var data []byte
|
||||
var err error
|
||||
for _, p := range candidates {
|
||||
data, err = os.ReadFile(p)
|
||||
if err == nil {
|
||||
break
|
||||
}
|
||||
}
|
||||
if data == nil {
|
||||
return
|
||||
}
|
||||
|
||||
var cfg ModelsJSON
|
||||
if err := json.Unmarshal(data, &cfg); err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
// 从 speech_recognition_offline 路由取离线模型
|
||||
if r, ok := cfg.Routing["speech_recognition_offline"]; ok && len(r.FallbackChain) > 0 {
|
||||
modelID := r.FallbackChain[0]
|
||||
if m, ok := cfg.Models[modelID]; ok {
|
||||
offlineModel = m.Name
|
||||
if m.Name == "" {
|
||||
offlineModel = m.ID
|
||||
}
|
||||
// 从 provider 取 API key
|
||||
if p, ok := cfg.Providers[m.Provider]; ok && apiKey == "" {
|
||||
apiKey = p.APIKey
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 从 speech_recognition 路由取实时模型
|
||||
if r, ok := cfg.Routing["speech_recognition"]; ok && len(r.FallbackChain) > 0 {
|
||||
modelID := r.FallbackChain[0]
|
||||
if m, ok := cfg.Models[modelID]; ok {
|
||||
realtimeModel = m.Name
|
||||
if realtimeModel == "" {
|
||||
realtimeModel = m.ID
|
||||
}
|
||||
// 从 provider 取 API key
|
||||
if p, ok := cfg.Providers[m.Provider]; ok && apiKey == "" {
|
||||
apiKey = p.APIKey
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 如果 routing 里没有,尝试从所有 models 中找带有 ASR tag 的模型
|
||||
if offlineModel == "" {
|
||||
for _, m := range cfg.Models {
|
||||
if m.Provider == "dashscope" && m.Name != "" {
|
||||
if offlineModel == "" {
|
||||
offlineModel = m.Name
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 从 provider 取 API key (兜底)
|
||||
if apiKey == "" {
|
||||
if p, ok := cfg.Providers["dashscope"]; ok {
|
||||
apiKey = p.APIKey
|
||||
}
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
Reference in New Issue
Block a user