|
|
@@ -2,6 +2,7 @@
|
|
|
|
|
|
import {
|
|
|
DownOutlined,
|
|
|
+ DownloadOutlined,
|
|
|
EditOutlined,
|
|
|
EyeOutlined,
|
|
|
LockOutlined,
|
|
|
@@ -39,6 +40,7 @@ import AudioUpload from "@/components/AudioUpload";
|
|
|
import ImageUpload from "@/components/ImageUpload";
|
|
|
import { useGlobalConsts } from "@/contexts/GlobalConstsContext";
|
|
|
import {
|
|
|
+ exportUserExcel,
|
|
|
getUserDetail,
|
|
|
getUserPage,
|
|
|
lockOrUnlockUser,
|
|
|
@@ -66,6 +68,7 @@ const UserListPage: React.FC = () => {
|
|
|
|
|
|
// State management
|
|
|
const [loading, setLoading] = useState(false);
|
|
|
+ const [exportLoading, setExportLoading] = useState(false);
|
|
|
const [dataSource, setDataSource] = useState<UserInfoAdminDTO[]>([]);
|
|
|
const [total, setTotal] = useState(0);
|
|
|
const [queryParams, setQueryParams] = useState<UserInfoAdminQuery>({
|
|
|
@@ -142,6 +145,46 @@ const UserListPage: React.FC = () => {
|
|
|
loadPageData();
|
|
|
};
|
|
|
|
|
|
+ // Export excel (desensitized)
|
|
|
+ const handleExport = async () => {
|
|
|
+ setExportLoading(true);
|
|
|
+ try {
|
|
|
+ const exportQuery: UserInfoAdminQuery = {
|
|
|
+ ...queryParams,
|
|
|
+ pageSize: 0,
|
|
|
+ pageIndex: 0,
|
|
|
+ };
|
|
|
+
|
|
|
+ const { blob, filename } = await exportUserExcel(exportQuery);
|
|
|
+
|
|
|
+ if (!blob || blob.size === 0) {
|
|
|
+ message.error("导出失败:文件为空");
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ const now = new Date();
|
|
|
+ const pad = (n: number) => String(n).padStart(2, "0");
|
|
|
+ const ts = `${now.getFullYear()}${pad(now.getMonth() + 1)}${pad(now.getDate())}_${pad(now.getHours())}${pad(now.getMinutes())}${pad(now.getSeconds())}`;
|
|
|
+ const fallbackName = `user_list_${ts}.xlsx`;
|
|
|
+
|
|
|
+ const url = window.URL.createObjectURL(blob);
|
|
|
+ const a = document.createElement("a");
|
|
|
+ a.href = url;
|
|
|
+ a.download = filename || fallbackName;
|
|
|
+ document.body.appendChild(a);
|
|
|
+ a.click();
|
|
|
+ a.remove();
|
|
|
+ window.URL.revokeObjectURL(url);
|
|
|
+
|
|
|
+ message.success("导出成功");
|
|
|
+ } catch (error) {
|
|
|
+ console.error("Failed to export user excel:", error);
|
|
|
+ message.error("导出失败");
|
|
|
+ } finally {
|
|
|
+ setExportLoading(false);
|
|
|
+ }
|
|
|
+ };
|
|
|
+
|
|
|
// Pagination change handler
|
|
|
const handleTableChange = (pagination: TablePaginationConfig) => {
|
|
|
setQueryParams({
|
|
|
@@ -572,6 +615,13 @@ const UserListPage: React.FC = () => {
|
|
|
>
|
|
|
刷新
|
|
|
</Button>
|
|
|
+ <Button
|
|
|
+ icon={<DownloadOutlined />}
|
|
|
+ onClick={() => void handleExport()}
|
|
|
+ loading={exportLoading}
|
|
|
+ >
|
|
|
+ 导出 (脱敏)
|
|
|
+ </Button>
|
|
|
</Space>
|
|
|
</Form.Item>
|
|
|
</Form>
|