main
parent
1a4d97f1e9
commit
6cbe02fbf6
|
|
@ -4,6 +4,8 @@ import apiClient from '../utils/apiClient';
|
||||||
import { buildApiUrl, API_ENDPOINTS } from '../config/api';
|
import { buildApiUrl, API_ENDPOINTS } from '../config/api';
|
||||||
import Dropdown from '../components/Dropdown';
|
import Dropdown from '../components/Dropdown';
|
||||||
import menuService from '../services/menuService';
|
import menuService from '../services/menuService';
|
||||||
|
import ConfirmDialog from '../components/ConfirmDialog';
|
||||||
|
import Toast from '../components/Toast';
|
||||||
import './AdminDashboard.css';
|
import './AdminDashboard.css';
|
||||||
|
|
||||||
// 常量定义
|
// 常量定义
|
||||||
|
|
@ -60,6 +62,20 @@ const AdminDashboard = ({ user, onLogout }) => {
|
||||||
const [autoRefresh, setAutoRefresh] = useState(true);
|
const [autoRefresh, setAutoRefresh] = useState(true);
|
||||||
const [countdown, setCountdown] = useState(AUTO_REFRESH_INTERVAL);
|
const [countdown, setCountdown] = useState(AUTO_REFRESH_INTERVAL);
|
||||||
|
|
||||||
|
// Toast和确认对话框
|
||||||
|
const [toasts, setToasts] = useState([]);
|
||||||
|
const [kickConfirmInfo, setKickConfirmInfo] = useState(null);
|
||||||
|
|
||||||
|
// Toast辅助函数
|
||||||
|
const showToast = (message, type = 'info') => {
|
||||||
|
const id = Date.now();
|
||||||
|
setToasts(prev => [...prev, { id, message, type }]);
|
||||||
|
};
|
||||||
|
|
||||||
|
const removeToast = (id) => {
|
||||||
|
setToasts(prev => prev.filter(toast => toast.id !== id));
|
||||||
|
};
|
||||||
|
|
||||||
// 获取菜单配置
|
// 获取菜单配置
|
||||||
const getMenuItemConfig = (menu) => {
|
const getMenuItemConfig = (menu) => {
|
||||||
const iconMap = {
|
const iconMap = {
|
||||||
|
|
@ -203,20 +219,20 @@ const AdminDashboard = ({ user, onLogout }) => {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleKickUser = async (userId) => {
|
const handleKickUser = async () => {
|
||||||
if (!confirm('确定要踢出该用户吗?')) return;
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const response = await apiClient.post(buildApiUrl(API_ENDPOINTS.ADMIN.KICK_USER(userId)));
|
const response = await apiClient.post(buildApiUrl(API_ENDPOINTS.ADMIN.KICK_USER(kickConfirmInfo.user_id)));
|
||||||
if (response.code === '200') {
|
if (response.code === '200') {
|
||||||
alert('用户已被踢出');
|
showToast('用户已被踢出', 'success');
|
||||||
fetchOnlineUsers();
|
fetchOnlineUsers();
|
||||||
} else {
|
} else {
|
||||||
alert('踢出失败: ' + response.message);
|
showToast(`踢出失败: ${response.message}`, 'error');
|
||||||
}
|
}
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
console.error('踢出用户失败:', err);
|
console.error('踢出用户失败:', err);
|
||||||
alert('踢出用户失败');
|
showToast('踢出用户失败', 'error');
|
||||||
|
} finally {
|
||||||
|
setKickConfirmInfo(null);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -494,7 +510,7 @@ const AdminDashboard = ({ user, onLogout }) => {
|
||||||
<td>
|
<td>
|
||||||
<button
|
<button
|
||||||
className="kick-btn"
|
className="kick-btn"
|
||||||
onClick={() => handleKickUser(u.user_id)}
|
onClick={() => setKickConfirmInfo(u)}
|
||||||
title="踢出用户"
|
title="踢出用户"
|
||||||
>
|
>
|
||||||
<UserX size={16} />
|
<UserX size={16} />
|
||||||
|
|
@ -568,6 +584,28 @@ const AdminDashboard = ({ user, onLogout }) => {
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
{/* 踢出用户确认对话框 */}
|
||||||
|
<ConfirmDialog
|
||||||
|
isOpen={!!kickConfirmInfo}
|
||||||
|
onClose={() => setKickConfirmInfo(null)}
|
||||||
|
onConfirm={handleKickUser}
|
||||||
|
title="踢出用户"
|
||||||
|
message={`确定要踢出用户"${kickConfirmInfo?.caption}"吗?该用户将被强制下线。`}
|
||||||
|
confirmText="确定踢出"
|
||||||
|
cancelText="取消"
|
||||||
|
type="warning"
|
||||||
|
/>
|
||||||
|
|
||||||
|
{/* Toast notifications */}
|
||||||
|
{toasts.map(toast => (
|
||||||
|
<Toast
|
||||||
|
key={toast.id}
|
||||||
|
message={toast.message}
|
||||||
|
type={toast.type}
|
||||||
|
onClose={() => removeToast(toast.id)}
|
||||||
|
/>
|
||||||
|
))}
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue