'use client' import { useState, useEffect } from 'react' import { Button } from '@/components/ui/button' import { Input } from '@/components/ui/input' import { Label } from '@/components/ui/label' import { Textarea } from '@/components/ui/textarea' import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card' import { Checkbox } from '@/components/ui/checkbox' import { Trash2, Plus } from 'lucide-react' import { authenticatedFetch } from '@/lib/auth' interface DataSourceConfigFormProps { type: 'lankong' | 'manual' | 'api_get' | 'api_post' | 'endpoint' config: string onChange: (config: string) => void } interface LankongConfig { api_token: string album_ids: string[] base_url?: string } interface APIConfig { url: string method?: string headers: { [key: string]: string } body?: string url_field: string } interface SavedToken { id: string name: string token: string } interface EndpointConfig { endpoint_ids: number[] } export default function DataSourceConfigForm({ type, config, onChange }: DataSourceConfigFormProps) { const [lankongConfig, setLankongConfig] = useState({ api_token: '', album_ids: [''], base_url: '' }) const [apiConfig, setAPIConfig] = useState({ url: '', method: type === 'api_post' ? 'POST' : 'GET', headers: {}, body: '', url_field: 'url' }) const [endpointConfig, setEndpointConfig] = useState({ endpoint_ids: [] }) const [availableEndpoints, setAvailableEndpoints] = useState>([]) const [headerPairs, setHeaderPairs] = useState>([{key: '', value: ''}]) const [savedTokens, setSavedTokens] = useState([]) const [newTokenName, setNewTokenName] = useState('') // 从localStorage加载保存的token useEffect(() => { const saved = localStorage.getItem('lankong_tokens') if (saved) { try { setSavedTokens(JSON.parse(saved)) } catch (error) { console.error('Failed to parse saved tokens:', error) } } }, []) // 获取可用端点列表 useEffect(() => { if (type === 'endpoint') { loadAvailableEndpoints() } }, [type]) const loadAvailableEndpoints = async () => { try { const response = await authenticatedFetch('/api/admin/endpoints') if (response.ok) { const data = await response.json() setAvailableEndpoints(data.data || []) } } catch (error) { console.error('Failed to load endpoints:', error) } } // 解析现有配置 useEffect(() => { if (!config) return try { const parsed = JSON.parse(config) if (type === 'lankong') { setLankongConfig({ api_token: parsed.api_token || '', album_ids: parsed.album_ids || [''], base_url: parsed.base_url || '' }) } else if (type === 'api_get' || type === 'api_post') { setAPIConfig({ url: parsed.url || '', method: parsed.method || (type === 'api_post' ? 'POST' : 'GET'), headers: parsed.headers || {}, body: parsed.body || '', url_field: parsed.url_field || 'url' }) // 转换headers为键值对数组 const pairs = Object.entries(parsed.headers || {}).map(([key, value]) => ({key, value: value as string})) if (pairs.length === 0) pairs.push({key: '', value: ''}) setHeaderPairs(pairs) } else if (type === 'endpoint') { setEndpointConfig({ endpoint_ids: parsed.endpoint_ids || [] }) } } catch (error) { console.error('Failed to parse config:', error) } }, [config, type]) // 保存token到localStorage const saveToken = () => { if (!newTokenName.trim() || !lankongConfig.api_token.trim()) { alert('请输入token名称和token值') return } const newToken: SavedToken = { id: Date.now().toString(), name: newTokenName.trim(), token: lankongConfig.api_token } const updated = [...savedTokens, newToken] setSavedTokens(updated) localStorage.setItem('lankong_tokens', JSON.stringify(updated)) setNewTokenName('') alert('Token保存成功') } // 删除保存的token const deleteToken = (tokenId: string) => { if (!confirm('确定要删除这个token吗?')) return const updated = savedTokens.filter(t => t.id !== tokenId) setSavedTokens(updated) localStorage.setItem('lankong_tokens', JSON.stringify(updated)) } // 更新兰空图床配置 const updateConfig = (newConfig: LankongConfig | APIConfig) => { onChange(JSON.stringify(newConfig)) } // 添加相册ID const addAlbumId = () => { const newConfig = { ...lankongConfig, album_ids: [...lankongConfig.album_ids, ''] } setLankongConfig(newConfig) updateConfig(newConfig) } // 删除相册ID const removeAlbumId = (index: number) => { const newConfig = { ...lankongConfig, album_ids: lankongConfig.album_ids.filter((_, i) => i !== index) } setLankongConfig(newConfig) updateConfig(newConfig) } // 更新相册ID const updateAlbumId = (index: number, value: string) => { const newConfig = { ...lankongConfig, album_ids: lankongConfig.album_ids.map((id, i) => i === index ? value : id) } setLankongConfig(newConfig) updateConfig(newConfig) } // 添加请求头 const addHeader = () => { setHeaderPairs([...headerPairs, {key: '', value: ''}]) } // 删除请求头 const removeHeader = (index: number) => { const newPairs = headerPairs.filter((_, i) => i !== index) setHeaderPairs(newPairs) updateAPIHeaders(newPairs) } // 更新请求头 const updateHeader = (index: number, field: 'key' | 'value', value: string) => { const newPairs = headerPairs.map((pair, i) => i === index ? { ...pair, [field]: value } : pair ) setHeaderPairs(newPairs) updateAPIHeaders(newPairs) } // 更新API配置的headers const updateAPIHeaders = (pairs: Array<{key: string, value: string}>) => { const headers: { [key: string]: string } = {} pairs.forEach(pair => { if (pair.key.trim() && pair.value.trim()) { headers[pair.key.trim()] = pair.value.trim() } }) const newConfig = { ...apiConfig, headers } setAPIConfig(newConfig) updateConfig(newConfig) } // 更新API配置 const updateAPIConfig = (field: keyof APIConfig, value: string) => { // 对URL字段进行trim处理,去除前后空格 const trimmedValue = field === 'url' ? value.trim() : value const newConfig = { ...apiConfig, [field]: trimmedValue } setAPIConfig(newConfig) updateConfig(newConfig) } // 更新端点配置 const updateEndpointConfig = (endpointIds: number[]) => { const newConfig = { endpoint_ids: endpointIds } setEndpointConfig(newConfig) onChange(JSON.stringify(newConfig)) } // 切换端点选择 const toggleEndpoint = (endpointId: number) => { const currentIds = endpointConfig.endpoint_ids const newIds = currentIds.includes(endpointId) ? currentIds.filter(id => id !== endpointId) : [...currentIds, endpointId] updateEndpointConfig(newIds) } if (type === 'manual') { return (