'use client'; 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'; 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'; import { utils, writeFile } from 'xlsx'; import { Modal, Input, Button } from 'antd'; import { api } from '@nice/client'; import { StaffDto } from 'packages/common/dist'; import DepartmentSelect from '@web/src/components/models/department/department-select'; // 修改函数类型定义 function getAreaName(codes: string[], level?: number): string { const result: string[] = []; let currentLevel: CascaderProps['options'] = areaOptions; 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; // 添加层级控制 } return level ? result[level - 1] || '' : result.join(' / ') || codes.join('/'); } export default function StaffTable() { const { data: staffs, isLoading } = api.staff.findMany.useQuery({ where: { deletedAt: null }, include: { // 添加关联查询 department: true } }); const [gridApi, setGridApi] = useState(null); // 添加gridApi状态 const [confirmVisible, setConfirmVisible] = useState(false); const [fileNameVisible, setFileNameVisible] = useState(false); const [fileName, setFileName] = useState(''); const [defaultFileName] = useState(`员工数据_${new Date().toISOString().slice(0, 10)}`); const [exporting, setExporting] = useState(false); const [selectedDepartment, setSelectedDepartment] = useState(''); const [tempExportData, setTempExportData] = useState(null); const [exportScope, setExportScope] = useState<'current' | 'department'>('current'); const handleExport = async () => { setConfirmVisible(true); }; const handleConfirm = async () => { setConfirmVisible(false); setExporting(true); if (exportScope === 'current') { setExporting(false); try { const allStaffs = await api.staff.findMany.useQuery({ where: { deletedAt: null, department: { name: selectedDepartment } // 添加部门过滤条件 }, include: { department: true } }); setTempExportData(allStaffs); } finally { setExporting(false); } } setFileNameVisible(true); }; // 添加导出处理函数 const handleFileNameConfirm = () => { setFileNameVisible(false) if (!tempExportData) return; if (!gridApi) return; const finalFileName = fileName || defaultFileName; const flattenColumns = (cols: any[]): any[] => { return cols.flatMap(col => col.children ? flattenColumns(col.children) : col ); }; const allColDefs = flattenColumns(gridApi.getColumnDefs()); let rowData; if (exportScope === 'current') { rowData = gridApi.getDisplayedRowNodes().map((node: any) => node.data) || []; } else { rowData = tempExportData || []; } rowData.map((node: any) => { const row: Record = {}; allColDefs.forEach((colDef: any) => { const field = colDef.field; if (field) { const value = node.data[field]; const formatter = colDef.valueFormatter; const renderer = colDef.cellRenderer; let renderedValue = value; if (formatter) { renderedValue = formatter({ value }); } else if (renderer) { const renderResult = renderer({ value }); // 改进渲染结果处理 if (typeof renderResult === 'string') { renderedValue = renderResult; } else if (renderResult?.props?.children) { // 处理React元素文本内容 renderedValue = String(renderResult.props.children); } else if (renderResult?.props?.dangerouslySetInnerHTML?.__html) { const html = renderResult.props.dangerouslySetInnerHTML.__html; renderedValue = html.replace(//gi, '\n'); } } // 增强布尔值处理逻辑 if (typeof renderedValue === 'boolean' || (typeof renderedValue === 'string' && ['true', 'false'].includes(renderedValue.toLowerCase()))) { const boolValue = typeof renderedValue === 'boolean' ? renderedValue : renderedValue.toLowerCase() === 'true'; renderedValue = boolValue ? '是' : '否'; } row[colDef.headerName] = renderedValue; } }); return row; }); // 创建工作表并导出 const ws = utils.json_to_sheet(rowData); const wb = utils.book_new(); utils.book_append_sheet(wb, ws, "Sheet1"); // 修改导出文件名生成方式 writeFile(wb, `${fileName || '未命名数据'}.xlsx`); }; const columnDefs: (ColDef | ColGroupDef)[] = [ { field: 'username', headerName: '姓名', minWidth: 120, pinned: 'left', // floatingFilter: true // 确保启用浮动过滤器 }, { headerName: '个人基本信息', children: [ { field: 'idNumber', headerName: '身份证号', minWidth: 180, }, { field: 'type', headerName: '人员类型', minWidth: 120, }, { field: 'officerId', headerName: '警号', minWidth: 120 }, { field: 'phoneNumber', headerName: '手机号', minWidth: 130 }, { field: 'age', headerName: '年龄', minWidth: 80 }, { field: 'sex', headerName: '性别', minWidth: 80, cellRenderer: (params: any) => params.value ? '男' : '女' }, { field: 'bloodType', headerName: '血型', minWidth: 80 }, { field: 'birthplace', headerName: '籍贯', minWidth: 200, valueFormatter: (params) => params.value ? getAreaName(params.value.split('/')) : '', }, { field: 'source', headerName: '来源', minWidth: 120 }, ] }, { headerName: '政治信息', children: [ { field: 'politicalStatus', headerName: '政治面貌', minWidth: 150 }, { field: 'partyPosition', headerName: '党内职务', minWidth: 120 } ] }, { headerName: '职务信息', children: [ { field: 'department.name', headerName: '所属部门', minWidth: 200 }, { field: 'rank', headerName: '衔职级别', minWidth: 120 }, { field: 'rankDate', headerName: '衔职时间', minWidth: 120, valueFormatter: (params: any) => params.value ? new Date(params.value).toLocaleDateString() : '' }, { field: 'proxyPosition', headerName: '代理职务', minWidth: 120 } ] }, { headerName: '入职信息', children: [ { 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() : '' }, { field: 'sourceType', headerName: '来源类型', minWidth: 120 }, { 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() : '' } ] }, { headerName: '教育背景', children: [ { field: 'education', headerName: '学历', minWidth: 100 }, { field: 'educationType', headerName: '学历形式', minWidth: 120 }, { field: 'isGraduated', headerName: '是否毕业', minWidth: 100, cellRenderer: (params: any) => params.value ? '是' : '否' }, { field: 'major', headerName: '专业', minWidth: 150 }, { field: 'foreignLang', headerName: '外语能力', minWidth: 120 } ] }, { headerName: '培训信息', children: [ { field: 'trainType', headerName: '培训类型', minWidth: 120 }, { field: 'trainInstitute', headerName: '培训机构', minWidth: 150 }, { field: 'trainMajor', headerName: '培训专业', minWidth: 150 }, { field: 'hasTrain', headerName: '是否参加培训', minWidth: 120, cellRenderer: (params: any) => params.value ? '是' : '否' } ] }, { headerName: '鉴定信息', children: [ { field: 'certRank', headerName: '鉴定等级', minWidth: 120 }, { field: 'certWork', headerName: '鉴定工种', minWidth: 120 }, { field: 'hasCert', headerName: '是否参加鉴定', minWidth: 120, cellRenderer: (params: any) => params.value ? '是' : '否' } ] }, { headerName: '工作信息', children: [ { field: 'equipment', headerName: '操作维护装备', minWidth: 150, cellRenderer: (params: any) => (
') || '' }} /> ), autoHeight: true }, { field: 'projects', headerName: '演训任务经历', minWidth: 150, cellRenderer: (params: any) => (
') || '' }} /> ), autoHeight: true }, // 修改剩余两个字段的cellRenderer为相同结构 { field: 'awards', headerName: '奖励信息', minWidth: 150, cellRenderer: (params: any) => (
') || '' }} /> ), autoHeight: true }, { field: 'punishments', headerName: '处分信息', minWidth: 150, cellRenderer: (params: any) => (
') || '' }} /> ), autoHeight: true } ] } ]; const defaultColDef: ColDef = { sortable: true, filter: 'agSetColumnFilter', resizable: false, flex: 1, minWidth: 150, maxWidth: 600, suppressMovable: true, cellStyle: { whiteSpace: 'normal', overflowWrap: 'break-word' }, wrapText: true, autoHeight: true }; return (
{!isLoading && ( )} setConfirmVisible(false)} okText="确认" cancelText="取消" >
导出范围:
{exportScope === 'department' && (

部门名称:

setSelectedDepartment(value)} placeholder="请选择部门" />
)}
setFileNameVisible(false)} okText="导出" cancelText="取消" > setFileName(e.target.value)} /> {isLoading ? (
加载中...
) : ( setGridApi(params.api)} // 添加gridApi回调 rowData={staffs} columnDefs={columnDefs} defaultColDef={{ ...defaultColDef, filterParams: { textCustomComparator: (_, value) => value !== '', } }} enableCellTextSelection={true} pagination={true} paginationAutoPageSize={true} cacheQuickFilter={true} /> )}
); }