import React, { useState, useEffect } from 'react';
import {
Download,
Plus,
Edit,
Trash2,
Smartphone,
Monitor,
Apple,
Search,
X,
ChevronDown,
ChevronUp
} from 'lucide-react';
import apiClient from '../utils/apiClient';
import { buildApiUrl, API_ENDPOINTS } from '../config/api';
import './ClientManagement.css';
const ClientManagement = ({ user }) => {
const [clients, setClients] = useState([]);
const [loading, setLoading] = useState(true);
const [showCreateModal, setShowCreateModal] = useState(false);
const [showEditModal, setShowEditModal] = useState(false);
const [showDeleteModal, setShowDeleteModal] = useState(false);
const [selectedClient, setSelectedClient] = useState(null);
const [filterPlatformType, setFilterPlatformType] = useState('');
const [searchQuery, setSearchQuery] = useState('');
const [expandedNotes, setExpandedNotes] = useState({});
const [formData, setFormData] = useState({
platform_type: 'mobile',
platform_name: 'ios',
version: '',
version_code: '',
download_url: '',
file_size: '',
release_notes: '',
is_active: true,
is_latest: false,
min_system_version: ''
});
const platformOptions = {
mobile: [
{ value: 'ios', label: 'iOS', icon: },
{ value: 'android', label: 'Android', icon: }
],
desktop: [
{ value: 'windows', label: 'Windows', icon: },
{ value: 'mac_intel', label: 'Mac (Intel)', icon: },
{ value: 'mac_m', label: 'Mac (M系列)', icon: },
{ value: 'linux', label: 'Linux', icon: }
]
};
useEffect(() => {
fetchClients();
}, []);
const fetchClients = async () => {
setLoading(true);
try {
const response = await apiClient.get(buildApiUrl(API_ENDPOINTS.CLIENT_DOWNLOADS.LIST));
console.log('Client downloads response:', response);
setClients(response.data.clients || []);
} catch (error) {
console.error('获取客户端列表失败:', error);
} finally {
setLoading(false);
}
};
const handleCreate = async () => {
try {
// 验证必填字段
if (!formData.version_code || !formData.version || !formData.download_url) {
alert('请填写所有必填字段');
return;
}
const payload = {
...formData,
version_code: parseInt(formData.version_code, 10),
file_size: formData.file_size ? parseInt(formData.file_size, 10) : null
};
// 验证转换后的数字
if (isNaN(payload.version_code)) {
alert('版本代码必须是有效的数字');
return;
}
if (formData.file_size && isNaN(payload.file_size)) {
alert('文件大小必须是有效的数字');
return;
}
await apiClient.post(buildApiUrl(API_ENDPOINTS.CLIENT_DOWNLOADS.CREATE), payload);
setShowCreateModal(false);
resetForm();
fetchClients();
} catch (error) {
console.error('创建客户端失败:', error);
alert(error.response?.data?.message || '创建失败,请重试');
}
};
const handleUpdate = async () => {
try {
// 验证必填字段
if (!formData.version_code || !formData.version || !formData.download_url) {
alert('请填写所有必填字段');
return;
}
const payload = {
version: formData.version,
version_code: parseInt(formData.version_code, 10),
download_url: formData.download_url,
file_size: formData.file_size ? parseInt(formData.file_size, 10) : null,
release_notes: formData.release_notes,
is_active: formData.is_active,
is_latest: formData.is_latest,
min_system_version: formData.min_system_version
};
// 验证转换后的数字
if (isNaN(payload.version_code)) {
alert('版本代码必须是有效的数字');
return;
}
if (formData.file_size && isNaN(payload.file_size)) {
alert('文件大小必须是有效的数字');
return;
}
await apiClient.put(
buildApiUrl(API_ENDPOINTS.CLIENT_DOWNLOADS.UPDATE(selectedClient.id)),
payload
);
setShowEditModal(false);
resetForm();
fetchClients();
} catch (error) {
console.error('更新客户端失败:', error);
alert(error.response?.data?.message || '更新失败,请重试');
}
};
const handleDelete = async () => {
try {
await apiClient.delete(buildApiUrl(API_ENDPOINTS.CLIENT_DOWNLOADS.DELETE(selectedClient.id)));
setShowDeleteModal(false);
setSelectedClient(null);
fetchClients();
} catch (error) {
console.error('删除客户端失败:', error);
alert('删除失败,请重试');
}
};
const openEditModal = (client) => {
setSelectedClient(client);
setFormData({
platform_type: client.platform_type,
platform_name: client.platform_name,
version: client.version,
version_code: String(client.version_code),
download_url: client.download_url,
file_size: client.file_size ? String(client.file_size) : '',
release_notes: client.release_notes || '',
is_active: client.is_active,
is_latest: client.is_latest,
min_system_version: client.min_system_version || ''
});
setShowEditModal(true);
};
const openDeleteModal = (client) => {
setSelectedClient(client);
setShowDeleteModal(true);
};
const resetForm = () => {
setFormData({
platform_type: 'mobile',
platform_name: 'ios',
version: '',
version_code: '',
download_url: '',
file_size: '',
release_notes: '',
is_active: true,
is_latest: false,
min_system_version: ''
});
setSelectedClient(null);
};
const getPlatformLabel = (platformName) => {
const allOptions = [...platformOptions.mobile, ...platformOptions.desktop];
const option = allOptions.find(opt => opt.value === platformName);
return option ? option.label : platformName;
};
const formatFileSize = (bytes) => {
if (!bytes) return '-';
const mb = bytes / (1024 * 1024);
return `${mb.toFixed(2)} MB`;
};
const toggleNotes = (clientId) => {
setExpandedNotes(prev => ({
...prev,
[clientId]: !prev[clientId]
}));
};
const filteredClients = clients.filter(client => {
if (filterPlatformType && client.platform_type !== filterPlatformType) {
return false;
}
if (searchQuery) {
const query = searchQuery.toLowerCase();
return (
client.version.toLowerCase().includes(query) ||
getPlatformLabel(client.platform_name).toLowerCase().includes(query) ||
(client.release_notes && client.release_notes.toLowerCase().includes(query))
);
}
return true;
});
const groupedClients = {
mobile: filteredClients.filter(c => c.platform_type === 'mobile'),
desktop: filteredClients.filter(c => c.platform_type === 'desktop')
};
if (loading) {
return
加载中...
;
}
return (
客户端下载管理
{['mobile', 'desktop'].map(type => {
const typeClients = groupedClients[type];
if (typeClients.length === 0 && filterPlatformType && filterPlatformType !== type) {
return null;
}
return (
{type === 'mobile' ? : }
{type === 'mobile' ? '移动端' : '桌面端'}
({typeClients.length})
{typeClients.length === 0 ? (
暂无客户端
) : (
{typeClients.map(client => (
{getPlatformLabel(client.platform_name)}
{client.is_latest && 最新}
{!client.is_active && 未启用}
版本:
{client.version}
版本代码:
{client.version_code}
文件大小:
{formatFileSize(client.file_size)}
{client.min_system_version && (
系统要求:
{client.min_system_version}
)}
{client.release_notes && (
toggleNotes(client.id)}
style={{ cursor: 'pointer', display: 'flex', alignItems: 'center', justifyContent: 'space-between' }}
>
更新说明
{expandedNotes[client.id] ? : }
{expandedNotes[client.id] && (
{client.release_notes}
)}
)}
))}
)}
);
})}
{/* 创建/编辑模态框 */}
{(showCreateModal || showEditModal) && (
{
setShowCreateModal(false);
setShowEditModal(false);
resetForm();
}}>
e.stopPropagation()}>
{showEditModal ? '编辑客户端' : '新增客户端'}
setFormData({ ...formData, download_url: e.target.value })}
/>
)}
{/* 删除确认模态框 */}
{showDeleteModal && selectedClient && (
setShowDeleteModal(false)}>
e.stopPropagation()}>
确认删除
确定要删除 {getPlatformLabel(selectedClient.platform_name)} 版本{' '}
{selectedClient.version} 吗?此操作无法撤销。
)}
);
};
export default ClientManagement;