mirror of
https://github.com/fawney19/Aether.git
synced 2026-09-02 01:10:23 +08:00
feat: 手动代理节点支持、系统默认代理与跨格式流式 usage 提取
代理节点: - 支持手动添加代理节点(HTTP/HTTPS/SOCKS5),含地址、认证信息和区域标签 - 新增手动节点的 CRUD API 和前端管理界面 - 提供商代理配置从 URL 字符串迁移至代理节点选择器(proxy_node_id) - 新增系统默认代理节点设置,未单独配置代理的提供商自动回退使用 - 删除节点时自动清除系统默认代理引用并失效缓存 - 健康检查跳过手动节点(无心跳,始终在线) 流式处理: - CLI handler 跨格式转换时委托基类解析 Provider 原始事件的 usage - StreamProcessor 新增 _extract_usage_from_converted_event 从转换后事件补充提取 usage - 支持 Claude/OpenAI/OpenAI Responses/Gemini 多种 usage 格式
This commit is contained in:
@@ -1,12 +1,19 @@
|
||||
import { defineStore } from 'pinia'
|
||||
import { ref } from 'vue'
|
||||
import { proxyNodesApi, type ProxyNode } from '@/api/proxy-nodes'
|
||||
import { ref, computed } from 'vue'
|
||||
import { proxyNodesApi, type ProxyNode, type ManualProxyNodeCreateRequest } from '@/api/proxy-nodes'
|
||||
|
||||
export const useProxyNodesStore = defineStore('proxy-nodes', () => {
|
||||
const nodes = ref<ProxyNode[]>([])
|
||||
const total = ref(0)
|
||||
const loading = ref(false)
|
||||
const error = ref<string | null>(null)
|
||||
/** 标记是否已加载过(避免重复请求) */
|
||||
const fetched = ref(false)
|
||||
|
||||
/** 在线节点(可用于代理选择) */
|
||||
const onlineNodes = computed(() =>
|
||||
nodes.value.filter(n => n.status === 'online')
|
||||
)
|
||||
|
||||
async function fetchNodes(params?: { status?: string }) {
|
||||
loading.value = true
|
||||
@@ -16,6 +23,7 @@ export const useProxyNodesStore = defineStore('proxy-nodes', () => {
|
||||
const data = await proxyNodesApi.listProxyNodes({ ...params, limit: 1000 })
|
||||
nodes.value = data.items
|
||||
total.value = data.total
|
||||
fetched.value = true
|
||||
} catch (err: any) {
|
||||
error.value = err.response?.data?.error?.message || err.response?.data?.detail || '获取代理节点列表失败'
|
||||
} finally {
|
||||
@@ -23,6 +31,30 @@ export const useProxyNodesStore = defineStore('proxy-nodes', () => {
|
||||
}
|
||||
}
|
||||
|
||||
/** 确保节点列表已加载(懒加载,不重复请求) */
|
||||
async function ensureLoaded() {
|
||||
if (!fetched.value && !loading.value) {
|
||||
await fetchNodes()
|
||||
}
|
||||
}
|
||||
|
||||
async function createManualNode(data: ManualProxyNodeCreateRequest) {
|
||||
loading.value = true
|
||||
error.value = null
|
||||
|
||||
try {
|
||||
const result = await proxyNodesApi.createManualNode(data)
|
||||
// 重新获取列表以保持排序一致
|
||||
await fetchNodes()
|
||||
return result
|
||||
} catch (err: any) {
|
||||
error.value = err.response?.data?.error?.message || err.response?.data?.detail || '创建手动代理节点失败'
|
||||
throw err
|
||||
} finally {
|
||||
loading.value = false
|
||||
}
|
||||
}
|
||||
|
||||
async function deleteNode(nodeId: string) {
|
||||
loading.value = true
|
||||
error.value = null
|
||||
@@ -44,7 +76,11 @@ export const useProxyNodesStore = defineStore('proxy-nodes', () => {
|
||||
total,
|
||||
loading,
|
||||
error,
|
||||
fetched,
|
||||
onlineNodes,
|
||||
fetchNodes,
|
||||
ensureLoaded,
|
||||
createManualNode,
|
||||
deleteNode,
|
||||
}
|
||||
})
|
||||
|
||||
Reference in New Issue
Block a user