blob: c0ede42477dac7b0195d9ca3d31a0141cffd1fcf [file] [log] [blame]
import React, { useState, useEffect } from 'react';
import {
Table,
Button,
Modal,
Image,
message,
Spin,
Input,
Select,
Pagination,
Space
} from 'antd';
import { ExclamationCircleOutlined } from '@ant-design/icons';
import axios from 'axios';
const { confirm } = Modal;
const { Option } = Select;
const UserManagement = () => {
// 状态管理
const [users, setUsers] = useState([]);
const [isLoading, setIsLoading] = useState(false);
const [error, setError] = useState(null);
const [currentUserId, setCurrentUserId] = useState(null);
const [applyExamLoading, setApplyExamLoading] = useState(false);
const [searchKeyword, setSearchKeyword] = useState('');
const [currentPage, setCurrentPage] = useState(1);
const [pageSize, setPageSize] = useState(10);
// 获取当前用户ID
useEffect(() => {
const userId = 1; // 示例,实际从认证系统获取
setCurrentUserId(userId ? parseInt(userId) : null);
}, []);
// 获取所有用户数据
useEffect(() => {
fetchAllUsers();
}, [searchKeyword]);
// 获取所有用户的函数
const fetchAllUsers = async () => {
setIsLoading(true);
setError(null);
try {
const res = await axios.get('http://localhost:8080/user/alluser');
setUsers(res.data.data);
setCurrentPage(1); // 重置为第一页
} catch (err) {
console.error('获取用户失败', err);
setError('获取用户列表失败,请稍后重试');
message.error('获取用户列表失败');
} finally {
setIsLoading(false);
}
};
console.log('当前用户列表:', users);
// 删除用户
const handleDeleteUser = async (username) => {
confirm({
title: '确认删除',
icon: <ExclamationCircleOutlined />,
content: '确定要删除这个用户吗?此操作不可恢复!',
onOk: async () => {
try {
await axios.delete(`http://localhost:8080/user/DeleteUser`, {
params: { username: username }
});
setUsers(users.filter(user => user.username !== username));
message.success('用户删除成功');
} catch (err) {
console.error('用户删除失败', err);
if (err.response && err.response.status === 403) {
message.error('无权删除此用户');
} else {
message.error('删除用户失败');
}
}
}
});
};
// 搜索种子
const handleSearch = async () => {
if (!searchKeyword.trim()) {
fetchAllUsers();
return;
}
setIsLoading(true);
setError(null);
try {
const res = await axios.get(`http://localhost:8080/user/finduser`, {
params: { keyword: searchKeyword },
});
setUsers(res.data.data);
setCurrentPage(1); // 搜索后重置为第一页
} catch (err) {
console.error('搜索失败', err);
setError('搜索失败,请稍后重试');
message.error('搜索失败');
} finally {
setIsLoading(false);
}
};
// 月度下载量考核
const handleMonthExam = async () => {
if (!currentUserId) {
message.warning('请先登录');
return;
}
setApplyExamLoading(true);
try {
const now = new Date();
const year = now.getFullYear();
const month = String(now.getMonth() + 1).padStart(2, '0'); // 月份从0开始,补零
const day = String(now.getDate()).padStart(2, '0'); // 日期补零
const formattedDate = `${year}-${month}-${day}`;
const currentDate = new Date();
const lastMonthDate = new Date(
currentDate.getFullYear(),
currentDate.getMonth() - 1, // 月份减1
currentDate.getDate() // 保持相同的日
);
if (lastMonthDate.getDate() !== currentDate.getDate()) {
lastMonthDate.setDate(0); // 设置为上个月的最后一天
}
const year1 = lastMonthDate.getFullYear();
const month1 = String(lastMonthDate.getMonth() + 1).padStart(2, '0');
const day1 = String(lastMonthDate.getDate()).padStart(2, '0');
const formattedDate1 = `${year1}-${month1}-${day1}`;
const res = await axios.post('http://localhost:8080/exam/MonthDownload', null, {
params: { startDate: formattedDate1,endDate: formattedDate }
});
if (res.data.success) {
message.success(res.data.message);
fetchAllUsers(); // 刷新种子列表
}
} catch (err) {
console.error('月度考核失败', err);
if (err.response && err.response.status === 403) {
message.error('无权执行此操作');
} else {
message.error('月度考核失败');
}
} finally {
setApplyExamLoading(false);
}
};
// 季度上传量考核
const handleQuarterExam = async () => {
if (!currentUserId) {
message.warning('请先登录');
return;
}
setApplyExamLoading(true);
try {
const now = new Date();
const year = now.getFullYear();
const month = String(now.getMonth() + 1).padStart(2, '0'); // 月份从0开始,补零
const day = String(now.getDate()).padStart(2, '0'); // 日期补零
const formattedDate = `${year}-${month}-${day}`;
const currentDate = new Date();
const lastMonthDate = new Date(
currentDate.getFullYear(),
currentDate.getMonth() - 3, // 月份减1
currentDate.getDate() // 保持相同的日
);
if (lastMonthDate.getDate() !== currentDate.getDate()) {
lastMonthDate.setDate(0); // 设置为上个月的最后一天
}
const year1 = lastMonthDate.getFullYear();
const month1 = String(lastMonthDate.getMonth() + 1).padStart(2, '0');
const day1 = String(lastMonthDate.getDate()).padStart(2, '0');
const formattedDate1 = `${year1}-${month1}-${day1}`;
const res = await axios.post('http://localhost:8080/exam/QuarterUpload', null, {
params: { startDate: formattedDate1,endDate: formattedDate }
});
if (res.data.success) {
message.success(res.data.message);
fetchAllUsers(); // 刷新种子列表
}
} catch (err) {
console.error('季度考核失败', err);
if (err.response && err.response.status === 403) {
message.error('无权执行此操作');
} else {
message.error('月度考核失败');
}
} finally {
setApplyExamLoading(false);
}
};
// 分页数据计算
const getCurrentPageData = () => {
const start = (currentPage - 1) * pageSize;
const end = start + pageSize;
return users;//.slice(start, end);
};
// 页码变化处理
const handlePageChange = (page) => {
setCurrentPage(page);
};
// 每页条数变化处理
const handlePageSizeChange = (current, size) => {
setPageSize(size);
setCurrentPage(1); // 重置为第一页
};
// 格式化文件大小
const formatFileSize = (bytes) => {
if (bytes === 0) return '0 Bytes';
const k = 1024;
const sizes = ['Bytes', 'KB', 'MB', 'GB', 'TB'];
const i = Math.floor(Math.log(bytes) / Math.log(k));
return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + ' ' + sizes[i];
};
////////////////////////////////////////////////////////////////////////////
return (
<div className="p-4 max-w-7xl mx-auto">
<h1 className="text-2xl font-bold mb-6">用户管理</h1>
{/* 搜索框 */}
<div className="mb-4 flex items-center">
<Input
placeholder="搜索用户..."
value={searchKeyword}
onChange={(e) => setSearchKeyword(e.target.value)}
style={{ width: 300 }}
onPressEnter={handleSearch}
/>
<Button
type="primary"
onClick={handleSearch}
style={{ marginLeft: 8 }}
>
搜索
</Button>
</div>
{/* 右上角按钮 */}
<Space>
<Button
type="primary"
loading={applyExamLoading}
onClick={handleMonthExam}
>
月度下载量检查
</Button>
<Button
type="primary"
loading={applyExamLoading}
onClick={handleQuarterExam}
>
季度上传量检查
</Button>
</Space>
{/* 加载状态 */}
{isLoading && <Spin size="large" style={{ display: 'block', margin: '100px auto' }} />}
{/* 错误提示 */}
{error && <div className="mb-4 p-3 bg-red-100 text-red-700 rounded border border-red-200">{error}</div>}
{/* 种子列表表格 */}
{!isLoading && !error && (
<>
<Table
columns={[
{
title: '用户名',
dataIndex: 'username',
key: 'username'
},
{
title: '密码',
dataIndex: 'password',
key: 'password'
},
{
title: '上传量',
dataIndex: 'user_upload',
key: 'user_upload',
render: (size) => formatFileSize(size)
},
{
title: '下载量',
dataIndex: 'user_download',
key: 'user_download',
render: (size) => formatFileSize(size)
},
{
title: '保种积分',
dataIndex: 'credit',
key: 'credit',
},
{
title: '头像',
dataIndex: 'image',
key: 'image',
render: (text) => text ? (
<Image
src={text}
width={50}
height={50}
preview={{ maskClosable: true }}
/>
) : (
<div className="w-16 h-16 bg-gray-200 flex items-center justify-center">无头像</div>
)
},
{
title: '性别',
dataIndex: 'sex',
key: 'sex',
},
{
title: '用户id',
dataIndex: 'userid',
key: 'userid'
},
{
title: '用户等级',
dataIndex: 'grade_id',
key: 'grade_id'
},
{
title: 'passkey',
dataIndex: 'passkey',
key: 'passkey'
},
{
title: '分享率',
dataIndex: 'ratio',
key: 'ratio'
},
{
title: '年龄',
dataIndex: 'age',
key: 'age'
},
{
title: '邮箱',
dataIndex: 'email',
key: 'email'
},
{
title: '用户权限',
dataIndex: 'permission',
key: 'permission'
},
{
title: '操作',
key: 'action',
render: (_, record) => (
<Space>
<Button
danger
onClick={() => handleDeleteUser(record.username)}
loading={isLoading}
>
删除
</Button>
</Space>
)
}
]}
dataSource={getCurrentPageData()}
rowKey="userid"
pagination={false}
loading={isLoading}
/>
{/* 分页控件 */}
{users.length > 0 && (
<div style={{ marginTop: 16, textAlign: 'center' }}>
<Pagination
current={currentPage}
pageSize={pageSize}
total={users.length}
onChange={handlePageChange}
onShowSizeChange={handlePageSizeChange}
showSizeChanger
showTotal={(total) => `共 ${total} 条记录`}
pageSizeOptions={['10', '20', '50']}
/>
</div>
)}
</>
)}
</div>
);
};
export default UserManagement;