From 386bf8b4d3ac6c6637f40861ed42aab056a11905 Mon Sep 17 00:00:00 2001 From: z <2199297992@qq.com> Date: Tue, 21 Jan 2025 11:40:29 +0800 Subject: [PATCH] feat(product): 优化采购管理功能 --- src/pages/product/procure/index.tsx | 145 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++------------------------ src/pages/product/productCollect/components/AddOrUpdate.tsx | 242 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-------------------------------------------------- 2 files changed, 313 insertions(+), 74 deletions(-) diff --git a/src/pages/product/procure/index.tsx b/src/pages/product/procure/index.tsx index baa87e5..5d873d9 100644 --- a/src/pages/product/procure/index.tsx +++ b/src/pages/product/procure/index.tsx @@ -1,15 +1,27 @@ import ButtonConfirm from '@/components/ButtomConfirm'; import { RESPONSE_CODE } from '@/constants/enum'; import AddOrUpdate from '@/pages/product/procure/components/AddOrUpdate'; -import { postProcureBillDelete, postProcureBillPage } from '@/services'; +import { + postProcureBillDelete, + postProcureBillPage, + postServiceConstProcureBillAuditStatus, +} from '@/services'; +import { enumToSelect } from '@/utils'; import { ProTable, type ActionType } from '@ant-design/pro-components'; import { message } from 'antd'; import { useRef } from 'react'; +import Audit from './components/Audit'; export default () => { const actionRef = useRef<ActionType>(); const columns = [ { + title: '单号', + dataIndex: 'id', + ellipsis: true, + hideInSearch: true, + }, + { title: '创建时间', dataIndex: 'createTime', ellipsis: true, @@ -52,32 +64,84 @@ export default () => { hideInSearch: true, }, { + title: '采购单号', + dataIndex: 'id', + ellipsis: true, + hideInTable: true, + }, + { + title: '创建人', + dataIndex: 'createByNameLike', + ellipsis: true, + hideInTable: true, + }, + { + title: '创建时间', + valueType: 'dateTimeRange', + hideInTable: true, + search: { + transform: (value) => { + if (value) { + return { + createTimeGe: value[0], + createTimeLe: value[1], + }; + } + }, + }, + }, + { + title: '审核状态', + valueType: 'select', + key: 'auditStatus', + dataIndex: 'auditStatus', + filters: true, + onFilter: true, + hideInTable: true, + request: async () => { + const res = await postServiceConstProcureBillAuditStatus(); + return enumToSelect(res.data); + }, + }, + { title: '操作', valueType: 'option', key: 'option', render: (text, record) => [ - <AddOrUpdate - key="update" - record={record} - onfinish={() => { - actionRef.current?.reload(); - }} - />, - <ButtonConfirm - key="delete" - className="p-0" - title={'确认删除该记录?'} - text="删除" - onConfirm={async () => { - let res = await postProcureBillDelete({ - query: { id: record.id }, - }); - if (res) { - message.success(res.message); + record.paths?.includes('UPDATE') && ( + <AddOrUpdate + key="update" + record={record} + onfinish={() => { actionRef.current?.reload(); - } - }} - />, + }} + /> + ), + record.paths?.includes('UPDATE') && ( + <ButtonConfirm + key="delete" + className="p-0" + title={'确认删除该记录?'} + text="删除" + onConfirm={async () => { + let res = await postProcureBillDelete({ + query: { id: record.id }, + }); + if (res) { + message.success(res.message); + actionRef.current?.reload(); + } + }} + /> + ), + record.paths?.includes('AUDIT') && ( + <Audit + recordId={record.id} + onClose={() => { + actionRef.current?.reload(); + }} + ></Audit> + ), ], }, ]; @@ -128,7 +192,41 @@ export default () => { }, { title: '数量', dataIndex: 'number', key: 'number' }, { title: '小计', dataIndex: 'totalPrice', key: 'totalPrice' }, - { title: '附件', dataIndex: 'annex', key: 'annex' }, + { + title: '附件', + dataIndex: 'annex', + key: 'annex', + 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: '备注', dataIndex: 'notes', key: 'notes' }, ]} headerTitle={false} @@ -139,7 +237,6 @@ export default () => { /> ), }} - search={false} dateFormatter="string" headerTitle="采购管理" options={false} diff --git a/src/pages/product/productCollect/components/AddOrUpdate.tsx b/src/pages/product/productCollect/components/AddOrUpdate.tsx index 0b47ff4..89ce566 100644 --- a/src/pages/product/productCollect/components/AddOrUpdate.tsx +++ b/src/pages/product/productCollect/components/AddOrUpdate.tsx @@ -1,19 +1,128 @@ import { postProductCollectBillAddOrModify } from '@/services'; import { useModel } from '@@/exports'; import { + ActionType, + EditableProTable, ModalForm, - ProFormDigit, - ProFormSelect, - ProFormText, + ProCard, + ProColumns, + ProForm, + ProFormDependency, + ProFormField, + ProFormSwitch, ProFormTextArea, } from '@ant-design/pro-components'; import { Button, Form, 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(() => { + if (record?.details) { + const updateddetails = record.details.map((item) => ({ + ...item, + key: item.key || `key-${Math.random().toString(36).substr(2, 9)}`, // 动态生成唯一 key + })); + setProcessedRecord({ + ...record, + details: updateddetails, + }); + } + }, [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) => { + const currentTableData = editorFormRef.current?.getRowsData?.(); + if (currentTableData) { + const updatedData = [...currentTableData]; + updatedData[rowIndex] = { + ...updatedData[rowIndex], + productUnitName: option.productUnitName, + productUnitPrice: option.productUnitPrice, + }; + formRef.current?.setFieldsValue({ + details: 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: '操作', + valueType: 'option', + render: (text, record, _, action) => [ + <a + key="editable" + onClick={() => { + action?.startEditable?.(record.key); + }} + > + 编辑 + </a>, + <a + key="delete" + onClick={() => { + const tableDataSource = formRef.current?.getFieldValue('details'); + formRef.current?.setFieldsValue({ + table: tableDataSource.filter((item) => item.key !== record.key), + }); + }} + > + 删除 + </a>, + ], + }, + ]; -export default ({ record, onFinish }) => { const [form] = Form.useForm(); - const { getWarehouse } = useModel('enum'); return ( <ModalForm + formRef={formRef} + initialValues={processedRecord} + validateTrigger="onBlur" title="新建表单" trigger={ record?.id ? ( @@ -24,66 +133,99 @@ export default ({ record, onFinish }) => { } form={form} autoFocusFirstInput + width={1500} modalProps={{ destroyOnClose: true, onCancel: () => console.log('run'), }} submitTimeout={2000} onFinish={async (values) => { - let res = await postProductCollectBillAddOrModify({ - data: values, + const res = await postProductCollectBillAddOrModify({ + data: { + ...record, + ...values, + }, }); if (res) { message.success(res.message); - onFinish(); + onfinish(); } return true; }} > - <ProFormDigit - label="id" - name="id" - initialValue={record?.id} - width="sm" - hidden={true} - /> - <ProFormText - width="md" - initialValue={record?.productName} - name="productName" - label="申领物品" - rules={[{ required: true, message: '申领物品必填' }]} - /> - <ProFormDigit - label="申领数量" - name="productNumber" - initialValue={record?.productNumber} - width="sm" - min={1} - rules={[{ required: true, message: '申领数量必填' }]} - /> - <ProFormSelect - width="md" - request={async () => { - const res = await getWarehouse(); - console.log('options:' + res); - let options = Object.entries(res).map(([value, label]) => ({ - label, - value, - })); - console.log('options:' + options); - return options; + <EditableProTable + rowKey="key" + scroll={{ + x: 960, + }} + editableFormRef={editorFormRef} + headerTitle="可编辑表格" + maxLength={5} + name="details" + 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]; + }, }} - // initialValue={record?.warehouseCode} - name="warehouseCode" - label="申领仓库" - rules={[{ required: true, message: '申领仓库为必填项' }]} - /> - <ProFormTextArea - initialValue={record?.applyRemarks} - name="applyRemarks" - label="申领备注" /> + <ProForm.Item> + <ProCard title="表格数据" headerBordered collapsible defaultCollapsed> + <ProFormDependency name={['details']}> + {({ details }) => ( + <ProFormField + ignoreFormItem + fieldProps={{ + style: { + width: '100%', + }, + }} + mode="read" + valueType="jsonCode" + text={JSON.stringify(details)} + /> + )} + </ProFormDependency> + </ProCard> + </ProForm.Item> + <ProFormTextArea name="auditRemarks" label="备注" /> </ModalForm> ); }; -- libgit2 0.23.3