Files
fe_supplier_frontend/src/components/EvaluateTaskPersonnelSelector/EvaluateTaskPersonnelSelector.tsx

186 lines
5.5 KiB
TypeScript
Raw Normal View History

2025-06-23 21:39:51 +08:00
import React, { useState, useEffect, useCallback, useMemo } from 'react';
2025-06-24 18:58:43 +08:00
import { Table, Input, Button, Space, message } from 'antd';
import { SearchOutlined } from '@ant-design/icons';
import { getUserList } from '@/servers/api/user';
2025-06-23 19:15:13 +08:00
import './EvaluateTaskPersonnelSelector.less';
const { Search } = Input;
/**
*
* @interface EvaluateTaskPersonnelSelectorProps
* @property {Function} onSelect -
2025-06-24 18:58:43 +08:00
* @property {API.PersonnelItem[]} selectedPersonnel -
2025-06-23 19:15:13 +08:00
*/
interface EvaluateTaskPersonnelSelectorProps {
2025-06-24 18:58:43 +08:00
onSelect: (personnel: API.PersonnelItem[]) => void; // 选择确认后的回调函数
selectedPersonnel?: API.PersonnelItem[]; // 已选择的人员列表(用于回显)
2025-06-23 19:15:13 +08:00
}
/**
*
2025-06-24 18:58:43 +08:00
*
2025-06-23 19:15:13 +08:00
*
* @component
* @example
* ```jsx
* <EvaluateTaskPersonnelSelector
* onSelect={(selected) => console.log('已选择人员:', selected)}
* selectedPersonnel={[]}
* />
* ```
*/
const EvaluateTaskPersonnelSelector: React.FC<EvaluateTaskPersonnelSelectorProps> = ({
onSelect,
selectedPersonnel = []
}) => {
// 搜索关键词
const [keyword, setKeyword] = useState<string>('');
2025-06-24 18:58:43 +08:00
2025-06-23 19:15:13 +08:00
// 所有可选人员列表
2025-06-24 18:58:43 +08:00
const [personnel, setPersonnel] = useState<API.PersonnelItem[]>([]);
2025-06-23 19:15:13 +08:00
// 已选择人员ID列表
const [selectedKeys, setSelectedKeys] = useState<string[]>([]);
2025-06-24 18:58:43 +08:00
// 加载状态
const [loading, setLoading] = useState<boolean>(false);
// 初始化时根据传入的selectedPersonnel设置选中状态
useEffect(() => {
// 直接使用传入的selectedPersonnel更新选中状态
// 如果为空数组,则清空选择
const newSelectedIds = selectedPersonnel?.map(item => item.id) || [];
setSelectedKeys(newSelectedIds);
}, [selectedPersonnel]); // 依赖selectedPersonnel而不是selectedPersonnelIds
2025-06-23 19:15:13 +08:00
/**
2025-06-24 18:58:43 +08:00
* API获取用户列表数据
2025-06-23 19:15:13 +08:00
*/
2025-06-24 18:58:43 +08:00
const fetchPersonnelData = useCallback(async () => {
setLoading(true);
try {
const params: API.UserListRequest = {
basePageRequest: {
pageNo: 1,
pageSize: 100, // 获取足够多的数据
},
keyword: keyword || undefined,
};
const response = await getUserList(params);
if (response && response.code === 200 && response.data) {
const users = response.data as API.UserItem[];
// 转换API返回的用户数据为组件所需格式
const personnelData: API.PersonnelItem[] = users.map((user) => ({
id: user.userId, // 用户ID
name: user.userName, // 用户名称
department: user.userDept, // 用户部门
position: '', // API中没有提供职位信息
}));
setPersonnel(personnelData);
} else {
message.error(response?.message || '获取用户列表失败');
}
} catch (error) {
console.error('获取人员数据失败:', error);
message.error('获取人员数据失败,请稍后重试');
} finally {
setLoading(false);
}
}, [keyword]); // 移除selectedPersonnelIds依赖
2025-06-23 21:39:51 +08:00
/**
2025-06-24 18:58:43 +08:00
*
2025-06-23 21:39:51 +08:00
*/
useEffect(() => {
2025-06-24 18:58:43 +08:00
// 加载人员数据API请求
2025-06-23 21:39:51 +08:00
fetchPersonnelData();
2025-06-24 18:58:43 +08:00
}, [fetchPersonnelData]);
2025-06-23 19:15:13 +08:00
/**
*
* @param {string} value -
*/
2025-06-24 18:58:43 +08:00
const handleSearch = (value: string) => {
2025-06-23 19:15:13 +08:00
setKeyword(value);
2025-06-24 18:58:43 +08:00
};
2025-06-23 19:15:13 +08:00
/**
2025-06-24 18:58:43 +08:00
*
* @param {string[]} selectedRowKeys - keys
* @param {API.PersonnelItem[]} selectedRows -
2025-06-23 19:15:13 +08:00
*/
2025-06-24 18:58:43 +08:00
const handleSelectChange = (selectedRowKeys: React.Key[], selectedRows: API.PersonnelItem[]) => {
setSelectedKeys(selectedRowKeys as string[]);
};
2025-06-23 19:15:13 +08:00
/**
2025-06-24 18:58:43 +08:00
*
2025-06-23 19:15:13 +08:00
*/
2025-06-24 18:58:43 +08:00
const handleConfirm = () => {
// 根据选中的ID筛选出完整的人员数据
const selectedData = personnel.filter(item => selectedKeys.includes(item.id));
// 回调传递给父组件
onSelect(selectedData);
};
// 表格列定义
const columns = [
{
title: '姓名', // 列标题
dataIndex: 'name', // 数据字段名
key: 'name', // 列唯一标识
},
{
title: '部门',
dataIndex: 'department',
key: 'department',
},
];
2025-06-23 19:15:13 +08:00
return (
<div className="evaluate-task-personnel-selector">
<div className="selector-header">
2025-06-24 18:58:43 +08:00
<div className="search-bar">
<Search
placeholder="请输入姓名搜索"
onSearch={handleSearch}
enterButton={<Button icon={<SearchOutlined />}></Button>}
/>
</div>
2025-06-23 19:15:13 +08:00
<div className="selected-count">
2025-06-24 18:58:43 +08:00
: <span className="count">{selectedKeys.length}</span>
2025-06-23 19:15:13 +08:00
</div>
</div>
2025-06-24 18:58:43 +08:00
<Table
rowSelection={{
selectedRowKeys: selectedKeys,
onChange: handleSelectChange,
}}
columns={columns}
dataSource={personnel}
rowKey="id"
size="small"
loading={loading}
pagination={{ pageSize: 10 }}
/>
2025-06-23 19:15:13 +08:00
<div className="selector-footer">
2025-06-24 18:58:43 +08:00
<Space>
<Button onClick={() => setSelectedKeys([])}></Button>
<Button type="primary" onClick={handleConfirm}>
</Button>
</Space>
2025-06-23 19:15:13 +08:00
</div>
</div>
);
};
export default EvaluateTaskPersonnelSelector;