diff --git a/apps/web/src/app/main/staffinfo_show/staffmessage_page.tsx b/apps/web/src/app/main/staffinfo_show/staffmessage_page.tsx index 90410a5..0b57f6e 100644 --- a/apps/web/src/app/main/staffinfo_show/staffmessage_page.tsx +++ b/apps/web/src/app/main/staffinfo_show/staffmessage_page.tsx @@ -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([]); const { useCustomFields, softDeleteByIds } = useStaff(); const fields = useCustomFields(); + const [isEditModalVisible, setIsEditModalVisible] = useState(false); + const [currentEditStaff, setCurrentEditStaff] = useState(null); // 获取数据 const { data: staffData } = api.staff.findMany.useQuery({ @@ -42,15 +43,14 @@ export default function StaffMessage() { department: true } } as any); - + // console.log(staffData); const actionColumns = [{ - field:"action", + field: "action", width: 50, checkboxSelection: true, 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 () => { @@ -109,21 +118,21 @@ export default function StaffMessage() { const rawValue = params.data.fieldValues?.find( (fv: any) => fv.fieldId === field.id )?.value; - + // 根据字段类型格式化 - switch(field.type) { + switch (field.type) { case 'cascader': return rawValue ? getAreaName(rawValue.split('/')) : ''; - + case 'date': // 格式化日期(假设存储的是ISO字符串) return rawValue ? new Date(rawValue).toLocaleDateString() : ''; - + case 'textarea': // 换行处理 - + return rawValue?.replace(/,/g, '\n'); - + default: return rawValue; } @@ -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 ( - <> - - -
-

人员总览

- setSelectedRows(e.api.getSelectedRows())} - rowSelection="multiple" - /> +
+
+ + +
+
- + +
+

人员总览

+ +
+ setSelectedRows(e.api.getSelectedRows())} + rowSelection="multiple" + className="rounded border border-gray-200" + headerHeight={40} + rowHeight={40} + domLayout="autoHeight" + /> +
+
+ + {/* 编辑弹窗 */} + setIsEditModalVisible(false)} + footer={null} + width={1000} + destroyOnClose={true} + > + {currentEditStaff && ( + + )} + ); } \ No newline at end of file diff --git a/apps/web/src/app/main/staffinfo_write/staffinfo_write.page.tsx b/apps/web/src/app/main/staffinfo_write/staffinfo_write.page.tsx index 8182a3d..ec99982 100644 --- a/apps/web/src/app/main/staffinfo_write/staffinfo_write.page.tsx +++ b/apps/web/src/app/main/staffinfo_write/staffinfo_write.page.tsx @@ -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([]); @@ -19,7 +28,10 @@ const StaffInfoWrite = () => { // 添加状态来跟踪每个文本区域的高度 const [textAreaHeights, setTextAreaHeights] = useState>({}); - + 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); - }; - - // 初始化时执行一次 - fieldChangeHandler(); - - // 不需要返回取消订阅,因为我们不再使用 subscribe - }, [form]); + if (initialData && fieldValues && fields) { + // 设置基础字段 + const formValues: any = { + showname: initialData.showname, + department: initialData.deptId + }; + + // 设置自定义字段值 + 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; + + // 根据字段类型转换值的格式 + 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,151 +215,107 @@ const StaffInfoWrite = () => { message.error("姓名不能为空"); return; } - // 创建基础员工记录 - console.log('准备创建用户,数据:', { showname: values.showname }); - const staff = await create.mutateAsync({ - data: { - showname: values.showname, - deptId: values.department? values.department : null, + + 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; // 如果基本信息更新失败,提前返回不继续处理 } - }); - 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 // 用户所属部门 - }); - // 过滤有效字段并转换值 - const validEntries = Object.entries(values) - .filter(([key, value]) => - key !== 'showname' && // 新增排除 showname - key !== 'username' && - key !== 'department' && - value !== undefined && - value !== null && - value !== '' - ) - .map(([fieldName, value]) => { - const field = fields && Array.isArray(fields) ? - fields.find((f: any) => f.name === fieldName) : undefined; - - // 处理特殊字段类型 - let processedValue = value; - if (field?.type === 'date') { //日期类型 - processedValue = (value as Date)?.toISOString(); - } else if (field?.type === 'cascader' && Array.isArray(value)) { //级联选择器 - processedValue = value?.join('/'); - }else if(field?.type === 'textarea'){ //多行文本 - processedValue = (value as string[])?.join(','); - } - - return { field, value: processedValue }; - }) - .filter(item => item.field?.id); - - // 批量提交自定义字段 - await Promise.all( - validEntries.map(({ field, value }) => - setCustomFieldValue.mutateAsync({ - staffId: staff.id, - fieldId: field.id, - value: String(value) - }) - ) - ); - 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}`); + } else { + // 创建模式 - 创建新员工 + console.log('准备创建用户,数据:', { showname: values.showname }); + try { + staff = await create.mutateAsync({ + data: { + showname: values.showname, + deptId: values.department ? values.department : null, + } + }); + } catch (error) { + console.error('创建员工记录失败:', error); + message.error("提交失败,请重试"); + setLoading(false); + return; // 如果创建失败,提前返回不继续处理 } - }); - // 根据字段分组记录 - 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 || '无'}`); - }); - - // 获取现有日志 - let currentLogs = []; + } + + // 只有在上面的操作成功后才继续处理自定义字段 try { - const storedLogs = localStorage.getItem('systemLogs'); - currentLogs = storedLogs ? JSON.parse(storedLogs) : []; + // 过滤有效字段并转换值 + const validEntries = Object.entries(values) + .filter(([key, value]) => + key !== 'showname' && + key !== 'username' && + key !== 'department' && + value !== undefined && + value !== null && + value !== '' + ) + .map(([fieldName, value]) => { + const field = fields && Array.isArray(fields) ? + fields.find((f: any) => f.name === fieldName) : undefined; + + // 处理特殊字段类型 + let processedValue = 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 = Array.isArray(value) ? value.join(',') : value; + } + + return { field, value: processedValue }; + }) + .filter(item => item.field?.id); + + // 批量提交自定义字段 + await Promise.all( + validEntries.map(({ field, value }) => + setCustomFieldValue.mutateAsync({ + staffId: staff.id, + fieldId: field.id, + value: String(value) + }) + ) + ); + + // 只有当所有操作都成功时才显示成功消息 + message.success(staffId ? "信息更新成功" : "信息提交成功"); + + // 关闭编辑模态窗口(如果在编辑模式) + if (staffId && setIsEditModalVisible) { + setIsEditModalVisible(false); + } + + // 如果有回调函数,调用它 + if (onComplete) { + onComplete(); + } else if (!staffId) { + // 如果是新建模式,重置表单 + form.resetFields(); + } } catch (error) { - console.error('读取系统日志失败', error); + console.error('设置自定义字段值失败:', error); } - - // 添加新日志(倒序添加,最新的在最前面) - const updatedLogs = [...logs.reverse(), ...currentLogs]; - - // 保存到 localStorage - localStorage.setItem('systemLogs', JSON.stringify(updatedLogs)); - - // 如果有全局变量,也更新它 - if (typeof window !== 'undefined') { - (window as any).globalLogs = updatedLogs; - } - - message.success("信息提交成功"); - form.resetFields(); } 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); }