add
This commit is contained in:
parent
dd513444c5
commit
652883d142
|
@ -1,11 +1,10 @@
|
|||
import { useState, useEffect, useMemo, useCallback } from 'react';
|
||||
import { AgGridReact } from 'ag-grid-react';
|
||||
import { api, useStaff } from "@nice/client";
|
||||
import 'ag-grid-community/styles/ag-grid.css';
|
||||
import 'ag-grid-community/styles/ag-theme-alpine.css';
|
||||
import { SetFilterModule } from 'ag-grid-enterprise';
|
||||
import { Button, CascaderProps, message } from 'antd';
|
||||
import { Button, CascaderProps, message, Modal } from 'antd';
|
||||
import { areaOptions } from '@web/src/app/main/staffinfo_write/area-options';
|
||||
import StaffInfoWrite from '@web/src/app/main/staffinfo_write/staffinfo_write.page';
|
||||
|
||||
function getAreaName(codes: string[], level?: number): string {
|
||||
const result: string[] = [];
|
||||
let currentLevel: CascaderProps['options'] = areaOptions;
|
||||
|
@ -25,6 +24,8 @@ export default function StaffMessage() {
|
|||
const [selectedRows, setSelectedRows] = useState<any[]>([]);
|
||||
const { useCustomFields, softDeleteByIds } = useStaff();
|
||||
const fields = useCustomFields();
|
||||
const [isEditModalVisible, setIsEditModalVisible] = useState(false);
|
||||
const [currentEditStaff, setCurrentEditStaff] = useState<any>(null);
|
||||
|
||||
// 获取数据
|
||||
const { data: staffData } = api.staff.findMany.useQuery({
|
||||
|
@ -42,7 +43,7 @@ export default function StaffMessage() {
|
|||
department: true
|
||||
}
|
||||
} as any);
|
||||
|
||||
// console.log(staffData);
|
||||
const actionColumns = [{
|
||||
field: "action",
|
||||
width: 50,
|
||||
|
@ -50,7 +51,6 @@ export default function StaffMessage() {
|
|||
headerCheckboxSelection: true,
|
||||
pinned: 'left'
|
||||
}]
|
||||
|
||||
// 新增编辑处理函数
|
||||
const handleEdit = useCallback(async () => {
|
||||
if (selectedRows.length === 0) return;
|
||||
|
@ -58,8 +58,17 @@ export default function StaffMessage() {
|
|||
message.error('只能选择一个员工进行编辑');
|
||||
return;
|
||||
}
|
||||
console.log(selectedRows[0]);
|
||||
setCurrentEditStaff(selectedRows[0]);
|
||||
setIsEditModalVisible(true);
|
||||
}, [selectedRows]);
|
||||
console.log('选中行',currentEditStaff);
|
||||
// 处理编辑完成
|
||||
const handleEditComplete = useCallback(() => {
|
||||
setIsEditModalVisible(false);
|
||||
setCurrentEditStaff(null);
|
||||
// 刷新表格数据
|
||||
api.staff.findMany.useQuery();
|
||||
}, []);
|
||||
|
||||
// 新增删除处理函数
|
||||
const handleDelete = useCallback(async () => {
|
||||
|
@ -131,7 +140,6 @@ export default function StaffMessage() {
|
|||
})),
|
||||
[fields.data]
|
||||
);
|
||||
|
||||
// 合并列定义
|
||||
useEffect(() => {
|
||||
setColumnDefs([...actionColumns, ...baseColumns, ...dynamicColumns]);
|
||||
|
@ -143,27 +151,58 @@ export default function StaffMessage() {
|
|||
}, [staffData]);
|
||||
|
||||
return (
|
||||
|
||||
<>
|
||||
<Button className='mr-2' danger onClick={handleDelete} style={{ marginBottom: '10px' }}>批量删除</Button>
|
||||
<Button type="primary" onClick={handleEdit} style={{ marginBottom: '10px' }}>编辑</Button>
|
||||
<div className="ag-theme-alpine" style={{ height: '100%', width: '100%', padding: '20px' }}>
|
||||
<h1 className="text-2xl mb-4">人员总览</h1>
|
||||
<div className="flex justify-between items-center mb-4">
|
||||
<div className="space-x-2">
|
||||
<Button className="bg-red-500 hover:bg-red-600 border-red-500 text-white rounded-md px-4 py-2"
|
||||
onClick={handleDelete}>批量删除</Button>
|
||||
<Button className="bg-blue-500 hover:bg-blue-600 border-blue-500 text-white rounded-md px-4 py-2"
|
||||
onClick={handleEdit}>编辑</Button>
|
||||
</div>
|
||||
<Button className="bg-gray-100 hover:bg-gray-200 border-gray-300 text-gray-700 rounded-md px-4 py-2"
|
||||
onClick={() => {
|
||||
}}>调试数据</Button>
|
||||
</div>
|
||||
|
||||
<div className="bg-white rounded-lg shadow-md p-6 mb-4">
|
||||
<h1 className="text-2xl font-bold text-gray-800 mb-4">人员总览</h1>
|
||||
|
||||
<div className="ag-theme-alpine w-full min-h-[480px] h-auto overflow-visible">
|
||||
<AgGridReact
|
||||
modules={[SetFilterModule]}
|
||||
rowData={rowData}
|
||||
columnDefs={columnDefs}
|
||||
|
||||
pagination={true}
|
||||
paginationPageSize={10}
|
||||
paginationPageSizeSelector={[10, 20, 50, 100]}
|
||||
onSelectionChanged={e => setSelectedRows(e.api.getSelectedRows())}
|
||||
rowSelection="multiple"
|
||||
className="rounded border border-gray-200"
|
||||
headerHeight={40}
|
||||
rowHeight={40}
|
||||
domLayout="autoHeight"
|
||||
/>
|
||||
</div>
|
||||
<Button onClick={() => {
|
||||
console.log('字段配置:', fields.data);
|
||||
console.log('员工数据:', staffData);
|
||||
}}>调试数据</Button>
|
||||
</div>
|
||||
|
||||
{/* 编辑弹窗 */}
|
||||
<Modal
|
||||
title="编辑员工信息"
|
||||
open={isEditModalVisible}
|
||||
onCancel={() => setIsEditModalVisible(false)}
|
||||
footer={null}
|
||||
width={1000}
|
||||
destroyOnClose={true}
|
||||
>
|
||||
{currentEditStaff && (
|
||||
<StaffInfoWrite
|
||||
staffId={currentEditStaff.id}
|
||||
initialData={currentEditStaff}
|
||||
fieldValues={currentEditStaff.fieldValues}
|
||||
onComplete={handleEditComplete}
|
||||
setIsEditModalVisible={setIsEditModalVisible}
|
||||
/>
|
||||
)}
|
||||
</Modal>
|
||||
</>
|
||||
);
|
||||
}
|
|
@ -5,11 +5,20 @@ import { areaOptions } from './area-options';
|
|||
import InfoCard from './infoCard';
|
||||
import DepartmentSelect from "@web/src/components/models/department/department-select";
|
||||
import { baseFields } from "@web/src/app/admin/staffinfo-manage/defaultFields";
|
||||
const StaffInfoWrite = () => {
|
||||
import dayjs from 'dayjs'; // 导入 dayjs
|
||||
|
||||
interface StaffInformationProps {
|
||||
staffId?: string; // 可选,编辑模式时提供
|
||||
onComplete?: () => void; // 可选,完成时的回调函数
|
||||
initialData?: any; // 可选,编辑模式时提供的初始数据
|
||||
fieldValues?: any[]; // 可选,编辑模式时提供的字段值数组
|
||||
setIsEditModalVisible?: (visible: boolean) => void; // 可选,编辑模式时提供的回调函数
|
||||
}
|
||||
const StaffInfoWrite = ({ staffId, onComplete, initialData, fieldValues, setIsEditModalVisible }: StaffInformationProps) => {
|
||||
const [form] = Form.useForm();
|
||||
const [loading, setLoading] = useState(false);
|
||||
// 修改使用的hook方法
|
||||
const { create, setCustomFieldValue, useCustomFields } = useStaff();
|
||||
const { create, update, setCustomFieldValue, useCustomFields } = useStaff();
|
||||
const { data: fields, isLoading: fieldsLoading } = useCustomFields();
|
||||
const [infoCards, setInfoCards] = useState<any[]>([]);
|
||||
|
||||
|
@ -19,7 +28,10 @@ const StaffInfoWrite = () => {
|
|||
|
||||
// 添加状态来跟踪每个文本区域的高度
|
||||
const [textAreaHeights, setTextAreaHeights] = useState<Record<string, number>>({});
|
||||
|
||||
const { data: staffData } = api.staff.findUnique.useQuery(
|
||||
{ where: { id: staffId } },
|
||||
{ enabled: !!staffId } // 只在 staffId 存在时执行查询
|
||||
);
|
||||
const handleAdd = (content: string[]) => {
|
||||
// 将数组内容展开为独立对象
|
||||
const newItems = content.map(text => ({ content: text }));
|
||||
|
@ -29,26 +41,51 @@ const StaffInfoWrite = () => {
|
|||
]);
|
||||
}
|
||||
|
||||
// 在组件中添加监听字段变化
|
||||
// 在组件挂载或依赖项变化时填充表单数据
|
||||
useEffect(() => {
|
||||
// 设置默认值
|
||||
form.setFieldsValue({
|
||||
hasTrain: false,
|
||||
hasCert: false
|
||||
});
|
||||
|
||||
// 使用 Form 的 onValuesChange 在外部监听
|
||||
const fieldChangeHandler = () => {
|
||||
const values = form.getFieldsValue(['hasTrain', 'hasCert']);
|
||||
setHasTrain(!!values.hasTrain);
|
||||
setHasCert(!!values.hasCert);
|
||||
if (initialData && fieldValues && fields) {
|
||||
// 设置基础字段
|
||||
const formValues: any = {
|
||||
showname: initialData.showname,
|
||||
department: initialData.deptId
|
||||
};
|
||||
|
||||
// 初始化时执行一次
|
||||
fieldChangeHandler();
|
||||
// 设置自定义字段值
|
||||
if (Array.isArray(fieldValues)) {
|
||||
fieldValues.forEach(fv => {
|
||||
// 添加类型断言确保 fields 是数组
|
||||
const field = Array.isArray(fields) ?
|
||||
fields.find((f: any) => f.id === fv.fieldId) : undefined;
|
||||
if (field) {
|
||||
let value = fv.value;
|
||||
|
||||
// 不需要返回取消订阅,因为我们不再使用 subscribe
|
||||
}, [form]);
|
||||
// 根据字段类型转换值的格式
|
||||
if (field.type === 'cascader' && value) {
|
||||
value = value.split('/');
|
||||
} else if (field.type === 'textarea' && value) {
|
||||
value = value.split(',');
|
||||
} else if (field.type === 'date' && value) {
|
||||
// 使用 dayjs 而不是 new Date 来处理日期
|
||||
value = value ? dayjs(value) : null;
|
||||
}
|
||||
|
||||
formValues[field.name] = value;
|
||||
|
||||
// 设置培训和鉴定状态
|
||||
if (field.name === 'hasTrain') {
|
||||
setHasTrain(value === '是');
|
||||
}
|
||||
if (field.name === 'hasCert') {
|
||||
setHasCert(value === '是');
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// 设置表单的值
|
||||
form.setFieldsValue(formValues);
|
||||
}
|
||||
}, [initialData, fieldValues, fields, form]);
|
||||
|
||||
// 按分组组织字段
|
||||
const fieldGroups = useMemo(() => {
|
||||
|
@ -169,7 +206,6 @@ const StaffInfoWrite = () => {
|
|||
}
|
||||
};
|
||||
const onFinish = async (e, values: any) => {
|
||||
// values.preventDefault();
|
||||
e.preventDefault()
|
||||
console.log(values)
|
||||
try {
|
||||
|
@ -179,36 +215,51 @@ const StaffInfoWrite = () => {
|
|||
message.error("姓名不能为空");
|
||||
return;
|
||||
}
|
||||
// 创建基础员工记录
|
||||
|
||||
let staff;
|
||||
|
||||
if (staffId) {
|
||||
// 编辑模式 - 更新现有员工
|
||||
console.log('准备更新用户,数据:', { id: staffId, showname: values.showname });
|
||||
try {
|
||||
staff = await update.mutateAsync({
|
||||
where: { id: staffId },
|
||||
data: {
|
||||
showname: values.showname,
|
||||
deptId: values.department || null,
|
||||
}
|
||||
});
|
||||
console.log('更新员工记录:', staff);
|
||||
} catch (error) {
|
||||
console.error('更新员工基本信息失败:', error);
|
||||
message.error("更新失败,请重试");
|
||||
setLoading(false);
|
||||
return; // 如果基本信息更新失败,提前返回不继续处理
|
||||
}
|
||||
} else {
|
||||
// 创建模式 - 创建新员工
|
||||
console.log('准备创建用户,数据:', { showname: values.showname });
|
||||
const staff = await create.mutateAsync({
|
||||
try {
|
||||
staff = await create.mutateAsync({
|
||||
data: {
|
||||
showname: values.showname,
|
||||
deptId: values.department ? values.department : null,
|
||||
}
|
||||
});
|
||||
console.log('创建员工记录:', staff);
|
||||
// 创建系统日志记录
|
||||
await api.systemLog.create.mutateAsync({
|
||||
level: "info",
|
||||
module: "人员管理",
|
||||
action: "创建用户",
|
||||
targetId: staff.id,
|
||||
targetName: staff.username,
|
||||
message: `[${new Date().toLocaleString()}] 用户 ${staff.username} 的人员信息已成功添加`,
|
||||
details: {
|
||||
fields: validEntries.map(({ field, value }) => ({
|
||||
name: field.label,
|
||||
value
|
||||
}))
|
||||
},
|
||||
status: "success",
|
||||
departmentId: staff.deptId // 用户所属部门
|
||||
});
|
||||
} catch (error) {
|
||||
console.error('创建员工记录失败:', error);
|
||||
message.error("提交失败,请重试");
|
||||
setLoading(false);
|
||||
return; // 如果创建失败,提前返回不继续处理
|
||||
}
|
||||
}
|
||||
|
||||
// 只有在上面的操作成功后才继续处理自定义字段
|
||||
try {
|
||||
// 过滤有效字段并转换值
|
||||
const validEntries = Object.entries(values)
|
||||
.filter(([key, value]) =>
|
||||
key !== 'showname' && // 新增排除 showname
|
||||
key !== 'showname' &&
|
||||
key !== 'username' &&
|
||||
key !== 'department' &&
|
||||
value !== undefined &&
|
||||
|
@ -221,12 +272,12 @@ const StaffInfoWrite = () => {
|
|||
|
||||
// 处理特殊字段类型
|
||||
let processedValue = value;
|
||||
if (field?.type === 'date') { //日期类型
|
||||
processedValue = (value as Date)?.toISOString();
|
||||
} else if (field?.type === 'cascader' && Array.isArray(value)) { //级联选择器
|
||||
if (field?.type === 'date') {
|
||||
processedValue = (value as any)?.format?.('YYYY-MM-DD') || value;
|
||||
} else if (field?.type === 'cascader' && Array.isArray(value)) {
|
||||
processedValue = value?.join('/');
|
||||
}else if(field?.type === 'textarea'){ //多行文本
|
||||
processedValue = (value as string[])?.join(',');
|
||||
} else if(field?.type === 'textarea'){
|
||||
processedValue = Array.isArray(value) ? value.join(',') : value;
|
||||
}
|
||||
|
||||
return { field, value: processedValue };
|
||||
|
@ -243,87 +294,28 @@ const StaffInfoWrite = () => {
|
|||
})
|
||||
)
|
||||
);
|
||||
console.log('自定义字段提交成功', staff.username);
|
||||
// 记录系统日志 - 用户创建成功
|
||||
const timestamp = new Date().toLocaleString();
|
||||
const logs = [];
|
||||
// 记录用户创建
|
||||
logs.push(`${timestamp} - 用户创建成功:${staff.username}`);
|
||||
// 记录人员信息添加
|
||||
logs.push(`[${timestamp}] 用户 ${staff.username} 的人员信息已成功添加`);
|
||||
// 记录每个字段的详细信息
|
||||
validEntries.forEach(({ field, value }) => {
|
||||
if (field && field.label && value) {
|
||||
logs.push(`[${timestamp}] 提交的数据: ${field.label}=${value}`);
|
||||
}
|
||||
});
|
||||
// 根据字段分组记录
|
||||
const fieldsByGroup = validEntries.reduce((groups, { field, value }) => {
|
||||
if (field && field.group && value) {
|
||||
if (!groups[field.group]) {
|
||||
groups[field.group] = [];
|
||||
}
|
||||
groups[field.group].push({ field, value });
|
||||
}
|
||||
return groups;
|
||||
}, {});
|
||||
|
||||
// 为每个分组记录信息
|
||||
Object.entries(fieldsByGroup).forEach(([groupName, fields]) => {
|
||||
const groupValues = (fields as any[]).map(f => `${f.field.label}=${f.value}`).join(', ');
|
||||
logs.push(`[${timestamp}] ${staff.username} 的${groupName}:${groupValues || '无'}`);
|
||||
});
|
||||
// 只有当所有操作都成功时才显示成功消息
|
||||
message.success(staffId ? "信息更新成功" : "信息提交成功");
|
||||
|
||||
// 获取现有日志
|
||||
let currentLogs = [];
|
||||
try {
|
||||
const storedLogs = localStorage.getItem('systemLogs');
|
||||
currentLogs = storedLogs ? JSON.parse(storedLogs) : [];
|
||||
} catch (error) {
|
||||
console.error('读取系统日志失败', error);
|
||||
// 关闭编辑模态窗口(如果在编辑模式)
|
||||
if (staffId && setIsEditModalVisible) {
|
||||
setIsEditModalVisible(false);
|
||||
}
|
||||
|
||||
// 添加新日志(倒序添加,最新的在最前面)
|
||||
const updatedLogs = [...logs.reverse(), ...currentLogs];
|
||||
|
||||
// 保存到 localStorage
|
||||
localStorage.setItem('systemLogs', JSON.stringify(updatedLogs));
|
||||
|
||||
// 如果有全局变量,也更新它
|
||||
if (typeof window !== 'undefined') {
|
||||
(window as any).globalLogs = updatedLogs;
|
||||
}
|
||||
|
||||
message.success("信息提交成功");
|
||||
// 如果有回调函数,调用它
|
||||
if (onComplete) {
|
||||
onComplete();
|
||||
} else if (!staffId) {
|
||||
// 如果是新建模式,重置表单
|
||||
form.resetFields();
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('设置自定义字段值失败:', error);
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('提交出错:', error);
|
||||
|
||||
// 记录错误日志
|
||||
const timestamp = new Date().toLocaleString();
|
||||
const logMessage = `${timestamp} - 创建用户失败:${values.username || '未知用户'}, 错误: ${error.message || '未知错误'}`;
|
||||
|
||||
// 获取现有日志
|
||||
let currentLogs = [];
|
||||
try {
|
||||
const storedLogs = localStorage.getItem('systemLogs');
|
||||
currentLogs = storedLogs ? JSON.parse(storedLogs) : [];
|
||||
} catch (err) {
|
||||
console.error('读取系统日志失败', err);
|
||||
}
|
||||
|
||||
// 添加新日志
|
||||
const updatedLogs = [logMessage, ...currentLogs];
|
||||
|
||||
// 保存到 localStorage
|
||||
localStorage.setItem('systemLogs', JSON.stringify(updatedLogs));
|
||||
|
||||
// 如果有全局变量,也更新它
|
||||
if (typeof window !== 'undefined') {
|
||||
(window as any).globalLogs = updatedLogs;
|
||||
}
|
||||
|
||||
message.error("提交失败,请重试");
|
||||
message.error(staffId ? "更新失败,请重试" : "提交失败,请重试");
|
||||
} finally {
|
||||
setLoading(false);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue