diff --git a/src/app/admin/page.tsx b/src/app/admin/page.tsx index 4994392..4cca393 100644 --- a/src/app/admin/page.tsx +++ b/src/app/admin/page.tsx @@ -3445,6 +3445,7 @@ const EmbyConfigComponent = ({ const [sources, setSources] = useState([]); const [editingSource, setEditingSource] = useState(null); const [showAddForm, setShowAddForm] = useState(false); + const [selectedSources, setSelectedSources] = useState>(new Set()); // 表单状态 const [formData, setFormData] = useState({ @@ -3694,6 +3695,81 @@ const EmbyConfigComponent = ({ }); }; + // 批量启用 + const handleBatchEnable = async () => { + if (selectedSources.size === 0) return; + await withLoading('batchEnableEmby', async () => { + try { + const newSources = sources.map(s => + selectedSources.has(s.key) ? { ...s, enabled: true } : s + ); + const response = await fetch('/api/admin/config', { + method: 'POST', + headers: { 'Content-Type': 'application/json' }, + body: JSON.stringify({ ...config, EmbyConfig: { Sources: newSources } }), + }); + if (!response.ok) throw new Error('批量启用失败'); + await refreshConfig(); + setSelectedSources(new Set()); + showSuccess(`已启用 ${selectedSources.size} 个源`, showAlert); + } catch (error) { + showError(error instanceof Error ? error.message : '批量启用失败', showAlert); + } + }); + }; + + // 批量禁用 + const handleBatchDisable = async () => { + if (selectedSources.size === 0) return; + await withLoading('batchDisableEmby', async () => { + try { + const newSources = sources.map(s => + selectedSources.has(s.key) ? { ...s, enabled: false } : s + ); + const response = await fetch('/api/admin/config', { + method: 'POST', + headers: { 'Content-Type': 'application/json' }, + body: JSON.stringify({ ...config, EmbyConfig: { Sources: newSources } }), + }); + if (!response.ok) throw new Error('批量禁用失败'); + await refreshConfig(); + setSelectedSources(new Set()); + showSuccess(`已禁用 ${selectedSources.size} 个源`, showAlert); + } catch (error) { + showError(error instanceof Error ? error.message : '批量禁用失败', showAlert); + } + }); + }; + + // 批量删除 + const handleBatchDelete = async () => { + if (selectedSources.size === 0) return; + showAlert({ + type: 'warning', + title: '确认批量删除', + message: `确定要删除选中的 ${selectedSources.size} 个源吗?此操作不可恢复。`, + showConfirm: true, + onConfirm: async () => { + await withLoading('batchDeleteEmby', async () => { + try { + const newSources = sources.filter(s => !selectedSources.has(s.key)); + const response = await fetch('/api/admin/config', { + method: 'POST', + headers: { 'Content-Type': 'application/json' }, + body: JSON.stringify({ ...config, EmbyConfig: { Sources: newSources } }), + }); + if (!response.ok) throw new Error('批量删除失败'); + await refreshConfig(); + setSelectedSources(new Set()); + showSuccess(`已删除 ${selectedSources.size} 个源`, showAlert); + } catch (error) { + showError(error instanceof Error ? error.message : '批量删除失败', showAlert); + } + }); + }, + }); + }; + return (
Emby 源列表 ({sources.length}) - +
+ +
+ {selectedSources.size > 0 && ( +
+ + 已选择 {selectedSources.size} 项 + + + + + +
+ )} + {sources.length === 0 ? (
暂无Emby源,点击"添加新源"开始配置 @@ -3732,37 +3845,53 @@ const EmbyConfigComponent = ({ className='border border-gray-200 dark:border-gray-700 rounded-lg p-4 bg-white dark:bg-gray-800' >
-
-
-

- {source.name} -

- {source.isDefault && ( - - 默认 +
+ { + const newSelected = new Set(selectedSources); + if (e.target.checked) { + newSelected.add(source.key); + } else { + newSelected.delete(source.key); + } + setSelectedSources(newSelected); + }} + className='w-4 h-4 text-blue-600 rounded border-gray-300 dark:border-gray-600' + /> +
+
+

+ {source.name} +

+ {source.isDefault && ( + + 默认 + + )} + + {source.enabled ? '已启用' : '已禁用'} - )} - - {source.enabled ? '已启用' : '已禁用'} - -
-

- 标识符: {source.key} -

-

- 服务器: {source.ServerURL} -

- {source.UserId && ( +

- 用户ID: {source.UserId} + 标识符: {source.key}

- )} +

+ 服务器: {source.ServerURL} +

+ {source.UserId && ( +

+ 用户ID: {source.UserId} +

+ )} +