2025-03-19 15:57:48 +08:00
|
|
|
|
'use client';
|
2025-03-19 21:33:26 +08:00
|
|
|
|
import { useState } from 'react';
|
|
|
|
|
import { AgGridReact } from '@ag-grid-community/react';
|
|
|
|
|
import { ColDef, ColGroupDef } from '@ag-grid-community/core';
|
|
|
|
|
import { SetFilterModule } from '@ag-grid-enterprise/set-filter';
|
2025-03-19 15:57:48 +08:00
|
|
|
|
import 'ag-grid-community/styles/ag-grid.css';
|
|
|
|
|
import 'ag-grid-community/styles/ag-theme-alpine.css';
|
|
|
|
|
import { areaOptions } from '@web/src/app/main/staffinformation/area-options';
|
|
|
|
|
import type { CascaderProps } from 'antd/es/cascader';
|
2025-03-19 21:33:26 +08:00
|
|
|
|
import { utils, writeFile } from 'xlsx';
|
2025-03-20 23:09:41 +08:00
|
|
|
|
import { Modal, Input, Button, Switch } from 'antd';
|
2025-03-19 21:33:26 +08:00
|
|
|
|
import { api } from '@nice/client';
|
2025-03-19 22:04:01 +08:00
|
|
|
|
import DepartmentSelect from '@web/src/components/models/department/department-select';
|
2025-03-20 23:09:41 +08:00
|
|
|
|
import { ClientSideRowModelModule } from '@ag-grid-community/client-side-row-model';
|
2025-03-12 11:45:18 +08:00
|
|
|
|
|
2025-03-19 15:57:48 +08:00
|
|
|
|
// 修改函数类型定义
|
|
|
|
|
|
|
|
|
|
function getAreaName(codes: string[], level?: number): string {
|
|
|
|
|
const result: string[] = [];
|
|
|
|
|
let currentLevel: CascaderProps['options'] = areaOptions;
|
2025-03-19 21:33:26 +08:00
|
|
|
|
|
2025-03-19 15:57:48 +08:00
|
|
|
|
for (const code of codes) {
|
|
|
|
|
const found = currentLevel?.find(opt => opt.value === code);
|
|
|
|
|
if (!found) break;
|
|
|
|
|
|
|
|
|
|
result.push(String(found.label));
|
|
|
|
|
currentLevel = found.children || [];
|
|
|
|
|
if (level && result.length >= level) break; // 添加层级控制
|
|
|
|
|
}
|
2025-03-19 21:33:26 +08:00
|
|
|
|
|
2025-03-19 15:57:48 +08:00
|
|
|
|
|
|
|
|
|
return level ? result[level - 1] || '' : result.join(' / ') || codes.join('/');
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export default function StaffTable() {
|
2025-03-12 11:45:18 +08:00
|
|
|
|
const { data: staffs, isLoading } = api.staff.findMany.useQuery({
|
2025-03-19 15:57:48 +08:00
|
|
|
|
where: { deletedAt: null },
|
2025-03-19 21:33:26 +08:00
|
|
|
|
include: { // 添加关联查询
|
|
|
|
|
department: true
|
|
|
|
|
}
|
2025-03-12 11:45:18 +08:00
|
|
|
|
});
|
2025-03-19 21:33:26 +08:00
|
|
|
|
const [gridApi, setGridApi] = useState<any>(null); // 添加gridApi状态
|
|
|
|
|
const [fileNameVisible, setFileNameVisible] = useState(false);
|
|
|
|
|
const [fileName, setFileName] = useState('');
|
|
|
|
|
const [defaultFileName] = useState(`员工数据_${new Date().toISOString().slice(0, 10)}`);
|
2025-03-20 23:09:41 +08:00
|
|
|
|
const [paginationEnabled, setPaginationEnabled] = useState(true);
|
2025-03-19 21:33:26 +08:00
|
|
|
|
|
|
|
|
|
const handleConfirm = async () => {
|
|
|
|
|
setFileNameVisible(true);
|
2025-03-19 22:04:01 +08:00
|
|
|
|
|
2025-03-19 21:33:26 +08:00
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
// 添加导出处理函数
|
|
|
|
|
const handleFileNameConfirm = () => {
|
2025-03-20 23:09:41 +08:00
|
|
|
|
setFileNameVisible(false);
|
|
|
|
|
if (!gridApi || typeof gridApi.getRenderedNodes !== 'function') {
|
|
|
|
|
console.error('Grid API 未正确初始化');
|
|
|
|
|
return;
|
|
|
|
|
}
|
2025-03-19 22:04:01 +08:00
|
|
|
|
|
2025-03-20 23:09:41 +08:00
|
|
|
|
// 修改获取节点方式(使用更可靠的 getRenderedNodes)
|
|
|
|
|
const rowNodes = gridApi.getRenderedNodes();
|
2025-03-19 22:04:01 +08:00
|
|
|
|
|
2025-03-20 23:09:41 +08:00
|
|
|
|
// 获取所有列定义
|
|
|
|
|
const flattenColumns = (cols: any[]): any[] => cols.flatMap(col => col.children ? flattenColumns(col.children) : col);
|
|
|
|
|
const allColDefs = flattenColumns(gridApi.getColumnDefs());
|
2025-03-19 22:04:01 +08:00
|
|
|
|
|
2025-03-20 23:09:41 +08:00
|
|
|
|
// 获取数据(兼容分页状态)
|
2025-03-19 22:04:01 +08:00
|
|
|
|
|
2025-03-20 23:09:41 +08:00
|
|
|
|
// 处理数据格式
|
|
|
|
|
const processRowData = (node: any) => {
|
2025-03-19 21:33:26 +08:00
|
|
|
|
const row: Record<string, any> = {};
|
|
|
|
|
allColDefs.forEach((colDef: any) => {
|
2025-03-20 23:09:41 +08:00
|
|
|
|
if (!colDef.field || !colDef.headerName) return;
|
2025-03-19 22:04:01 +08:00
|
|
|
|
|
2025-03-20 23:09:41 +08:00
|
|
|
|
// 修改字段访问方式,支持嵌套对象
|
|
|
|
|
const value = colDef.field.includes('.')
|
|
|
|
|
? colDef.field.split('.').reduce((obj: any, key: string) => (obj || {})[key], node.data)
|
|
|
|
|
: node.data[colDef.field];
|
2025-03-19 22:04:01 +08:00
|
|
|
|
|
2025-03-20 23:09:41 +08:00
|
|
|
|
let renderedValue = value;
|
|
|
|
|
|
|
|
|
|
// 应用列格式化
|
|
|
|
|
if (colDef.valueFormatter) {
|
|
|
|
|
renderedValue = colDef.valueFormatter({ value });
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 处理特殊数据类型
|
|
|
|
|
if (colDef.cellRenderer) {
|
|
|
|
|
const renderResult = colDef.cellRenderer({ value });
|
|
|
|
|
if (typeof renderResult === 'string') {
|
|
|
|
|
renderedValue = renderResult;
|
|
|
|
|
} else if (renderResult?.props?.dangerouslySetInnerHTML?.__html) {
|
|
|
|
|
renderedValue = renderResult.props.dangerouslySetInnerHTML.__html.replace(/<br\s*\/?>/gi, '\n');
|
2025-03-19 21:33:26 +08:00
|
|
|
|
}
|
2025-03-20 23:09:41 +08:00
|
|
|
|
}
|
2025-03-19 22:04:01 +08:00
|
|
|
|
|
2025-03-20 23:09:41 +08:00
|
|
|
|
// 统一布尔值显示
|
|
|
|
|
if (typeof renderedValue === 'boolean') {
|
|
|
|
|
renderedValue = renderedValue ? '是' : '否';
|
2025-03-19 21:33:26 +08:00
|
|
|
|
}
|
2025-03-20 23:09:41 +08:00
|
|
|
|
|
|
|
|
|
// 日期字段处理
|
|
|
|
|
if (['hireDate', 'rankDate', 'seniority'].includes(colDef.field) && value) {
|
|
|
|
|
renderedValue = new Date(value).toLocaleDateString('zh-CN');
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 特别处理部门名称显示
|
|
|
|
|
if (colDef.field === 'department.name' && renderedValue === undefined) {
|
|
|
|
|
renderedValue = node.data.department?.name || '';
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
row[colDef.headerName] = renderedValue;
|
2025-03-19 21:33:26 +08:00
|
|
|
|
});
|
|
|
|
|
return row;
|
2025-03-20 23:09:41 +08:00
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
try {
|
|
|
|
|
// 生成工作表
|
|
|
|
|
const rowData = rowNodes.map(processRowData);
|
|
|
|
|
const ws = utils.json_to_sheet(rowData);
|
|
|
|
|
const wb = utils.book_new();
|
|
|
|
|
utils.book_append_sheet(wb, ws, "员工数据");
|
2025-03-19 21:33:26 +08:00
|
|
|
|
|
2025-03-20 23:09:41 +08:00
|
|
|
|
// 生成文件名
|
|
|
|
|
const finalFileName = fileName || `${defaultFileName}_${paginationEnabled ? '当前页' : '全部'}`;
|
|
|
|
|
writeFile(wb, `${finalFileName}.xlsx`);
|
|
|
|
|
} catch (error) {
|
|
|
|
|
console.error('导出失败:', error);
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
const handleResetFilters = () => {
|
|
|
|
|
if (gridApi) {
|
|
|
|
|
gridApi.setFilterModel(null);
|
|
|
|
|
gridApi.onFilterChanged(); // 触发筛选更新
|
|
|
|
|
}
|
2025-03-19 21:33:26 +08:00
|
|
|
|
};
|
2025-03-19 15:57:48 +08:00
|
|
|
|
|
|
|
|
|
const columnDefs: (ColDef | ColGroupDef)[] = [
|
2025-03-19 21:33:26 +08:00
|
|
|
|
{
|
|
|
|
|
field: 'username',
|
|
|
|
|
headerName: '姓名',
|
|
|
|
|
minWidth: 120,
|
2025-03-19 15:57:48 +08:00
|
|
|
|
pinned: 'left',
|
|
|
|
|
// floatingFilter: true // 确保启用浮动过滤器
|
|
|
|
|
},
|
2025-03-12 11:45:18 +08:00
|
|
|
|
{
|
2025-03-19 15:57:48 +08:00
|
|
|
|
headerName: '个人基本信息',
|
|
|
|
|
children: [
|
2025-03-19 21:33:26 +08:00
|
|
|
|
{
|
|
|
|
|
field: 'idNumber',
|
|
|
|
|
headerName: '身份证号',
|
2025-03-19 15:57:48 +08:00
|
|
|
|
minWidth: 180,
|
|
|
|
|
},
|
2025-03-19 21:33:26 +08:00
|
|
|
|
{
|
|
|
|
|
field: 'type',
|
|
|
|
|
headerName: '人员类型',
|
2025-03-19 15:57:48 +08:00
|
|
|
|
minWidth: 120,
|
|
|
|
|
},
|
|
|
|
|
{ field: 'officerId', headerName: '警号', minWidth: 120 },
|
|
|
|
|
{ field: 'phoneNumber', headerName: '手机号', minWidth: 130 },
|
|
|
|
|
{ field: 'age', headerName: '年龄', minWidth: 80 },
|
2025-03-19 21:33:26 +08:00
|
|
|
|
{
|
|
|
|
|
field: 'sex', headerName: '性别', minWidth: 80,
|
2025-03-20 23:09:41 +08:00
|
|
|
|
cellRenderer: (params: any) => {
|
|
|
|
|
switch (params.value) {
|
|
|
|
|
case true:
|
|
|
|
|
return '男';
|
|
|
|
|
case false:
|
|
|
|
|
return '女';
|
|
|
|
|
default:
|
|
|
|
|
return '未知';
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2025-03-19 21:33:26 +08:00
|
|
|
|
},
|
2025-03-19 15:57:48 +08:00
|
|
|
|
{ field: 'bloodType', headerName: '血型', minWidth: 80 },
|
2025-03-19 21:33:26 +08:00
|
|
|
|
{
|
|
|
|
|
field: 'birthplace',
|
|
|
|
|
headerName: '籍贯',
|
2025-03-19 15:57:48 +08:00
|
|
|
|
minWidth: 200,
|
|
|
|
|
valueFormatter: (params) => params.value ? getAreaName(params.value.split('/')) : '',
|
|
|
|
|
},
|
|
|
|
|
{ field: 'source', headerName: '来源', minWidth: 120 },
|
|
|
|
|
]
|
2025-03-12 11:45:18 +08:00
|
|
|
|
},
|
|
|
|
|
{
|
2025-03-19 15:57:48 +08:00
|
|
|
|
headerName: '政治信息',
|
|
|
|
|
children: [
|
|
|
|
|
{ field: 'politicalStatus', headerName: '政治面貌', minWidth: 150 },
|
|
|
|
|
{ field: 'partyPosition', headerName: '党内职务', minWidth: 120 }
|
|
|
|
|
]
|
2025-03-12 11:45:18 +08:00
|
|
|
|
},
|
|
|
|
|
{
|
2025-03-19 15:57:48 +08:00
|
|
|
|
headerName: '职务信息',
|
|
|
|
|
children: [
|
2025-03-19 21:33:26 +08:00
|
|
|
|
{ field: 'department.name', headerName: '所属部门', minWidth: 200 },
|
2025-03-19 15:57:48 +08:00
|
|
|
|
{ field: 'rank', headerName: '衔职级别', minWidth: 120 },
|
2025-03-19 21:33:26 +08:00
|
|
|
|
{
|
|
|
|
|
field: 'rankDate', headerName: '衔职时间', minWidth: 120,
|
|
|
|
|
valueFormatter: (params: any) => params.value ? new Date(params.value).toLocaleDateString() : ''
|
|
|
|
|
},
|
2025-03-20 23:09:41 +08:00
|
|
|
|
{ field: 'proxyPosition', headerName: '代理职务', minWidth: 120 },
|
|
|
|
|
{field: 'post', headerName: '岗位', minWidth: 120}
|
2025-03-19 15:57:48 +08:00
|
|
|
|
]
|
2025-03-12 11:45:18 +08:00
|
|
|
|
},
|
|
|
|
|
{
|
2025-03-19 15:57:48 +08:00
|
|
|
|
headerName: '入职信息',
|
|
|
|
|
children: [
|
2025-03-19 21:33:26 +08:00
|
|
|
|
{
|
|
|
|
|
field: 'hireDate', headerName: '入职时间', minWidth: 120,
|
|
|
|
|
valueFormatter: (params: any) => params.value ? new Date(params.value).toLocaleDateString() : ''
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
field: 'seniority', headerName: '工龄认定时间', minWidth: 140,
|
|
|
|
|
valueFormatter: (params: any) => params.value ? new Date(params.value).toLocaleDateString() : ''
|
|
|
|
|
},
|
2025-03-19 15:57:48 +08:00
|
|
|
|
{ field: 'sourceType', headerName: '来源类型', minWidth: 120 },
|
2025-03-19 21:33:26 +08:00
|
|
|
|
{
|
|
|
|
|
field: 'isReentry', headerName: '是否二次入职', minWidth: 120,
|
|
|
|
|
cellRenderer: (params: any) => params.value ? '是' : '否'
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
field: 'isExtended', headerName: '是否延期服役', minWidth: 120,
|
|
|
|
|
cellRenderer: (params: any) => params.value ? '是' : '否'
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
field: 'currentPositionDate', headerName: '现岗位开始时间', minWidth: 140,
|
|
|
|
|
valueFormatter: (params: any) => params.value ? new Date(params.value).toLocaleDateString() : ''
|
|
|
|
|
}
|
2025-03-19 15:57:48 +08:00
|
|
|
|
]
|
2025-03-12 11:45:18 +08:00
|
|
|
|
},
|
|
|
|
|
{
|
2025-03-19 15:57:48 +08:00
|
|
|
|
headerName: '教育背景',
|
|
|
|
|
children: [
|
|
|
|
|
{ field: 'education', headerName: '学历', minWidth: 100 },
|
|
|
|
|
{ field: 'educationType', headerName: '学历形式', minWidth: 120 },
|
2025-03-19 21:33:26 +08:00
|
|
|
|
{
|
|
|
|
|
field: 'isGraduated', headerName: '是否毕业', minWidth: 100,
|
|
|
|
|
cellRenderer: (params: any) => params.value ? '是' : '否'
|
|
|
|
|
},
|
2025-03-19 15:57:48 +08:00
|
|
|
|
{ field: 'major', headerName: '专业', minWidth: 150 },
|
|
|
|
|
{ field: 'foreignLang', headerName: '外语能力', minWidth: 120 }
|
|
|
|
|
]
|
2025-03-12 11:45:18 +08:00
|
|
|
|
},
|
|
|
|
|
{
|
2025-03-19 15:57:48 +08:00
|
|
|
|
headerName: '培训信息',
|
|
|
|
|
children: [
|
|
|
|
|
{ field: 'trainType', headerName: '培训类型', minWidth: 120 },
|
|
|
|
|
{ field: 'trainInstitute', headerName: '培训机构', minWidth: 150 },
|
|
|
|
|
{ field: 'trainMajor', headerName: '培训专业', minWidth: 150 },
|
2025-03-19 21:33:26 +08:00
|
|
|
|
{
|
|
|
|
|
field: 'hasTrain', headerName: '是否参加培训', minWidth: 120,
|
|
|
|
|
cellRenderer: (params: any) => params.value ? '是' : '否'
|
|
|
|
|
}
|
2025-03-19 15:57:48 +08:00
|
|
|
|
]
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
headerName: '鉴定信息',
|
|
|
|
|
children: [
|
|
|
|
|
{ field: 'certRank', headerName: '鉴定等级', minWidth: 120 },
|
|
|
|
|
{ field: 'certWork', headerName: '鉴定工种', minWidth: 120 },
|
2025-03-19 21:33:26 +08:00
|
|
|
|
{
|
|
|
|
|
field: 'hasCert', headerName: '是否参加鉴定', minWidth: 120,
|
|
|
|
|
cellRenderer: (params: any) => params.value ? '是' : '否'
|
|
|
|
|
}
|
2025-03-19 15:57:48 +08:00
|
|
|
|
]
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
headerName: '工作信息',
|
|
|
|
|
children: [
|
2025-03-19 21:33:26 +08:00
|
|
|
|
{
|
|
|
|
|
field: 'equipment',
|
2025-03-19 15:57:48 +08:00
|
|
|
|
headerName: '操作维护装备',
|
|
|
|
|
minWidth: 150,
|
|
|
|
|
cellRenderer: (params: any) => (
|
2025-03-19 21:33:26 +08:00
|
|
|
|
<div
|
2025-03-19 15:57:48 +08:00
|
|
|
|
style={{ lineHeight: '24px' }}
|
|
|
|
|
dangerouslySetInnerHTML={{ __html: params.value?.replace(/,/g, '<br/>') || '' }}
|
|
|
|
|
/>
|
|
|
|
|
),
|
|
|
|
|
autoHeight: true
|
|
|
|
|
},
|
2025-03-19 21:33:26 +08:00
|
|
|
|
{
|
|
|
|
|
field: 'projects',
|
2025-03-19 15:57:48 +08:00
|
|
|
|
headerName: '演训任务经历',
|
|
|
|
|
minWidth: 150,
|
|
|
|
|
cellRenderer: (params: any) => (
|
2025-03-19 21:33:26 +08:00
|
|
|
|
<div
|
2025-03-19 15:57:48 +08:00
|
|
|
|
style={{ lineHeight: '24px' }}
|
|
|
|
|
dangerouslySetInnerHTML={{ __html: params.value?.replace(/,/g, '<br/>') || '' }}
|
|
|
|
|
/>
|
|
|
|
|
),
|
|
|
|
|
autoHeight: true
|
|
|
|
|
},
|
|
|
|
|
// 修改剩余两个字段的cellRenderer为相同结构
|
2025-03-19 21:33:26 +08:00
|
|
|
|
{
|
|
|
|
|
field: 'awards',
|
2025-03-19 15:57:48 +08:00
|
|
|
|
headerName: '奖励信息',
|
|
|
|
|
minWidth: 150,
|
|
|
|
|
cellRenderer: (params: any) => (
|
2025-03-19 21:33:26 +08:00
|
|
|
|
<div
|
2025-03-19 15:57:48 +08:00
|
|
|
|
style={{ lineHeight: '24px' }}
|
|
|
|
|
dangerouslySetInnerHTML={{ __html: params.value?.replace(/,/g, '<br/>') || '' }}
|
|
|
|
|
/>
|
|
|
|
|
),
|
|
|
|
|
autoHeight: true
|
|
|
|
|
},
|
2025-03-19 21:33:26 +08:00
|
|
|
|
{
|
|
|
|
|
field: 'punishments',
|
2025-03-19 15:57:48 +08:00
|
|
|
|
headerName: '处分信息',
|
|
|
|
|
minWidth: 150,
|
|
|
|
|
cellRenderer: (params: any) => (
|
2025-03-19 21:33:26 +08:00
|
|
|
|
<div
|
2025-03-19 15:57:48 +08:00
|
|
|
|
style={{ lineHeight: '24px' }}
|
|
|
|
|
dangerouslySetInnerHTML={{ __html: params.value?.replace(/,/g, '<br/>') || '' }}
|
|
|
|
|
/>
|
|
|
|
|
),
|
|
|
|
|
autoHeight: true
|
|
|
|
|
}
|
|
|
|
|
]
|
2025-03-12 11:45:18 +08:00
|
|
|
|
}
|
|
|
|
|
];
|
|
|
|
|
|
2025-03-19 21:33:26 +08:00
|
|
|
|
|
2025-03-19 15:57:48 +08:00
|
|
|
|
const defaultColDef: ColDef = {
|
|
|
|
|
sortable: true,
|
|
|
|
|
filter: 'agSetColumnFilter',
|
|
|
|
|
resizable: false,
|
|
|
|
|
flex: 1,
|
|
|
|
|
minWidth: 150,
|
|
|
|
|
maxWidth: 600,
|
|
|
|
|
suppressMovable: true,
|
2025-03-19 21:33:26 +08:00
|
|
|
|
cellStyle: {
|
2025-03-19 15:57:48 +08:00
|
|
|
|
whiteSpace: 'normal',
|
|
|
|
|
overflowWrap: 'break-word'
|
|
|
|
|
},
|
|
|
|
|
wrapText: true,
|
|
|
|
|
autoHeight: true
|
|
|
|
|
};
|
2025-03-12 11:45:18 +08:00
|
|
|
|
|
2025-03-19 15:57:48 +08:00
|
|
|
|
return (
|
|
|
|
|
<div className="ag-theme-alpine w-full h-[calc(100vh-100px)]"
|
|
|
|
|
style={{
|
|
|
|
|
width: '100%',
|
|
|
|
|
borderRadius: '12px',
|
|
|
|
|
boxShadow: '0 4px 12px rgba(0, 0, 0, 0.1)'
|
|
|
|
|
}}
|
|
|
|
|
>
|
2025-03-19 21:33:26 +08:00
|
|
|
|
{!isLoading && (
|
2025-03-20 23:09:41 +08:00
|
|
|
|
<div className="flex items-center gap-4 mb-2">
|
|
|
|
|
<Button
|
|
|
|
|
onClick={handleConfirm}
|
|
|
|
|
className="bg-blue-500 text-white px-4 py-2 rounded hover:bg-blue-600"
|
2025-03-19 22:04:01 +08:00
|
|
|
|
>
|
2025-03-20 23:09:41 +08:00
|
|
|
|
导出Excel
|
|
|
|
|
</Button>
|
|
|
|
|
<Button
|
|
|
|
|
onClick={handleResetFilters}
|
|
|
|
|
className="bg-gray-500 text-white px-4 py-2 rounded hover:bg-gray-600"
|
|
|
|
|
>
|
|
|
|
|
重置筛选
|
|
|
|
|
</Button>
|
|
|
|
|
<div className="flex items-center gap-2">
|
|
|
|
|
<span className="text-gray-600">启用分页:</span>
|
|
|
|
|
<Switch
|
|
|
|
|
checked={paginationEnabled}
|
|
|
|
|
onChange={(checked) => setPaginationEnabled(checked)}
|
|
|
|
|
checkedChildren="开"
|
|
|
|
|
unCheckedChildren="关"
|
2025-03-19 22:04:01 +08:00
|
|
|
|
/>
|
|
|
|
|
</div>
|
2025-03-20 23:09:41 +08:00
|
|
|
|
</div>
|
|
|
|
|
)}
|
2025-03-19 21:33:26 +08:00
|
|
|
|
|
|
|
|
|
<Modal
|
|
|
|
|
title="输入文件名"
|
|
|
|
|
open={fileNameVisible}
|
|
|
|
|
onOk={handleFileNameConfirm}
|
|
|
|
|
onCancel={() => setFileNameVisible(false)}
|
|
|
|
|
okText="导出"
|
|
|
|
|
cancelText="取消"
|
|
|
|
|
>
|
2025-03-19 22:04:01 +08:00
|
|
|
|
<Input
|
2025-03-19 21:33:26 +08:00
|
|
|
|
placeholder={`默认名称: ${defaultFileName}`}
|
|
|
|
|
value={fileName}
|
|
|
|
|
onChange={(e) => setFileName(e.target.value)}
|
|
|
|
|
/>
|
|
|
|
|
</Modal>
|
2025-03-19 15:57:48 +08:00
|
|
|
|
{isLoading ? (
|
|
|
|
|
<div className="h-full flex items-center justify-center">
|
|
|
|
|
<div className="text-gray-600 text-xl">加载中...</div>
|
|
|
|
|
</div>
|
|
|
|
|
) : (
|
|
|
|
|
<AgGridReact
|
2025-03-20 23:09:41 +08:00
|
|
|
|
modules={[SetFilterModule, ClientSideRowModelModule]}
|
2025-03-19 21:33:26 +08:00
|
|
|
|
onGridReady={(params) => setGridApi(params.api)} // 添加gridApi回调
|
2025-03-19 15:57:48 +08:00
|
|
|
|
rowData={staffs}
|
|
|
|
|
columnDefs={columnDefs}
|
|
|
|
|
defaultColDef={{
|
|
|
|
|
...defaultColDef,
|
|
|
|
|
filterParams: {
|
|
|
|
|
textCustomComparator: (_, value) => value !== '',
|
|
|
|
|
}
|
|
|
|
|
}}
|
|
|
|
|
enableCellTextSelection={true}
|
2025-03-20 23:09:41 +08:00
|
|
|
|
pagination={paginationEnabled}
|
2025-03-19 15:57:48 +08:00
|
|
|
|
paginationAutoPageSize={true}
|
|
|
|
|
cacheQuickFilter={true}
|
|
|
|
|
/>
|
|
|
|
|
)}
|
|
|
|
|
</div>
|
|
|
|
|
);
|
|
|
|
|
}
|