training_data/apps/web/src/app/main/staffpage/stafftable/page.tsx

227 lines
8.5 KiB
TypeScript
Raw Normal View History

2025-03-24 20:16:37 +08:00
import { Button, Select, Table, Modal } from "antd"
2025-03-12 11:45:18 +08:00
import { StaffDto } from "@nice/common";
import { useStaff, api } from "@nice/client";
import { useEffect, useState } from "react";
import toast from "react-hot-toast";
import React from "react";
import { useMainContext } from "../../layout/MainProvider";
2025-03-24 20:16:37 +08:00
import { render } from "react-dom";
// 提取处理嵌套字段的函数
const getNestedValue = (record: any, dataIndex: string | string[]) => {
if (Array.isArray(dataIndex)) {
return dataIndex.reduce((obj, key) => obj?.[key], record);
}
return record[dataIndex];
};
2025-03-12 11:45:18 +08:00
export default function StaffTable() {
const{form, setVisible,searchValue} = useMainContext()
const { data: staffs, isLoading } = api.staff.findMany.useQuery({
where: {
2025-03-24 20:16:37 +08:00
deletedAt: null,
2025-03-12 11:45:18 +08:00
username: {
contains: searchValue
}
2025-03-24 20:16:37 +08:00
},
include: {
department: true,
position: true,
trainSituations: {
include: {
trainContent: {
select: {
id: true,
title: true
}
}
}
}
2025-03-12 11:45:18 +08:00
}
});
2025-03-24 20:16:37 +08:00
useEffect(() => {
console.log(staffs);
}, [staffs]);
const { softDeleteByIds } = useStaff();
2025-03-12 11:45:18 +08:00
const {editingRecord, setEditingRecord} = useMainContext();
2025-03-24 20:16:37 +08:00
const [isTrainingModalVisible, setIsTrainingModalVisible] = useState(false);
const [selectedTrainings, setSelectedTrainings] = useState([]);
const showTrainingDetails = (situations) => {
setSelectedTrainings(situations);
setIsTrainingModalVisible(true);
};
// 修正拼写错误
const columns = [
2025-03-12 11:45:18 +08:00
{
title: "姓名",
dataIndex: "username",
key: "username",
},
{
title: "部门",
2025-03-24 20:16:37 +08:00
dataIndex: ["department", "name"],
2025-03-12 11:45:18 +08:00
key: "deptId",
2025-03-24 20:16:37 +08:00
render: (_, record) => record.department?.name || "无部门"
2025-03-12 11:45:18 +08:00
},
{
title: "职务",
2025-03-24 20:16:37 +08:00
dataIndex: ["position", "type"],
key: "position",
render: (_, record) => record.position?.type || "无职务"
2025-03-12 11:45:18 +08:00
},
{
title: "在位",
dataIndex: "absent",
key: "absent",
2025-03-24 20:16:37 +08:00
render: (absent) => absent === null ? "未知" : absent ? "否" : "是"
2025-03-12 11:45:18 +08:00
},
{
2025-03-24 20:16:37 +08:00
title: "培训情况",
dataIndex: "trainSituations",
key: "trainSituations",
render: (situations) => {
if (!situations?.length) return "无培训记录";
return (
<div>
{situations.slice(0, 2).map((s) => (
<div key={s.id} className="mb-1">
<span>{s.trainContent?.title}: </span>
<span> {s.alreadyTrainTime}/{s.mustTrainTime} </span>
</div>
))}
{situations.length > 2 && (
<span
className="text-blue-500 cursor-pointer hover:underline"
onClick={() => showTrainingDetails(situations)}
>
{situations.length - 2}
</span>
)}
</div>
);
}
2025-03-12 11:45:18 +08:00
},
{
title: "操作",
key: "action",
render: (_, record) => (
2025-03-24 20:16:37 +08:00
<div className="flex space-x-2">
<Button
type="primary"
key={record.id}
onClick={() => handleEdit(record)}
>
</Button>
<Button
danger
onClick={async () => {
if (confirm("确定要删除该员工吗?")) {
try {
await softDeleteByIds.mutateAsync({
ids: [record.id],
});
toast.success("删除成功");
} catch (error) {
// 添加更详细的错误日志
console.error('删除员工时出错:', error);
toast.error("删除失败");
}
}
}}
>
</Button>
</div>
2025-03-12 11:45:18 +08:00
),
}
];
useEffect(() => {
if (editingRecord) {
form.setFieldsValue(editingRecord);
console.log(editingRecord);
}
}, [editingRecord]);
const handleEdit = (record) => {
setEditingRecord(record);
2025-03-24 20:16:37 +08:00
form.setFieldsValue(record); // 修正为设置当前记录的值
2025-03-12 11:45:18 +08:00
setVisible(true);
};
return (
<>
{
isLoading ? (<div>...</div>) :
(
<Table
key={"username"}
2025-03-24 20:16:37 +08:00
columns={columns}
2025-03-12 11:45:18 +08:00
dataSource={staffs}
tableLayout="fixed"
pagination={{
position: ["bottomCenter"],
className: "flex justify-center mt-4",
2025-03-24 20:16:37 +08:00
pageSize: 10,
2025-03-12 11:45:18 +08:00
}}
>
2025-03-24 20:16:37 +08:00
<thead >
2025-03-12 11:45:18 +08:00
<tr>
2025-03-24 20:16:37 +08:00
{columns.map((column) => (
2025-03-12 11:45:18 +08:00
<th
key={column.key}
>
{column.title}
</th>
))}
</tr>
</thead>
<tbody>
{staffs?.map((record) => (
<tr
key={record.id}
>
2025-03-24 20:16:37 +08:00
{columns.map((column) => (
// 使用提取的函数处理嵌套字段
<td key={column.key}>
{column.render?.(
getNestedValue(record, column.dataIndex),
record
) || getNestedValue(record, column.dataIndex)}
2025-03-12 11:45:18 +08:00
</td>
))}
</tr>
))}
</tbody>
</Table>
)
}
2025-03-24 20:16:37 +08:00
<Modal
title="培训详情"
open={isTrainingModalVisible}
onCancel={() => setIsTrainingModalVisible(false)}
footer={null}
width={600}
>
<div className="max-h-96 overflow-y-auto">
{selectedTrainings.map((training) => (
<div key={training.id} className="mb-4 p-4 border rounded">
<h3 className="font-bold mb-2">{training.trainContent?.title}</h3>
<div className="grid grid-cols-2 gap-4">
<div>: {training.mustTrainTime} </div>
<div>: {training.alreadyTrainTime} </div>
<div>: {((training.alreadyTrainTime / training.mustTrainTime) * 100).toFixed(1)}%</div>
{/* <div>得分: {training.score}</div> */}
</div>
</div>
))}
</div>
</Modal>
2025-03-12 11:45:18 +08:00
</>
);
}