diff --git a/src/server/routes/api/tokens.ts b/src/server/routes/api/tokens.ts index 9a45549..5ab1ac0 100644 --- a/src/server/routes/api/tokens.ts +++ b/src/server/routes/api/tokens.ts @@ -539,7 +539,7 @@ export async function tokensRoutes(app: FastifyInstance) { await db.insert(schema.routeChannels).values({ routeId, accountId: item.accountId, - tokenId: item.tokenId, + tokenId: effectiveTokenId, sourceModel: sourceModel || null, priority: 0, weight: 10, diff --git a/src/web/index.css b/src/web/index.css index 4db797a..7a49ec7 100644 --- a/src/web/index.css +++ b/src/web/index.css @@ -4101,19 +4101,19 @@ textarea { display: flex; flex-direction: column; gap: 8px; - animation: filterBarSlideDown 0.22s cubic-bezier(0.22, 1, 0.36, 1); + animation: filter-bar-slide-down 0.22s cubic-bezier(0.22, 1, 0.36, 1); } .route-filter-bar-expanded.is-closing { - animation: filterBarSlideUp 0.18s ease forwards; + animation: filter-bar-slide-up 0.18s ease forwards; } -@keyframes filterBarSlideDown { +@keyframes filter-bar-slide-down { from { opacity: 0; max-height: 0; transform: translateY(-4px); } to { opacity: 1; max-height: 600px; transform: translateY(0); } } -@keyframes filterBarSlideUp { +@keyframes filter-bar-slide-up { from { opacity: 1; max-height: 600px; } to { opacity: 0; max-height: 0; overflow: hidden; } } diff --git a/src/web/pages/token-routes/ManualRoutePanel.tsx b/src/web/pages/token-routes/ManualRoutePanel.tsx index ed9ca66..c8355e1 100644 --- a/src/web/pages/token-routes/ManualRoutePanel.tsx +++ b/src/web/pages/token-routes/ManualRoutePanel.tsx @@ -174,7 +174,7 @@ export default function ManualRoutePanel({ className="spinner spinner-sm" style={{ borderTopColor: 'white', borderColor: 'rgba(255,255,255,0.3)' }} />{' '} - 保存中... + {tr('保存中...')} ) : ( tr(editingRouteId ? '保存群组' : '创建群组') diff --git a/src/web/pages/token-routes/useRouteChannels.ts b/src/web/pages/token-routes/useRouteChannels.ts index b1c96d4..b708fb2 100644 --- a/src/web/pages/token-routes/useRouteChannels.ts +++ b/src/web/pages/token-routes/useRouteChannels.ts @@ -1,4 +1,4 @@ -import { useState, useCallback } from 'react'; +import { useState, useCallback, useRef } from 'react'; import { api } from '../../api.js'; import { normalizeChannels } from './utils.js'; import type { RouteChannel } from './types.js'; @@ -6,19 +6,24 @@ import type { RouteChannel } from './types.js'; export function useRouteChannels() { const [channelsByRouteId, setChannelsByRouteId] = useState>({}); const [loadingChannelsByRouteId, setLoadingChannelsByRouteId] = useState>({}); + const channelsByRouteIdRef = useRef(channelsByRouteId); + channelsByRouteIdRef.current = channelsByRouteId; const loadChannels = useCallback(async (routeId: number, force = false) => { - if (!force && channelsByRouteId[routeId]) return channelsByRouteId[routeId]; + if (!force && channelsByRouteIdRef.current[routeId]) return channelsByRouteIdRef.current[routeId]; setLoadingChannelsByRouteId((prev) => ({ ...prev, [routeId]: true })); try { const channels = await api.getRouteChannels(routeId); const sorted = normalizeChannels(channels || []); setChannelsByRouteId((prev) => ({ ...prev, [routeId]: sorted })); return sorted; + } catch (error) { + console.error(`Failed to load channels for route ${routeId}:`, error); + throw error; } finally { setLoadingChannelsByRouteId((prev) => ({ ...prev, [routeId]: false })); } - }, [channelsByRouteId]); + }, []); const invalidateChannels = useCallback((routeId: number) => { setChannelsByRouteId((prev) => {