import { postOrderErpTicketsUpload, postProcureBillAddOrModify, } from '@/services'; import { useModel } from '@@/exports'; import { UploadOutlined } from '@ant-design/icons'; import { ActionType, EditableProTable, ModalForm, ProCard, ProColumns, ProForm, ProFormDependency, ProFormField, ProFormSwitch, ProFormTextArea, } from '@ant-design/pro-components'; import { Button, Form, Upload, message } from 'antd'; import React, { useEffect, useRef, useState } from 'react'; export default ({ record, onfinish }) => { const [editableKeys, setEditableRowKeys] = useState<React.Key[]>([]); const [controlled, setControlled] = useState<boolean>(false); const [processedRecord, setProcessedRecord] = useState(record); const formRef = useRef(null); const editorFormRef = useRef(null); const { getProducts } = useModel('enum'); const actionRef = useRef<ActionType>(); // 使用 useEffect 为 procureBillDetailList 中的每个元素添加 key useEffect(() => { if (record?.procureBillDetailList) { const updatedProcureBillDetailList = record.procureBillDetailList.map( (item) => ({ ...item, key: item.key || `key-${Math.random().toString(36).substr(2, 9)}`, // 动态生成唯一 key }), ); setProcessedRecord({ ...record, procureBillDetailList: updatedProcureBillDetailList, }); } }, [record]); const columns: ProColumns[] = [ { title: '商品', dataIndex: 'productId', valueType: 'select', request: async () => { const res = await getProducts(); return res.map((item) => ({ ...item, label: item.name, value: item.id, productUnitName: item.baseUnitName, productUnitPrice: item.unitPrice, })); }, fieldProps: (_, { rowIndex }) => ({ onSelect: (value, option) => { console.log('option111111' + JSON.stringify(option)); const currentTableData = editorFormRef.current?.getRowsData?.(); if (currentTableData) { const updatedData = [...currentTableData]; updatedData[rowIndex] = { ...updatedData[rowIndex], productUnitName: option.productUnitName, productUnitPrice: option.productUnitPrice, }; formRef.current?.setFieldsValue({ procureBillDetailList: updatedData, }); } }, }), }, { title: '单位', dataIndex: 'productUnitName', valueType: 'text', editable: false, }, { title: '单价', dataIndex: 'productUnitPrice', valueType: 'digit', editable: false, }, { title: '数量', dataIndex: 'number', valueType: 'digit', }, { title: '备注', dataIndex: 'notes', valueType: 'textarea', }, { title: '附件', dataIndex: 'annexUpload', renderFormItem: (_, { record }) => ( <Upload fileList={ record.annexList?.map((url) => ({ uid: url, name: url.split('/').pop(), status: 'done', url, })) || [] } onPreview={(file) => { window.open(file.url || file.thumbUrl); // 打开文件预览 }} customRequest={async (options) => { const { file, onSuccess, onError } = options; const formData = new FormData(); formData.append('file', file); try { const res = await postOrderErpTicketsUpload({ data: formData, headers: { 'Content-Type': 'multipart/form-data' }, }); if (res.message === '成功') { message.success(`${file.name} 上传成功`); // 更新文件列表 const currentData = formRef.current?.getFieldValue( 'procureBillDetailList', ); const currentRow = currentData.find( (row) => row.key === record.key, ); const existingAnnex = currentRow?.annexList || []; // 取现有的 annex 数据 const updatedAnnex = [...existingAnnex, res.data]; // 合并新的文件 URL // 更新表单数据 const updatedData = currentData.map((row) => row.key === record.key ? { ...row, annexList: updatedAnnex } : row, ); formRef.current?.setFieldValue( 'procureBillDetailList', updatedData, ); onSuccess?.('上传成功'); } else { message.error(`${file.name} 上传失败`); onError?.(new Error('上传失败')); } } catch (error) { message.error(`${file.name} 上传错误`); onError?.(error); } }} onRemove={(file) => { const currentData = formRef.current?.getFieldValue('procureBillDetailList') || []; const updatedData = currentData.map((row) => { if (row.key === record.key) { return { ...row, annexList: row.annexList.filter((url) => url !== file.url), // 移除对应文件 URL }; } return row; }); formRef.current?.setFieldsValue({ procureBillDetailList: updatedData, }); // 触发状态更新 setProcessedRecord((prevRecord) => ({ ...prevRecord, procureBillDetailList: updatedData, })); }} > <Button icon={<UploadOutlined />}>上传附件</Button> </Upload> ), render: (_, record) => ( <div> {record.annexList?.map((url, index) => { const shortName = url.split('/').pop()?.slice(0, 15) || `附件 ${index + 1}`; return ( <a key={index} href={url} target="_blank" rel="noopener noreferrer" title={url} // 悬停显示完整链接 style={{ display: 'block', marginBottom: '4px', whiteSpace: 'nowrap', overflow: 'hidden', textOverflow: 'ellipsis', maxWidth: '200px', // 限制显示宽度 }} > {shortName.length < url.split('/').pop()?.length ? `${shortName}...` : shortName} </a> ); })} </div> ), }, { title: '附件', hideInTable: true, dataIndex: 'annexList', }, { title: '操作', valueType: 'option', render: (text, record, _, action) => [ <a key="editable" onClick={() => { action?.startEditable?.(record.key); }} > 编辑 </a>, <a key="delete" onClick={() => { const tableDataSource = formRef.current?.getFieldValue( 'procureBillDetailList', ); formRef.current?.setFieldsValue({ table: tableDataSource.filter((item) => item.key !== record.key), }); }} > 删除 </a>, ], }, ]; const [form] = Form.useForm(); return ( <ModalForm formRef={formRef} initialValues={processedRecord} validateTrigger="onBlur" title="新建表单" trigger={ record?.id ? ( <Button type="link">修改</Button> ) : ( <Button type="primary">新建</Button> ) } form={form} autoFocusFirstInput width={1500} modalProps={{ destroyOnClose: true, onCancel: () => console.log('run'), }} submitTimeout={2000} onFinish={async (values) => { const res = await postProcureBillAddOrModify({ data: { ...record, ...values, }, }); if (res) { message.success(res.message); onfinish(); } return true; }} > <EditableProTable rowKey="key" scroll={{ x: 960, }} editableFormRef={editorFormRef} headerTitle="可编辑表格" maxLength={5} name="procureBillDetailList" controlled={controlled} recordCreatorProps={{ position: 'bottom', record: () => ({ key: `key-${Math.random().toString(36).substr(2, 9)}`, }), }} actionRef={actionRef} toolBarRender={() => [ <ProFormSwitch key="render" fieldProps={{ style: { marginBlockEnd: 0, }, checked: controlled, onChange: (value) => { setControlled(value); }, }} checkedChildren="数据更新通知 Form" unCheckedChildren="保存后通知 Form" noStyle />, <Button key="rows" onClick={() => { const rows = editorFormRef.current?.getRowsData?.(); console.log(rows); }} > 获取 table 的数据 </Button>, ]} columns={columns} editable={{ type: 'multiple', editableKeys, onChange: setEditableRowKeys, actionRender: (row, config, defaultDom) => { return [defaultDom.save, defaultDom.delete, defaultDom.cancel]; }, }} /> <ProForm.Item> <ProCard title="表格数据" headerBordered collapsible defaultCollapsed> <ProFormDependency name={['procureBillDetailList']}> {({ procureBillDetailList }) => ( <ProFormField ignoreFormItem fieldProps={{ style: { width: '100%', }, }} mode="read" valueType="jsonCode" text={JSON.stringify(procureBillDetailList)} /> )} </ProFormDependency> </ProCard> </ProForm.Item> <ProFormTextArea name="notes" label="备注" /> </ModalForm> ); };