diff --git a/package-lock.json b/package-lock.json index 6ccf0bc..1504865 100644 --- a/package-lock.json +++ b/package-lock.json @@ -13,7 +13,8 @@ "@umijs/max": "^4.0.87", "antd": "^5.10.2", "axios": "^1.6.1", - "lodash": "^4.17.21" + "lodash": "^4.17.21", + "print-js": "^1.6.0" }, "devDependencies": { "@inspir/pluto": "^1.0.5", @@ -14526,6 +14527,11 @@ "renderkid": "^3.0.0" } }, + "node_modules/print-js": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/print-js/-/print-js-1.6.0.tgz", + "integrity": "sha512-BfnOIzSKbqGRtO4o0rnj/K3681BSd2QUrsIZy/+WdCIugjIswjmx3lDEZpXB2ruGf9d4b3YNINri81+J0FsBWg==" + }, "node_modules/process": { "version": "0.11.10", "resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz", @@ -29855,6 +29861,11 @@ "renderkid": "^3.0.0" } }, + "print-js": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/print-js/-/print-js-1.6.0.tgz", + "integrity": "sha512-BfnOIzSKbqGRtO4o0rnj/K3681BSd2QUrsIZy/+WdCIugjIswjmx3lDEZpXB2ruGf9d4b3YNINri81+J0FsBWg==" + }, "process": { "version": "0.11.10", "resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz", diff --git a/package.json b/package.json index 47afd9c..a433fef 100644 --- a/package.json +++ b/package.json @@ -18,7 +18,8 @@ "@umijs/max": "^4.0.87", "antd": "^5.10.2", "axios": "^1.6.1", - "lodash": "^4.17.21" + "lodash": "^4.17.21", + "print-js": "^1.6.0" }, "devDependencies": { "@inspir/pluto": "^1.0.5", diff --git a/src/pages/Order/components/ConfirmReceiptModal.tsx b/src/pages/Order/components/ConfirmReceiptModal.tsx new file mode 100644 index 0000000..2ba28a4 --- /dev/null +++ b/src/pages/Order/components/ConfirmReceiptModal.tsx @@ -0,0 +1,108 @@ +import { postServiceOrderConfirmReceipt } from '@/services'; +import { UploadOutlined } from '@ant-design/icons'; +import { ModalForm } from '@ant-design/pro-components'; +import { Button, Form, Upload } from 'antd'; +import { RcFile, UploadFile, UploadProps } from 'antd/es/upload'; +import { useState } from 'react'; +export default ({ data, onClose }) => { + const [form] = Form.useForm<{ name: string; company: string }>(); + const [previewOpen, setPreviewOpen] = useState(false); + const [previewImage, setPreviewImage] = useState(''); + const [previewTitle, setPreviewTitle] = useState(''); + console.log(previewOpen); + console.log(previewImage); + console.log(previewTitle); + const getBase64 = (file: RcFile): Promise<string> => + new Promise((resolve, reject) => { + const reader = new FileReader(); + reader.readAsDataURL(file); + reader.onload = () => resolve(reader.result as string); + reader.onerror = (error) => reject(error); + }); + // const beforeUpload = (file: RcFile) => { + // const isJpgOrPng = file.type === 'image/jpeg' || file.type === 'image/png'; + // if (!isJpgOrPng) { + // message.error('You can only upload JPG/PNG file!'); + // } + // const isLt2M = file.size / 1024 / 1024 < 2; + // if (!isLt2M) { + // message.error('Image must smaller than 2MB!'); + // } + // return isJpgOrPng && isLt2M; + // }; + const [fileList, setFileList] = useState<UploadFile[]>([]); + const [uploading, setUploading] = useState(false); + + const handlePreview = async (file: UploadFile) => { + if (!file.url && !file.preview) { + file.preview = await getBase64(file.originFileObj as RcFile); + } + + setPreviewImage(file.url || (file.preview as string)); + setPreviewOpen(true); + setPreviewTitle( + file.name || file.url!.substring(file.url!.lastIndexOf('/') + 1), + ); + }; + + const handleUpload = async () => { + const formData = new FormData(); + // fileList.forEach((file) => { + // formData.append('files[]', file as RcFile); + // }); + formData.append('file', fileList[0] as RcFile); + formData.append('id', data.id); + setUploading(true); + // You can use any AJAX library you like + const res = await postServiceOrderConfirmReceipt({ data: formData }); + console.log(res); + + setUploading(false); + }; + + const props: UploadProps = { + onRemove: (file) => { + const index = fileList.indexOf(file); + const newFileList = fileList.slice(); + newFileList.splice(index, 1); + setFileList(newFileList); + }, + beforeUpload: (file) => { + setFileList([...fileList, file]); + + return false; + }, + onPreview: handlePreview, + fileList, + }; + + return ( + <ModalForm<{ + name: string; + company: string; + }> + width={500} + open + title="确认收货" + form={form} + autoFocusFirstInput + submitTimeout={2000} + onFinish={async () => { + onClose(); + }} + > + <Upload {...props}> + <Button icon={<UploadOutlined />}>Select File</Button> + </Upload> + <Button + type="primary" + onClick={handleUpload} + disabled={fileList.length === 0} + loading={uploading} + style={{ marginTop: 16 }} + > + {uploading ? 'Uploading' : 'Start Upload'} + </Button> + </ModalForm> + ); +}; diff --git a/src/pages/Order/components/FinancialDrawer.tsx b/src/pages/Order/components/FinancialDrawer.tsx index 286b10c..850abd2 100644 --- a/src/pages/Order/components/FinancialDrawer.tsx +++ b/src/pages/Order/components/FinancialDrawer.tsx @@ -14,17 +14,10 @@ import { Form, message } from 'antd'; // }); // }; -export default ({ onClose }) => { - // const [expandedRowKeys, setExpandedRowKeys] = useState<readonly Key[]>([]); - const [form] = Form.useForm<{ name: string; company: string }>(); - // const actionRef = useRef< - // FormListActionType<{ - // name: string; - // }> - // >(); - //作为商品行号 - // const rowRumber = useRef(0); +export default ({ mainOrder, subOrders, onClose }) => { + console.log(subOrders); + const [form] = Form.useForm<{ name: string; company: string }>(); return ( <DrawerForm<{ name: string; @@ -39,8 +32,7 @@ export default ({ onClose }) => { maxWidth: window.innerWidth * 0.8, minWidth: 400, }} - // layout="horizontal" - // labelCol={{ span: 8 }} + initialValues={mainOrder} form={form} autoFocusFirstInput drawerProps={{ @@ -53,7 +45,7 @@ export default ({ onClose }) => { console.log(values.name); message.success('提交成功'); // 不返回不会关闭弹框 - // onClose(); + onClose(); return true; }} onOpenChange={(val) => { @@ -62,24 +54,27 @@ export default ({ onClose }) => { > <ProFormText width="lg" - name="invoiceInformation" + name="invoiceIdentificationNumber" label="开票信息" placeholder="请输入开票信息" + disabled /> <ProFormText width="lg" name="bank" label="开户银行" placeholder="请输入开户银行" + disabled /> <ProFormText width="lg" name="bankAccountNumber" label="开户银行账号" placeholder="请输入开户银行账号" + disabled /> - <ProFormDatePicker width="lg" name="contractTime" label="开票时间" /> - <ProFormDatePicker width="lg" name="contractTime" label="收款时间" /> + <ProFormDatePicker width="lg" name="invoicingTime" label="开票时间" /> + <ProFormDatePicker width="lg" name="collectMoneyTime" label="收款时间" /> </DrawerForm> ); }; diff --git a/src/pages/Order/components/OrderDrawer.tsx b/src/pages/Order/components/OrderDrawer.tsx index 8f55499..4b72535 100644 --- a/src/pages/Order/components/OrderDrawer.tsx +++ b/src/pages/Order/components/OrderDrawer.tsx @@ -2,8 +2,9 @@ import { RESPONSE_CODE } from '@/constants/enum'; import { postServiceOrderAddOrder, postServiceOrderQueryProductInformation, + postServiceOrderUpdateOrder, } from '@/services'; -import { enumToSelect } from '@/utils'; +import { enumToSelect, getUserInfo } from '@/utils'; import { DrawerForm, FormListActionType, @@ -16,7 +17,7 @@ import { ProFormTextArea, } from '@ant-design/pro-components'; import { Form, message } from 'antd'; -import { useEffect, useRef } from 'react'; +import { useEffect, useRef, useState } from 'react'; import { INVOCING_STATUS_OPTIONS, PAYMENT_CHANNEL_OPTIONS, @@ -24,7 +25,17 @@ import { PRODUCT_BELONG_DEPARTMENT_OPTIONS, } from '../constant'; -export default ({ onClose, data }) => { +export default ({ onClose, data, isAdd }) => { + const [invoicingStatus, setInvoicingStatus] = useState(''); + + //订单修改和新增的子订单列表命名是list + data.list = data.subOrderInformationLists; + if (!isAdd) { + data.paymentMethod = data.list[0].paymentMethod; + data.paymentChannel = data.list[0].paymentChannel; + data.invoicingStatus = data.list[0].invoicingStatus; + } + const [form] = Form.useForm<{ salesCode: ''; customerName: ''; @@ -89,46 +100,11 @@ export default ({ onClose, data }) => { }> open width="35%" - title="新建订单" - initialValues={{ - customerName: '123', - customerContactNumber: '123', - institution: '123', - institutionContactName: '123', - customerShippingAddress: '123123', - totalPayment: '12312', - paymentChannel: 'BANK_TRANSFER', - paymentMethod: 'PAYMENT_IN_ADVANCE', - productBelongBusiness: 'EXPERIMENTAL_CONSUMABLES', - invoicingStatus: 'INVOICED', - invoiceIdentificationNumber: '12312', - invoicingTime: '2023-11-29 23:19:15', - bank: '123', - bankAccountNumber: '1231', - notes: '123', - list: [ - { - productCode: 'qweq', - productName: 'qweqwe', - quantity: '99', - productPrice: '12313', - parameters: 'qweq', - subOrderPayment: '1231', - unit: 'qweq', - serialNumber: 'qwewqe', - notes: 'qweqw', - }, - { - productName: 'asdsda', - productCode: 'dasda', - parameters: 'sdasa', - quantity: '99', - productPrice: '123', - unit: '123', - subOrderPayment: '123', - serialNumber: 'adadas', - }, - ], + title={isAdd ? '新建订单' : '修改订单'} + initialValues={() => { + if (!isAdd) { + return data; + } }} resize={{ onResize() { @@ -146,13 +122,21 @@ export default ({ onClose, data }) => { }} submitTimeout={2000} onFinish={async (values) => { - const data = await postServiceOrderAddOrder({ data: values }); + let data = {}; + if (isAdd) { + message.info('add'); + data = await postServiceOrderAddOrder({ data: values }); + } else { + message.info('update'); + data = await postServiceOrderUpdateOrder({ data: values }); + } + if (data.result === RESPONSE_CODE.SUCCESS) { message.success(data.message); + // 不返回不会关闭弹框 + onClose(); + return true; } - // 不返回不会关闭弹框 - onClose(); - return true; }} onOpenChange={(val) => { return !val && onClose(); @@ -160,12 +144,20 @@ export default ({ onClose, data }) => { > <h2>订单基本信息</h2> <ProFormText + name="id" + width="lg" + disabled + label="id" + placeholder="id" + hidden + /> + <ProFormText name="salesCode" width="lg" disabled label="销售代表" placeholder="请输入销售代表" - initialValue="JOJO" + initialValue={getUserInfo().nickName} /> <ProFormText name="customerName" @@ -220,33 +212,43 @@ export default ({ onClose, data }) => { options={enumToSelect(PRODUCT_BELONG_DEPARTMENT_OPTIONS)} /> <ProFormSelect - placeholder="选择是否要开票" + placeholder="选择是否需要开票" name="invoicingStatus" width="lg" - label="是否要开票" + label="是否需要开票" options={enumToSelect(INVOCING_STATUS_OPTIONS)} + onChange={(_, option) => { + setInvoicingStatus(option.value); + }} /> <ProFormText width="lg" name="invoiceIdentificationNumber" label="开票信息" + hidden={invoicingStatus !== 'INVOICED'} placeholder="请输入开票信息" /> - <ProFormDateTimePicker - width="lg" - name="invoicingTime" - label="开票时间" - placeholder="请输入开票时间" - /> + {getUserInfo().roleSmallVO?.code === 'admin' ? ( + <ProFormDateTimePicker + width="lg" + name="invoicingTime" + label="开票时间" + placeholder="请输入开票时间" + /> + ) : ( + '' + )} <ProFormText width="lg" name="bank" label="开户银行" + hidden={invoicingStatus !== 'INVOICED'} placeholder="请输入开户银行" /> <ProFormText width="lg" name="bankAccountNumber" + hidden={invoicingStatus !== 'INVOICED'} label="银行账号" placeholder="请输入银行账号" /> diff --git a/src/pages/Order/constant.ts b/src/pages/Order/constant.ts index 9aa8544..b692b1d 100644 --- a/src/pages/Order/constant.ts +++ b/src/pages/Order/constant.ts @@ -138,48 +138,70 @@ export const MAIN_ORDER_COLUMNS = [ ]; export const SUB_ORDER_COLUMNS = [ - { title: 'ID', dataIndex: 'id', key: 'id' }, - { title: '商品编码', dataIndex: 'productCode', key: 'productCode' }, - { title: '商品名称', dataIndex: 'productName', key: 'productName' }, - { title: '商品参数', dataIndex: 'parameters', key: 'parameters' }, - { title: '商品数量', dataIndex: 'quantity', key: 'quantity' }, + { title: 'ID', dataIndex: 'id', key: 'id', width: 80 }, + { + title: '商品编码', + dataIndex: 'productCode', + key: 'productCode', + width: 80, + }, + { + title: '商品名称', + dataIndex: 'productName', + key: 'productName', + width: 80, + }, + { title: '商品参数', dataIndex: 'parameters', key: 'parameters', width: 80 }, + { title: '商品数量', dataIndex: 'quantity', key: 'quantity', width: 80 }, { title: '子订单金额(¥)', dataIndex: 'subOrderPayment', key: 'subOrderPayment', + width: 80, }, { title: '支付方式', dataIndex: 'paymentMethod', key: 'paymentMethod', + width: 80, }, { title: '支付渠道', dataIndex: 'paymentChannel', key: 'paymentChannel', + width: 80, }, { title: '支付流水', dataIndex: 'paymentTransactionId', key: 'paymentTransactionId', + width: 80, }, { title: '物流方式', dataIndex: 'logisticsMethod', key: 'logisticsMethod', + width: 80, + }, + { + title: '物流单号', + dataIndex: 'serialNumber', + key: 'serialNumber', + width: 80, }, - { title: '物流单号', dataIndex: 'serialNumber', key: 'serialNumber' }, { title: '开票状态', dataIndex: 'invoicingStatus', key: 'invoicingStatus', component: 'tag', + width: 80, }, { title: '订单状态', dataIndex: 'orderStatus', key: 'orderStatus', component: 'tag', + width: 80, }, ]; @@ -203,8 +225,8 @@ export const PRODUCT_BELONG_DEPARTMENT_OPTIONS = { }; export const INVOCING_STATUS_OPTIONS = { - UN_INVOICE: '未开票', - INVOICED: '已开票', + UN_INVOICE: '否', + INVOICED: '是', }; export const LOGISTICS_STATUS_OPTIONS = { diff --git a/src/pages/Order/index.tsx b/src/pages/Order/index.tsx index e9c0bc1..1c40e9a 100644 --- a/src/pages/Order/index.tsx +++ b/src/pages/Order/index.tsx @@ -1,20 +1,21 @@ import ButtonConfirm from '@/components/ButtomConfirm'; import { RESPONSE_CODE } from '@/constants/enum'; import { - postServiceOrderExport, postServiceOrderOrderCancel, postServiceOrderPrintOrder, postServiceOrderQueryServiceOrder, } from '@/services'; import { orderExport } from '@/services/order'; import { enumValueToLabel } from '@/utils'; -import { DownOutlined } from '@ant-design/icons'; +import { DownOutlined, EllipsisOutlined } from '@ant-design/icons'; import { PageContainer, ProColumns, ProTable, } from '@ant-design/pro-components'; +import { history } from '@umijs/max'; import { + Avatar, Button, Checkbox, Divider, @@ -27,8 +28,11 @@ import { } from 'antd'; import { cloneDeep } from 'lodash'; import { Key, useRef, useState } from 'react'; +import OrderPrintModal from '../OrderPrint/OrderPrintModal'; import CheckModal from './components/CheckModal'; +import ConfirmReceiptModal from './components/ConfirmReceiptModal'; import DeliverModal from './components/DeliverModal'; +import FinancialDrawer from './components/FinancialDrawer'; import OrderDrawer from './components/OrderDrawer'; import { INVOCING_STATUS_OPTIONS, @@ -45,11 +49,17 @@ import { OrderListItemType, OrderType } from './type.d'; const OrderPage = () => { const [orderDrawerVisible, setOrderDrawerVisible] = useState<boolean>(false); const [checkVisible, setCheckVisible] = useState<boolean>(false); + const [orderPrintVisible, setOrderPrintVisible] = useState<boolean>(false); + const [financialVisible, setFinancialVisible] = useState<boolean>(false); + const [confirmReceiptVisible, setConfirmReceiptVisible] = + useState<boolean>(false); const [deliverVisible, setDeliverVisible] = useState<boolean>(false); + const [isOrderAddOpt, setIsOrderAddOpt] = useState<boolean>(false); const [expandedRowKeys, setExpandedRowKeys] = useState<Key[]>([]); const [orderRow, setOrderRow] = useState<Partial<OrderType>>({}); const [mainOrderAllItemKeys, setMainOrderAllItemKeys] = useState([]); const [rolePath, setRolePath] = useState([]); //当前角色权限(新增跟打印按钮) + const userInfo = JSON.parse(localStorage.getItem('userInfo')); const [selectedRows, setSelectedRows] = useState({}); const [selectedRowObj, setSelectedRowObj] = useState({}); @@ -68,7 +78,6 @@ const OrderPage = () => { setExpandedRowKeys([]); return; } - setExpandedRowKeys(mainOrderAllItemKeys); }; // 主订单内容渲染 @@ -169,7 +178,12 @@ const OrderPage = () => { className="p-0" type="link" onClick={() => { - window.print(); + if (!selectedRowObj[record.id]?.length) { + return message.error('请选择选择子订单'); + } + setSelectedRows(selectedRowObj[record.id]); + setOrderRow(record); + setOrderPrintVisible(true); }} > 打印 @@ -177,13 +191,21 @@ const OrderPage = () => { ) : ( '' )} - {record.mainPath.includes('confirmReceipt') ? ( - <ButtonConfirm + {record.mainPath.includes('editOrder') ? ( + <Button + type="link" className="p-0" - title="确认开票?" - text="开票" - onConfirm={() => {}} - /> + onClick={() => { + let selectedSubOrders = selectedRowObj[record.id]; + setSelectedRows(selectedSubOrders); + if (selectedSubOrders === undefined) { + setSelectedRows(record.subOrderInformationLists); + } + setFinancialVisible(true); + }} + > + 开票 + </Button> ) : ( '' )} @@ -194,6 +216,7 @@ const OrderPage = () => { onClick={() => { setOrderDrawerVisible(true); setOrderRow(record); + setIsOrderAddOpt(false); }} > 编辑 @@ -201,6 +224,7 @@ const OrderPage = () => { ) : ( '' )} + {record.mainPath.includes('checkOrder') ? ( <Button className="p-0" @@ -290,10 +314,8 @@ const OrderPage = () => { return <Tag color={color}>{label}</Tag>; }, }; - } - - //枚举字段处理 - if ( + } else if ( + //枚举字段处理 item.key === 'paymentMethod' || item.key === 'paymentChannel' || item.key === 'logisticsMethod' @@ -311,8 +333,22 @@ const OrderPage = () => { return label; }, }; + } else { + //普通字段,超出长度自动换行 + return { + ...item, + render: (text: string) => { + return ( + <div + style={{ wordWrap: 'break-word', wordBreak: 'break-all' }} + > + {text} + </div> + ); + }, + }; } - return item; + // return item; }) .concat([ { @@ -359,26 +395,32 @@ const OrderPage = () => { ) : ( '' )} - {optRecord.subPath.includes('confirmReceipt') ? ( - <ButtonConfirm + {optRecord.subPath.includes('editOrder') ? ( + <Button className="p-0" - title="确认开票?" - text="开票" - onConfirm={() => {}} - /> + type="link" + onClick={() => { + setFinancialVisible(true); + setOrderRow(record); + setSelectedRows(selectedRowObj[record.id]); + }} + > + 编辑 + </Button> ) : ( '' )} - {optRecord.subPath.includes('updateOrder') ? ( + {optRecord.subPath.includes('invocing') ? ( <Button className="p-0" type="link" onClick={() => { - setOrderDrawerVisible(true); - setOrderRow(optRecord); + setFinancialVisible(true); + setOrderRow(record); + setSelectedRows(selectedRowObj[record.id]); }} > - 编辑 + 开票 </Button> ) : ( '' @@ -398,6 +440,21 @@ const OrderPage = () => { '' )} + {optRecord.subPath.includes('confirmReceipt') ? ( + <Button + className="p-0" + type="link" + onClick={() => { + setConfirmReceiptVisible(true); + setOrderRow(optRecord); + }} + > + 确认收货 + </Button> + ) : ( + '' + )} + {/* {optRecord.subPath.includes("OrderCancel") ? <ButtonConfirm className="p-0" @@ -474,24 +531,28 @@ const OrderPage = () => { message.error('当前没有订单'); return; } - const data = await postServiceOrderExport({ - data: { flag: true, ids: mainOrderAllItemKeys }, - }); - if (data.result === RESPONSE_CODE.SUCCESS) { - message.success(data.message); - } + // const data = await postServiceOrderExport({ + // data: { flag: true, ids: mainOrderAllItemKeys }, + // }); + // if (data.result === RESPONSE_CODE.SUCCESS) { + // message.success(data.message); + // } + let body = { flag: true, ids: mainOrderAllItemKeys }; + orderExport(body); }, }, { label: '导出所有订单', key: '3', onClick: async () => { - const data = await postServiceOrderExport({ - data: { flag: false, ids: [] }, - }); - if (data.result === RESPONSE_CODE.SUCCESS) { - message.success(data.message); - } + // const data = await postServiceOrderExport({ + // data: { flag: false, ids: [] }, + // }); + // if (data.result === RESPONSE_CODE.SUCCESS) { + // message.success(data.message); + // } + let body = { flag: false, ids: [] }; + orderExport(body); }, }, ]; @@ -506,7 +567,10 @@ const OrderPage = () => { <Button type="primary" key="out" - onClick={() => setOrderDrawerVisible(true)} + onClick={() => { + setOrderDrawerVisible(true); + setIsOrderAddOpt(true); + }} > 新增 </Button>, @@ -544,6 +608,35 @@ const OrderPage = () => { <PageContainer header={{ title: '订单管理', + extra: [ + <Avatar key="0" style={{ verticalAlign: 'middle' }} size="large"> + {userInfo?.nickName} + </Avatar>, + <Dropdown + key="dropdown" + trigger={['click']} + menu={{ + items: [ + { + label: '退出登录', + key: '1', + onClick: () => { + localStorage.removeItem('token'); + history.push('/login'); + }, + }, + { + label: '修改密码', + key: '2', + }, + ], + }} + > + <Button key="4" style={{ padding: '0 8px' }}> + <EllipsisOutlined /> + </Button> + </Dropdown>, + ], }} > <ProTable @@ -578,6 +671,7 @@ const OrderPage = () => { filter, data: params, }); + let mainOrderIds = data?.data?.map((d) => d.id); if (mainOrderAllItemKeys === undefined) { setMainOrderAllItemKeys([]); @@ -603,6 +697,7 @@ const OrderPage = () => { setOrderRow({}); mainTableRef.current?.reload(); }} + isAdd={isOrderAddOpt} /> )} @@ -628,6 +723,41 @@ const OrderPage = () => { }} /> )} + + {financialVisible && ( + <FinancialDrawer + mainOrder={orderRow} + subOrders={selectedRows} + onClose={() => { + setFinancialVisible(false); + setOrderRow({}); + mainTableRef.current?.reload(); + }} + /> + )} + + {orderPrintVisible && ( + <OrderPrintModal + mainOrder={orderRow} + subOrders={selectedRows} + onClose={() => { + setOrderPrintVisible(false); + setOrderRow({}); + mainTableRef.current?.reload(); + }} + /> + )} + + {confirmReceiptVisible && ( + <ConfirmReceiptModal + data={orderRow} + onClose={() => { + setConfirmReceiptVisible(false); + setOrderRow({}); + mainTableRef.current?.reload(); + }} + /> + )} </PageContainer> ); }; diff --git a/src/pages/OrderPrint/OrderPrintModal.tsx b/src/pages/OrderPrint/OrderPrintModal.tsx new file mode 100644 index 0000000..a19ac11 --- /dev/null +++ b/src/pages/OrderPrint/OrderPrintModal.tsx @@ -0,0 +1,275 @@ +import '@/pages/OrderPrint/index.less'; +import { Modal } from 'antd'; +import printJS from 'print-js'; + +export default ({ mainOrder, subOrders, onClose }) => { + console.log(mainOrder); + console.log(subOrders); + + let columns = []; + for (let i = 0; i < subOrders.length; i++) { + let subOrder = subOrders[i]; + columns.push( + <tr height="30" style={{ height: '15.00pt' }}> + <td height="30" style={{ height: '15.00pt' }}></td> + <td className="xl72">{i + 1}</td> + <td className="xl72">{subOrder.id}</td> + <td className="xl72">{subOrder.productName}</td> + <td className="xl72">{subOrder.parameters}</td> + <td className="xl72">{subOrder.unit}</td> + <td className="xl72">{subOrder.quantity}</td> + <td className="xl72">{subOrder.notes}</td> + </tr>, + ); + } + + //补充空白行,使表格不少于六行 + for (let i = subOrders.length; i < 6; i++) { + columns.push( + <tr height="30" style={{ height: '15.00pt' }}> + <td height="30" style={{ height: '15.00pt' }}></td> + <td className="xl72"></td> + <td className="xl72"></td> + <td className="xl72"></td> + <td className="xl72"></td> + <td className="xl72"></td> + <td className="xl72"></td> + <td className="xl72"></td> + </tr>, + ); + } + + return ( + <Modal + title="打印出货单" + centered + open + onOk={() => { + //printJS打印出货单 + printJS({ + printable: 'printArea', // 元素id,不支持多个 + type: 'html', + targetStyle: ['* '], + targetStyles: ['*'], + style: + '@page{size:auto; margin: 0;}' + + '@media print { @page {size: landscape } }', // landscape 默认横向打印 + }); + + onClose(); + }} + onCancel={() => onClose()} + width={1000} + > + <div + id="printArea" + className="flex items-center justify-center bg-gray-100" + > + <div className="w-full max-w-4xl p-10 my-10 bg-white border border-gray-300"> + <table + className="p-10" + width="846" + border={0} + cellPadding={0} + cellSpacing={0} + style={{ + width: '423.00pt', + borderCollapse: 'collapse', + tableLayout: 'fixed', + }} + > + <col + width="25.50" + style={{ msoWidthSource: 'userset', msoWidthAlt: 544 }} + /> + <col + width="52.50" + style={{ msoWidthSource: 'userset', msoWidthAlt: 1120 }} + /> + <col + width="115.50" + style={{ msoWidthSource: 'userset', msoWidthAlt: 2464 }} + /> + <col + width="169.50" + style={{ msoWidthSource: 'userset', msoWidthAlt: 3616 }} + /> + <col + width="165" + style={{ msoWidthSource: 'userset', msoWidthAlt: 3520 }} + /> + <col + width="96" + style={{ msoWidthSource: 'userset', msoWidthAlt: 2048 }} + /> + <col + width="114" + style={{ msoWidthSource: 'userset', msoWidthAlt: 2432 }} + /> + <col width="108" style={{ width: '54.00pt' }} /> + <tr height="42" style={{ height: '21.00pt' }}> + <td height="42" style={{ height: '21.00pt' }}></td> + <td + className="xl65" + colSpan="7" + style={{ borderRight: 'none', borderBottom: 'none' }} + > + 科 路 得 + </td> + </tr> + <tr height="30" style={{ height: '15.00pt' }}> + <td height="30" style={{ height: '15.00pt' }}></td> + <td + className="xl66" + colSpan="7" + style={{ borderRight: 'none', borderBottom: 'none' }} + > + 网址:www.canrd.com + </td> + </tr> + <tr height="35" style={{ height: '17.50pt' }}> + <td height="35" style={{ height: '17.50pt' }}></td> + <td + className="xl67" + colSpan="7" + style={{ borderRight: 'none', borderBottom: 'none' }} + > + 销售出货单 + </td> + </tr> + <tr height="30" style={{ height: '15.00pt' }}> + <td height="30" style={{ height: '15.00pt' }}></td> + <td + className="xl69" + colSpan="4" + style={{ borderRight: 'none', borderBottom: 'none' }} + > + 单位名称:{mainOrder.institution} + </td> + <td + className="xl69" + colSpan="3" + style={{ borderRight: 'none', borderBottom: 'none' }} + > + 单号:{mainOrder.id} + </td> + </tr> + <tr height="30" style={{ height: '15.00pt' }}> + <td height="30" style={{ height: '15.00pt' }}></td> + <td + className="xl69" + colSpan="4" + style={{ borderRight: 'none', borderBottom: 'none' }} + > + 联系人:{mainOrder.customerName} + </td> + <td + className="xl69" + colSpan="3" + style={{ borderRight: 'none', borderBottom: 'none' }} + > + 开单日期:{mainOrder.createTime} + </td> + </tr> + <tr height="30" style={{ height: '15.00pt' }}> + <td height="30" style={{ height: '15.00pt' }}></td> + <td + className="xl69" + colSpan="4" + style={{ borderRight: 'none', borderBottom: 'none' }} + > + 联系电话:{mainOrder.customerContactNumber} + </td> + <td + className="xl70" + colSpan={2} + style={{ msoIgnore: 'colSpan' }} + ></td> + <td className="xl70"></td> + </tr> + <tr height="30" style={{ height: '15.00pt' }}> + <td height="30" style={{ height: '15.00pt' }}></td> + <td + className="xl69" + colSpan="7" + style={{ borderRight: 'none', borderBottom: 'none' }} + > + 送货地址:{mainOrder.customerShippingAddress} + </td> + </tr> + <tr height="30" style={{ height: '15.00pt' }}> + <td height="30" style={{ height: '15.00pt' }}></td> + <td className="xl71">序号</td> + <td className="xl71">订单号</td> + <td className="xl71">货品名称</td> + <td className="xl71">规格</td> + <td className="xl71">单位</td> + <td className="xl71">数量</td> + <td className="xl71">备注</td> + </tr> + + {columns} + + <tr style={{ height: '19.00pt' }}> + <td style={{ height: '19.00pt' }}></td> + <td className="xl73">销货单位</td> + <td + className="xl74" + colSpan="3" + style={{ + borderRight: '0.5pt solid windowtext', + borderBottom: '0.5pt solid windowtext', + }} + > + 发货地址:广东省东莞市厚街镇锦丰路9号科路得产业园 + </td> + <td className="xl73">开户银行及账号</td> + <td + className="xl74" + colSpan={2} + style={{ + borderRight: '0.5pt solid windowtext', + borderBottom: '0.5pt solid windowtext', + }} + > + 招商银行股份有限公司东莞东骏路支行 + <br /> + 账号:769906437110802 + </td> + </tr> + <tr style={{ height: 30 }}> + <td height="30" style={{ height: '15.00pt' }}></td> + <td className="xl76" colSpan={2} style={{ msoIgnore: 'colSpan' }}> + 客户签名: + </td> + <td className="xl76">核准:屠亚辉</td> + <td + className="xl78" + colSpan={2} + style={{ borderRight: 'none', borderBottom: 'none' }} + > + 业务员:Peter + </td> + <td + className="xl78" + colSpan={2} + style={{ borderRight: 'none', borderBottom: 'none' }} + > + 开单人:张玉红 + </td> + </tr> + <tr style={{ display: 'none', width: 0 }}> + <td width="26" style={{ width: 13 }}></td> + <td width="53" style={{ width: 26 }}></td> + <td width="116" style={{ width: 58 }}></td> + <td width="170" style={{ width: 85 }}></td> + <td width="165" style={{ width: 83 }}></td> + <td width="96" style={{ width: 48 }}></td> + <td width="114" style={{ width: 57 }}></td> + </tr> + </table> + </div> + </div> + </Modal> + ); +}; diff --git a/src/pages/OrderPrint/index.less b/src/pages/OrderPrint/index.less new file mode 100644 index 0000000..1c24702 --- /dev/null +++ b/src/pages/OrderPrint/index.less @@ -0,0 +1,1057 @@ +tr { + // mso-height-source: auto; + // mso-ruby-visibility: none; +} + +col { + // mso-width-source: auto; + // mso-ruby-visibility: none; +} + +br { + // mso-data-placement: same-cell; +} + +.font0 { + color: windowtext; + font-size: 12pt; + font-weight: 400; + font-style: normal; + text-decoration: none; + font-family: '宋体'; + // //mso-generic-font-family: auto; + // //mso-font-charset: 134; +} + +.font1 { + color: windowtext; + font-size: 16pt; + font-weight: 400; + font-style: normal; + text-decoration: none; + font-family: '宋体'; + // //mso-generic-font-family: auto; + // mso-font-charset: 134; +} + +.font2 { + color: windowtext; + font-size: 10pt; + font-weight: 400; + font-style: normal; + text-decoration: none; + font-family: '宋体'; + ////mso-generic-font-family: auto; + //mso-font-charset: 134; +} + +.font3 { + color: windowtext; + font-size: 14pt; + font-weight: 400; + font-style: normal; + text-decoration: none; + font-family: '宋体'; + ////mso-generic-font-family: auto; + //mso-font-charset: 134; +} + +.font4 { + color: windowtext; + font-size: 8pt; + font-weight: 400; + font-style: normal; + text-decoration: none; + font-family: '宋体'; + ////mso-generic-font-family: auto; + //mso-font-charset: 134; +} + +.font5 { + color: #00f; + font-size: 11pt; + font-weight: 400; + font-style: normal; + text-decoration: underline; + //text-underline-style: single; + font-family: '宋体'; + ////mso-generic-font-family: auto; + //mso-font-charset: 134; +} + +.font6 { + color: #800080; + font-size: 11pt; + font-weight: 400; + font-style: normal; + text-decoration: underline; + //text-underline-style: single; + font-family: '宋体'; + ////mso-generic-font-family: auto; + //mso-font-charset: 134; +} + +.font7 { + color: #000; + font-size: 11pt; + font-weight: 400; + font-style: normal; + text-decoration: none; + font-family: '宋体'; + ////mso-generic-font-family: auto; + //mso-font-charset: 134; +} + +.font8 { + color: #f00; + font-size: 11pt; + font-weight: 400; + font-style: normal; + text-decoration: none; + font-family: '宋体'; + ////mso-generic-font-family: auto; + //mso-font-charset: 134; +} + +.font9 { + color: #44546a; + font-size: 18pt; + font-weight: 700; + font-style: normal; + text-decoration: none; + font-family: '宋体'; + ////mso-generic-font-family: auto; + //mso-font-charset: 134; +} + +.font10 { + color: #7f7f7f; + font-size: 11pt; + font-weight: 400; + font-style: italic; + text-decoration: none; + font-family: '宋体'; + ////mso-generic-font-family: auto; + //mso-font-charset: 134; +} + +.font11 { + color: #44546a; + font-size: 15pt; + font-weight: 700; + font-style: normal; + text-decoration: none; + font-family: '宋体'; + ////mso-generic-font-family: auto; + //mso-font-charset: 134; +} + +.font12 { + color: #44546a; + font-size: 13pt; + font-weight: 700; + font-style: normal; + text-decoration: none; + font-family: '宋体'; + ////mso-generic-font-family: auto; + //mso-font-charset: 134; +} + +.font13 { + color: #44546a; + font-size: 11pt; + font-weight: 700; + font-style: normal; + text-decoration: none; + font-family: '宋体'; + ////mso-generic-font-family: auto; + //mso-font-charset: 134; +} + +.font14 { + color: #3f3f76; + font-size: 11pt; + font-weight: 400; + font-style: normal; + text-decoration: none; + font-family: '宋体'; + ////mso-generic-font-family: auto; + //mso-font-charset: 134; +} + +.font15 { + color: #3f3f3f; + font-size: 11pt; + font-weight: 700; + font-style: normal; + text-decoration: none; + font-family: '宋体'; + ////mso-generic-font-family: auto; + //mso-font-charset: 134; +} + +.font16 { + color: #fa7d00; + font-size: 11pt; + font-weight: 700; + font-style: normal; + text-decoration: none; + font-family: '宋体'; + ////mso-generic-font-family: auto; + //mso-font-charset: 134; +} + +.font17 { + color: #fff; + font-size: 11pt; + font-weight: 700; + font-style: normal; + text-decoration: none; + font-family: '宋体'; + ////mso-generic-font-family: auto; + //mso-font-charset: 134; +} + +.font18 { + color: #fa7d00; + font-size: 11pt; + font-weight: 400; + font-style: normal; + text-decoration: none; + font-family: '宋体'; + ////mso-generic-font-family: auto; + //mso-font-charset: 134; +} + +.font19 { + color: #000; + font-size: 11pt; + font-weight: 700; + font-style: normal; + text-decoration: none; + font-family: '宋体'; + ////mso-generic-font-family: auto; + //mso-font-charset: 134; +} + +.font20 { + color: #006100; + font-size: 11pt; + font-weight: 400; + font-style: normal; + text-decoration: none; + font-family: '宋体'; + ////mso-generic-font-family: auto; + //mso-font-charset: 134; +} + +.font21 { + color: #9c0006; + font-size: 11pt; + font-weight: 400; + font-style: normal; + text-decoration: none; + font-family: '宋体'; + ////mso-generic-font-family: auto; + //mso-font-charset: 134; +} + +.font22 { + color: #9c6500; + font-size: 11pt; + font-weight: 400; + font-style: normal; + text-decoration: none; + font-family: '宋体'; + ////mso-generic-font-family: auto; + //mso-font-charset: 134; +} + +.font23 { + color: #fff; + font-size: 11pt; + font-weight: 400; + font-style: normal; + text-decoration: none; + font-family: '宋体'; + ////mso-generic-font-family: auto; + //mso-font-charset: 134; +} + +.font24 { + color: #000; + font-size: 11pt; + font-weight: 400; + font-style: normal; + text-decoration: none; + font-family: '宋体'; + ////mso-generic-font-family: auto; + //mso-font-charset: 134; +} + +.style0 { + //mso-number-format: "General"; + text-align: general; + vertical-align: middle; + white-space: nowrap; + // mso-rotate: 0; + // //mso-pattern: auto; + // mso-background-source: auto; + color: windowtext; + font-size: 12pt; + font-weight: 400; + font-style: normal; + text-decoration: none; + font-family: '宋体'; + ////mso-generic-font-family: auto; + //mso-font-charset: 134; + border: none; + //mso-protection: locked visible; + // mso-style-name: "常规"; + // mso-style-id: 0; +} + +.style16 { + // mso-number-format: "_ * \#\,\#\#0\.00_ \;_ * \\-\#\,\#\#0\.00_ \;_ * \0022-\0022??_ \;_ \@_ "; + // mso-style-name: "千位分隔"; + // mso-style-id: 3; +} + +.style17 { + // mso-number-format: "_ \0022\00A5\0022* \#\,\#\#0\.00_ \;_ \0022\00A5\0022* \\-\#\,\#\#0\.00_ \;_ \0022\00A5\0022* \0022-\0022??_ \;_ \@_ "; + // mso-style-name: "货币"; + // mso-style-id: 4; +} + +.style18 { + // mso-number-format: "0%"; + // mso-style-name: "百分比"; + // mso-style-id: 5; +} + +.style19 { + // mso-number-format: "_ * \#\,\#\#0_ \;_ * \\-\#\,\#\#0_ \;_ * \0022-\0022_ \;_ \@_ "; + // mso-style-name: "千位分隔[0]"; + // mso-style-id: 6; +} + +.style20 { + // mso-number-format: "_ \0022\00A5\0022* \#\,\#\#0_ \;_ \0022\00A5\0022* \\-\#\,\#\#0_ \;_ \0022\00A5\0022* \0022-\0022_ \;_ \@_ "; + // mso-style-name: "货币[0]"; + // mso-style-id: 7; +} + +.style21 { + color: #00f; + font-size: 11pt; + font-weight: 400; + font-style: normal; + text-decoration: underline; + //text-underline-style: single; + font-family: '宋体'; + ////mso-generic-font-family: auto; + //mso-font-charset: 134; + // mso-style-name: "超链接"; + // mso-style-id: 8; +} + +.style22 { + color: #800080; + font-size: 11pt; + font-weight: 400; + font-style: normal; + text-decoration: underline; + //text-underline-style: single; + font-family: '宋体'; + ////mso-generic-font-family: auto; + //mso-font-charset: 134; + // mso-style-name: "已访问的超链接"; + // mso-style-id: 9; +} + +.style23 { + // //mso-pattern: auto none; + background: #ffc; + border: 0.5pt solid #b2b2b2; + // mso-style-name: "注释"; +} + +.style24 { + color: #f00; + font-size: 11pt; + font-weight: 400; + font-style: normal; + text-decoration: none; + font-family: '宋体'; + ////mso-generic-font-family: auto; + //mso-font-charset: 134; + // mso-style-name: "警告文本"; +} + +.style25 { + color: #44546a; + font-size: 18pt; + font-weight: 700; + font-style: normal; + text-decoration: none; + font-family: '宋体'; + ////mso-generic-font-family: auto; + //mso-font-charset: 134; + // mso-style-name: "标题"; +} + +.style26 { + color: #7f7f7f; + font-size: 11pt; + font-weight: 400; + font-style: italic; + text-decoration: none; + font-family: '宋体'; + ////mso-generic-font-family: auto; + //mso-font-charset: 134; + // mso-style-name: "解释性文本"; +} + +.style27 { + color: #44546a; + font-size: 15pt; + font-weight: 700; + font-style: normal; + text-decoration: none; + font-family: '宋体'; + ////mso-generic-font-family: auto; + //mso-font-charset: 134; + border-bottom: 1pt solid #5b9bd5; + // mso-style-name: "标题 1"; +} + +.style28 { + color: #44546a; + font-size: 13pt; + font-weight: 700; + font-style: normal; + text-decoration: none; + font-family: '宋体'; + ////mso-generic-font-family: auto; + //mso-font-charset: 134; + border-bottom: 1pt solid #5b9bd5; + // mso-style-name: "标题 2"; +} + +.style29 { + color: #44546a; + font-size: 11pt; + font-weight: 700; + font-style: normal; + text-decoration: none; + font-family: '宋体'; + ////mso-generic-font-family: auto; + //mso-font-charset: 134; + border-bottom: 1pt solid #acccea; + //mso-style-name: "标题 3"; +} + +.style30 { + color: #44546a; + font-size: 11pt; + font-weight: 700; + font-style: normal; + text-decoration: none; + font-family: '宋体'; + ////mso-generic-font-family: auto; + //mso-font-charset: 134; + //mso-style-name: "标题 4"; +} + +.style31 { + ////mso-pattern: auto none; + background: #fc9; + color: #3f3f76; + font-size: 11pt; + font-weight: 400; + font-style: normal; + text-decoration: none; + font-family: '宋体'; + ////mso-generic-font-family: auto; + //mso-font-charset: 134; + border: 0.5pt solid #7f7f7f; + //mso-style-name: "输入"; +} + +.style32 { + ////mso-pattern: auto none; + background: #f2f2f2; + color: #3f3f3f; + font-size: 11pt; + font-weight: 700; + font-style: normal; + text-decoration: none; + font-family: '宋体'; + ////mso-generic-font-family: auto; + //mso-font-charset: 134; + border: 0.5pt solid #3f3f3f; + //mso-style-name: "输出"; +} + +.style33 { + ////mso-pattern: auto none; + background: #f2f2f2; + color: #fa7d00; + font-size: 11pt; + font-weight: 700; + font-style: normal; + text-decoration: none; + font-family: '宋体'; + ////mso-generic-font-family: auto; + //mso-font-charset: 134; + border: 0.5pt solid #7f7f7f; + //mso-style-name: "计算"; +} + +.style34 { + ////mso-pattern: auto none; + background: #a5a5a5; + color: #fff; + font-size: 11pt; + font-weight: 700; + font-style: normal; + text-decoration: none; + font-family: '宋体'; + ////mso-generic-font-family: auto; + //mso-font-charset: 134; + border: 2pt double #3f3f3f; + //mso-style-name: "检查单元格"; +} + +.style35 { + color: #fa7d00; + font-size: 11pt; + font-weight: 400; + font-style: normal; + text-decoration: none; + font-family: '宋体'; + ////mso-generic-font-family: auto; + //mso-font-charset: 134; + border-bottom: 2pt double #ff8001; + //mso-style-name: "链接单元格"; +} + +.style36 { + color: #000; + font-size: 11pt; + font-weight: 700; + font-style: normal; + text-decoration: none; + font-family: '宋体'; + ////mso-generic-font-family: auto; + //mso-font-charset: 134; + border-top: 0.5pt solid #5b9bd5; + border-bottom: 2pt double #5b9bd5; + //mso-style-name: "汇总"; +} + +.style37 { + ////mso-pattern: auto none; + background: #c6efce; + color: #006100; + font-size: 11pt; + font-weight: 400; + font-style: normal; + text-decoration: none; + font-family: '宋体'; + ////mso-generic-font-family: auto; + //mso-font-charset: 134; + //mso-style-name: "好"; +} + +.style38 { + ////mso-pattern: auto none; + background: #ffc7ce; + color: #9c0006; + font-size: 11pt; + font-weight: 400; + font-style: normal; + text-decoration: none; + font-family: '宋体'; + ////mso-generic-font-family: auto; + //mso-font-charset: 134; + //mso-style-name: "差"; +} + +.style39 { + ////mso-pattern: auto none; + background: #ffeb9c; + color: #9c6500; + font-size: 11pt; + font-weight: 400; + font-style: normal; + text-decoration: none; + font-family: '宋体'; + ////mso-generic-font-family: auto; + //mso-font-charset: 134; + //mso-style-name: "适中"; +} + +.style40 { + ////mso-pattern: auto none; + background: #5b9bd5; + color: #fff; + font-size: 11pt; + font-weight: 400; + font-style: normal; + text-decoration: none; + font-family: '宋体'; + ////mso-generic-font-family: auto; + //mso-font-charset: 134; + //mso-style-name: "强调文字颜色 1"; +} + +.style41 { + ////mso-pattern: auto none; + background: #ddebf7; + color: #000; + font-size: 11pt; + font-weight: 400; + font-style: normal; + text-decoration: none; + font-family: '宋体'; + ////mso-generic-font-family: auto; + //mso-font-charset: 134; + //mso-style-name: "20% - 强调文字颜色 1"; +} + +.style42 { + ////mso-pattern: auto none; + background: #bdd7ee; + color: #000; + font-size: 11pt; + font-weight: 400; + font-style: normal; + text-decoration: none; + font-family: '宋体'; + ////mso-generic-font-family: auto; + //mso-font-charset: 134; + //mso-style-name: "40% - 强调文字颜色 1"; +} + +.style43 { + ////mso-pattern: auto none; + background: #9bc2e6; + color: #fff; + font-size: 11pt; + font-weight: 400; + font-style: normal; + text-decoration: none; + font-family: '宋体'; + ////mso-generic-font-family: auto; + //mso-font-charset: 134; + //mso-style-name: "60% - 强调文字颜色 1"; +} + +.style44 { + ////mso-pattern: auto none; + background: #ed7d31; + color: #fff; + font-size: 11pt; + font-weight: 400; + font-style: normal; + text-decoration: none; + font-family: '宋体'; + ////mso-generic-font-family: auto; + //mso-font-charset: 134; + //mso-style-name: "强调文字颜色 2"; +} + +.style45 { + ////mso-pattern: auto none; + background: #fce4d6; + color: #000; + font-size: 11pt; + font-weight: 400; + font-style: normal; + text-decoration: none; + font-family: '宋体'; + ////mso-generic-font-family: auto; + //mso-font-charset: 134; + //mso-style-name: "20% - 强调文字颜色 2"; +} + +.style46 { + ////mso-pattern: auto none; + background: #f8cbad; + color: #000; + font-size: 11pt; + font-weight: 400; + font-style: normal; + text-decoration: none; + font-family: '宋体'; + ////mso-generic-font-family: auto; + //mso-font-charset: 134; + //mso-style-name: "40% - 强调文字颜色 2"; +} + +.style47 { + ////mso-pattern: auto none; + background: #f4b084; + color: #fff; + font-size: 11pt; + font-weight: 400; + font-style: normal; + text-decoration: none; + font-family: '宋体'; + ////mso-generic-font-family: auto; + //mso-font-charset: 134; + //mso-style-name: "60% - 强调文字颜色 2"; +} + +.style48 { + //mso-pattern: auto none; + background: #a5a5a5; + color: #fff; + font-size: 11pt; + font-weight: 400; + font-style: normal; + text-decoration: none; + font-family: '宋体'; + ////mso-generic-font-family: auto; + //mso-font-charset: 134; + //mso-style-name: "强调文字颜色 3"; +} + +.style49 { + //mso-pattern: auto none; + background: #ededed; + color: #000; + font-size: 11pt; + font-weight: 400; + font-style: normal; + text-decoration: none; + font-family: '宋体'; + ////mso-generic-font-family: auto; + //mso-font-charset: 134; + //mso-style-name: "20% - 强调文字颜色 3"; +} + +.style50 { + //mso-pattern: auto none; + background: #dbdbdb; + color: #000; + font-size: 11pt; + font-weight: 400; + font-style: normal; + text-decoration: none; + font-family: '宋体'; + ////mso-generic-font-family: auto; + //mso-font-charset: 134; + //mso-style-name: "40% - 强调文字颜色 3"; +} + +.style51 { + //mso-pattern: auto none; + background: #c9c9c9; + color: #fff; + font-size: 11pt; + font-weight: 400; + font-style: normal; + text-decoration: none; + font-family: '宋体'; + ////mso-generic-font-family: auto; + //mso-font-charset: 134; + //mso-style-name: "60% - 强调文字颜色 3"; +} + +.style52 { + //mso-pattern: auto none; + background: #ffc000; + color: #fff; + font-size: 11pt; + font-weight: 400; + font-style: normal; + text-decoration: none; + font-family: '宋体'; + ////mso-generic-font-family: auto; + //mso-font-charset: 134; + //mso-style-name: "强调文字颜色 4"; +} + +.style53 { + //mso-pattern: auto none; + background: #fff2cc; + color: #000; + font-size: 11pt; + font-weight: 400; + font-style: normal; + text-decoration: none; + font-family: '宋体'; + ////mso-generic-font-family: auto; + //mso-font-charset: 134; + //mso-style-name: "20% - 强调文字颜色 4"; +} + +.style54 { + //mso-pattern: auto none; + background: #ffe699; + color: #000; + font-size: 11pt; + font-weight: 400; + font-style: normal; + text-decoration: none; + font-family: '宋体'; + ////mso-generic-font-family: auto; + //mso-font-charset: 134; + //mso-style-name: "40% - 强调文字颜色 4"; +} + +.style55 { + //mso-pattern: auto none; + background: #ffd966; + color: #fff; + font-size: 11pt; + font-weight: 400; + font-style: normal; + text-decoration: none; + font-family: '宋体'; + ////mso-generic-font-family: auto; + //mso-font-charset: 134; + //mso-style-name: "60% - 强调文字颜色 4"; +} + +.style56 { + //mso-pattern: auto none; + background: #4472c4; + color: #fff; + font-size: 11pt; + font-weight: 400; + font-style: normal; + text-decoration: none; + font-family: '宋体'; + ////mso-generic-font-family: auto; + //mso-font-charset: 134; + //mso-style-name: "强调文字颜色 5"; +} + +.style57 { + //mso-pattern: auto none; + background: #d9e1f2; + color: #000; + font-size: 11pt; + font-weight: 400; + font-style: normal; + text-decoration: none; + font-family: '宋体'; + ////mso-generic-font-family: auto; + //mso-font-charset: 134; + //mso-style-name: "20% - 强调文字颜色 5"; +} + +.style58 { + //mso-pattern: auto none; + background: #b4c6e7; + color: #000; + font-size: 11pt; + font-weight: 400; + font-style: normal; + text-decoration: none; + font-family: '宋体'; + ////mso-generic-font-family: auto; + //mso-font-charset: 134; + //mso-style-name: "40% - 强调文字颜色 5"; +} + +.style59 { + //mso-pattern: auto none; + background: #8ea9db; + color: #fff; + font-size: 11pt; + font-weight: 400; + font-style: normal; + text-decoration: none; + font-family: '宋体'; + ////mso-generic-font-family: auto; + //mso-font-charset: 134; + //mso-style-name: "60% - 强调文字颜色 5"; +} + +.style60 { + //mso-pattern: auto none; + background: #70ad47; + color: #fff; + font-size: 11pt; + font-weight: 400; + font-style: normal; + text-decoration: none; + font-family: '宋体'; + ////mso-generic-font-family: auto; + //mso-font-charset: 134; + //mso-style-name: "强调文字颜色 6"; +} + +.style61 { + //mso-pattern: auto none; + background: #e2efda; + color: #000; + font-size: 11pt; + font-weight: 400; + font-style: normal; + text-decoration: none; + font-family: '宋体'; + ////mso-generic-font-family: auto; + //mso-font-charset: 134; + //mso-style-name: "20% - 强调文字颜色 6"; +} + +.style62 { + //mso-pattern: auto none; + background: #c6e0b4; + color: #000; + font-size: 11pt; + font-weight: 400; + font-style: normal; + text-decoration: none; + font-family: '宋体'; + ////mso-generic-font-family: auto; + //mso-font-charset: 134; + //mso-style-name: "40% - 强调文字颜色 6"; +} + +.style63 { + //mso-pattern: auto none; + background: #a9d08e; + color: #fff; + font-size: 11pt; + font-weight: 400; + font-style: normal; + text-decoration: none; + font-family: '宋体'; + ////mso-generic-font-family: auto; + ////mso-font-charset: 134; + //mso-style-name: "60% - 强调文字颜色 6"; +} + +td { + //mso-style-parent: style0; + padding-top: 1px; + padding-right: 1px; + padding-left: 1px; + // mso-ignore: padding; + //mso-number-format: "General"; + text-align: general; + vertical-align: middle; + white-space: nowrap; + // mso-rotate: 0; + //mso-pattern: auto; + // mso-background-source: auto; + color: windowtext; + font-size: 12pt; + font-weight: 400; + font-style: normal; + text-decoration: none; + font-family: '宋体'; + //mso-generic-font-family: auto; + ////mso-font-charset: 134; + border: none; + //mso-protection: locked visible; +} + +.xl65 { + //mso-style-parent: style0; + text-align: center; + font-size: 16pt; + ////mso-font-charset: 134; +} + +.xl66 { + //mso-style-parent: style0; + text-align: center; + font-size: 10pt; + ////mso-font-charset: 134; +} + +.xl67 { + //mso-style-parent: style0; + text-align: center; + font-size: 14pt; + //mso-font-charset: 134; +} + +.xl68 { + //mso-style-parent: style0; + text-align: center; + font-size: 14pt; + //mso-font-charset: 134; +} + +.xl69 { + //mso-style-parent: style0; + text-align: left; + font-size: 8pt; + //mso-font-charset: 134; +} + +.xl70 { + //mso-style-parent: style0; + text-align: left; + font-size: 8pt; + //mso-font-charset: 134; +} + +.xl71 { + //mso-style-parent: style0; + text-align: center; + font-size: 8pt; + //mso-font-charset: 134; + border: 0.5pt solid windowtext; +} + +.xl72 { + //mso-style-parent: style0; + text-align: center; + font-size: 8pt; + //mso-font-charset: 134; + border: 0.5pt solid windowtext; +} + +.xl73 { + //mso-style-parent: style0; + white-space: normal; + font-size: 8pt; + //mso-font-charset: 134; + border: 0.5pt solid windowtext; +} + +.xl74 { + //mso-style-parent: style0; + text-align: center; + white-space: normal; + font-size: 8pt; + //mso-font-charset: 134; + border: 0.5pt solid windowtext; +} + +.xl75 { + //mso-style-parent: style0; + text-align: center; + white-space: normal; + font-size: 8pt; + //mso-font-charset: 134; + border: 0.5pt solid windowtext; +} + +.xl76 { + //mso-style-parent: style0; + font-size: 8pt; + //mso-font-charset: 134; +} + +.xl77 { + //mso-style-parent: style0; + font-size: 8pt; + //mso-font-charset: 134; +} + +.xl78 { + //mso-style-parent: style0; + text-align: center; + font-size: 8pt; + //mso-font-charset: 134; +} diff --git a/src/pages/OrderPrint/index.tsx b/src/pages/OrderPrint/index.tsx index 8028ac9..aeed30f 100644 --- a/src/pages/OrderPrint/index.tsx +++ b/src/pages/OrderPrint/index.tsx @@ -1,116 +1,370 @@ // App.js +import '@/pages/OrderPrint/index.less'; +// function Header() { +// return ( +// <div className="flex items-start justify-between mb-6"> +// <div className="text-sm"> +// <p className="font-medium">网址: www.canrd.com</p> +// </div> +// <h1 className="text-3xl font-bold text-center">发票</h1> +// <div className="text-sm text-right"> +// <p className="font-medium">QQ: 2902385824</p> +// </div> +// </div> +// ); +// } -function Header() { - return ( - <div className="flex items-start justify-between mb-6"> - <div className="text-sm"> - <p className="font-medium">网址: www.canrd.com</p> - </div> - <h1 className="text-3xl font-bold text-center">发票</h1> - <div className="text-sm text-right"> - <p className="font-medium">QQ: 2902385824</p> - </div> - </div> - ); -} +// function InvoiceDetails() { +// return ( +// <div className="grid grid-cols-2 gap-4 mb-6 text-sm"> +// <div> +// <p>单位名称: 某某科技有限公司</p> +// <p>联系人: 张三</p> +// <p>联系电话: 18583817221</p> +// <p>送货地址: 广东省东莞市</p> +// </div> +// <div className="text-right"> +// <p>编号: Canrd-DZ-2023-1101-004</p> +// <p>开票日期: 2023年11月1日</p> +// </div> +// </div> +// ); +// } -function InvoiceDetails() { - return ( - <div className="grid grid-cols-2 gap-4 mb-6 text-sm"> - <div> - <p>单位名称: 某某科技有限公司</p> - <p>联系人: 张三</p> - <p>联系电话: 18583817221</p> - <p>送货地址: 广东省东莞市</p> - </div> - <div className="text-right"> - <p>编号: Canrd-DZ-2023-1101-004</p> - <p>开票日期: 2023年11月1日</p> - </div> - </div> - ); -} +// function ProductsTable() { +// return ( +// <div className="mb-6"> +// <table className="w-full text-sm border border-gray-300 table-fixed"> +// <thead> +// <tr className=""> +// <th className="w-1/4 p-2 border border-gray-300 border-solid"> +// 序号 +// </th> +// <th className="w-1/6 p-2 border border-gray-300 border-solid"> +// 订单号 +// </th> +// <th className="w-1/6 p-2 border border-gray-300 border-solid"> +// 货品名称 +// </th> +// <th className="w-1/12 p-2 border border-gray-300 border-solid"> +// 规格 +// </th> +// <th className="w-1/6 p-2 border border-gray-300 border-solid"> +// 单位 +// </th> +// <th className="w-1/6 p-2 border border-gray-300 border-solid"> +// 数量 +// </th> +// <th className="w-1/4 p-2 border border-gray-300 border-solid"> +// 备注 +// </th> +// </tr> +// </thead> +// <tbody> +// <tr> +// <td className="p-2 whitespace-normal border border-gray-300 border-solid"> +// 产品名称可能非常长,所以这里会自动换行 +// </td> +// <td className="p-2 border border-gray-300 border-solid"> +// 规格型号 +// </td> +// <td className="p-2 border border-gray-300 border-solid">单位</td> +// <td className="p-2 border border-gray-300 border-solid">1</td> +// <td className="p-2 border border-gray-300 border-solid">400</td> +// <td className="p-2 border border-gray-300 border-solid">400</td> +// <td className="p-2 whitespace-normal border border-gray-300 border-solid"> +// 备注信息可能也会很长,需要自动换行来适应内容 +// </td> +// </tr> +// {/* 其他行 */} +// </tbody> +// </table> +// </div> +// ); +// } -function ProductsTable() { - return ( - <div className="mb-6"> - <table className="w-full text-sm border border-gray-300 table-fixed"> - <thead> - <tr className=""> - <th className="w-1/4 p-2 border border-gray-300 border-solid"> - 序号 - </th> - <th className="w-1/6 p-2 border border-gray-300 border-solid"> - 订单号 - </th> - <th className="w-1/6 p-2 border border-gray-300 border-solid"> - 货品名称 - </th> - <th className="w-1/12 p-2 border border-gray-300 border-solid"> - 规格 - </th> - <th className="w-1/6 p-2 border border-gray-300 border-solid"> - 单位 - </th> - <th className="w-1/6 p-2 border border-gray-300 border-solid"> - 数量 - </th> - <th className="w-1/4 p-2 border border-gray-300 border-solid"> - 备注 - </th> - </tr> - </thead> - <tbody> - <tr> - <td className="p-2 whitespace-normal border border-gray-300 border-solid"> - 产品名称可能非常长,所以这里会自动换行 - </td> - <td className="p-2 border border-gray-300 border-solid"> - 规格型号 - </td> - <td className="p-2 border border-gray-300 border-solid">单位</td> - <td className="p-2 border border-gray-300 border-solid">1</td> - <td className="p-2 border border-gray-300 border-solid">400</td> - <td className="p-2 border border-gray-300 border-solid">400</td> - <td className="p-2 whitespace-normal border border-gray-300 border-solid"> - 备注信息可能也会很长,需要自动换行来适应内容 - </td> - </tr> - {/* 其他行 */} - </tbody> - </table> - </div> - ); -} - -function Footer() { - return ( - <div className="text-sm"> - <p>备注: 一些备注文本...</p> - <div className="flex items-center justify-between mt-4"> - <div> - <p>销售人员: 签字</p> - </div> - <div> - <p>业务员: 签字</p> - </div> - <div> - <p>开票人: 签字</p> - <p className="font-medium">总计: ¥400</p> - </div> - </div> - </div> - ); -} +// function Footer() { +// return ( +// <div className="text-sm"> +// <p>备注: 一些备注文本...</p> +// <div className="flex items-center justify-between mt-4"> +// <div> +// <p>销售人员: 签字</p> +// </div> +// <div> +// <p>业务员: 签字</p> +// </div> +// <div> +// <p>开票人: 签字</p> +// <p className="font-medium">总计: ¥400</p> +// </div> +// </div> +// </div> +// ); +// } function App() { return ( <div className="flex items-center justify-center min-h-screen bg-gray-100"> <div className="w-full max-w-4xl p-10 bg-white border border-gray-300"> - <Header /> - <InvoiceDetails /> - <ProductsTable /> - <Footer /> + <table + width="846" + border={0} + cellPadding={0} + cellSpacing={0} + style={{ + width: '423.00pt', + borderCollapse: 'collapse', + tableLayout: 'fixed', + }} + > + <col + width="25.50" + style={{ msoWidthSource: 'userset', msoWidthAlt: 544 }} + /> + <col + width="52.50" + style={{ msoWidthSource: 'userset', msoWidthAlt: 1120 }} + /> + <col + width="115.50" + style={{ msoWidthSource: 'userset', msoWidthAlt: 2464 }} + /> + <col + width="169.50" + style={{ msoWidthSource: 'userset', msoWidthAlt: 3616 }} + /> + <col + width="165" + style={{ msoWidthSource: 'userset', msoWidthAlt: 3520 }} + /> + <col + width="96" + style={{ msoWidthSource: 'userset', msoWidthAlt: 2048 }} + /> + <col + width="114" + style={{ msoWidthSource: 'userset', msoWidthAlt: 2432 }} + /> + <col width="108" style={{ width: '54.00pt' }} /> + <tr height="42" style={{ height: '21.00pt' }}> + <td height="42" style={{ height: '21.00pt' }}></td> + <td + className="xl65" + colSpan="7" + style={{ borderRight: 'none', borderBottom: 'none' }} + > + 科 路 得 + </td> + </tr> + <tr height="30" style={{ height: '15.00pt' }}> + <td height="30" style={{ height: '15.00pt' }}></td> + <td + className="xl66" + colSpan="7" + style={{ borderRight: 'none', borderBottom: 'none' }} + > + 网址:www.canrd.com + </td> + </tr> + <tr height="35" style={{ height: '17.50pt' }}> + <td height="35" style={{ height: '17.50pt' }}></td> + <td + className="xl67" + colSpan="7" + style={{ borderRight: 'none', borderBottom: 'none' }} + > + 销售出货单 + </td> + </tr> + <tr height="30" style={{ height: '15.00pt' }}> + <td height="30" style={{ height: '15.00pt' }}></td> + <td + className="xl69" + colSpan="4" + style={{ borderRight: 'none', borderBottom: 'none' }} + > + 单位名称:武汉大学 + </td> + <td + className="xl69" + colSpan="3" + style={{ borderRight: 'none', borderBottom: 'none' }} + > + 单号:Canrd-DZ-2023-1101-004 + </td> + </tr> + <tr height="30" style={{ height: '15.00pt' }}> + <td height="30" style={{ height: '15.00pt' }}></td> + <td + className="xl69" + colSpan="4" + style={{ borderRight: 'none', borderBottom: 'none' }} + > + 联系人:陈程 + </td> + <td + className="xl69" + colSpan="3" + style={{ borderRight: 'none', borderBottom: 'none' }} + > + 开单日期:2023年11月1日 + </td> + </tr> + <tr height="30" style={{ height: '15.00pt' }}> + <td height="30" style={{ height: '15.00pt' }}></td> + <td + className="xl69" + colSpan="4" + style={{ borderRight: 'none', borderBottom: 'none' }} + > + 联系电话:15623543176-6556 + </td> + <td + className="xl70" + colSpan={2} + style={{ msoIgnore: 'colspan' }} + ></td> + <td className="xl70"></td> + </tr> + <tr height="30" style={{ height: '15.00pt' }}> + <td height="30" style={{ height: '15.00pt' }}></td> + <td + className="xl69" + colSpan="7" + style={{ borderRight: 'none', borderBottom: 'none' }} + > + 送货地址:广东省 深圳市龙岗区吉华街道联创科产业园3期33幢刘荣华[ + </td> + </tr> + <tr height="30" style={{ height: '15.00pt' }}> + <td height="30" style={{ height: '15.00pt' }}></td> + <td className="xl71">序号</td> + <td className="xl71">订单号</td> + <td className="xl71">货品名称</td> + <td className="xl71">规格</td> + <td className="xl71">单位</td> + <td className="xl71">数量</td> + <td className="xl71">备注</td> + </tr> + <tr height="30" style={{ height: '15.00pt' }}> + <td height="30" style={{ height: '15.00pt' }}></td> + <td className="xl72">1</td> + <td className="xl72">231101005</td> + <td className="xl71">纽扣电池检测夹具</td> + <td className="xl71">20系列</td> + <td className="xl71">个</td> + <td className="xl72">1</td> + <td className="xl72"></td> + </tr> + <tr height="30" style={{ height: '15.00pt' }}> + <td height="30" style={{ height: '15.00pt' }}></td> + <td className="xl72">2</td> + <td className="xl72">231101005</td> + <td className="xl72">笔记本</td> + <td className="xl72"></td> + <td className="xl72">本</td> + <td className="xl72"></td> + <td className="xl72"></td> + </tr> + <tr height="30" style={{ height: '15.00pt' }}> + <td height="30" style={{ height: '15.00pt' }}></td> + <td className="xl72"></td> + <td className="xl72"></td> + <td className="xl72"></td> + <td className="xl71"></td> + <td className="xl71"></td> + <td className="xl72"></td> + <td className="xl72"></td> + </tr> + <tr height="30" style={{ height: '15.00pt' }}> + <td height="30" style={{ height: '15.00pt' }}></td> + <td className="xl72"></td> + <td className="xl72"></td> + <td className="xl72"></td> + <td className="xl72"></td> + <td className="xl72"></td> + <td className="xl72"></td> + <td className="xl72"></td> + </tr> + <tr height="30" style={{ height: '15.00pt' }}> + <td height="30" style={{ height: '15.00pt' }}></td> + <td className="xl72"></td> + <td className="xl72"></td> + <td className="xl72"></td> + <td className="xl72"></td> + <td className="xl72"></td> + <td className="xl72"></td> + <td className="xl72"></td> + </tr> + <tr height="30" style={{ height: '15.00pt' }}> + <td height="30" style={{ height: '15.00pt' }}></td> + <td className="xl72"></td> + <td className="xl72"></td> + <td className="xl72"></td> + <td className="xl72"></td> + <td className="xl72"></td> + <td className="xl72"></td> + <td className="xl72"></td> + </tr> + <tr style={{ height: '19.00pt' }}> + <td style={{ height: '19.00pt' }}></td> + <td className="xl73">销货单位</td> + <td + className="xl74" + colSpan="3" + style={{ + borderRight: '0.5pt solid windowtext', + borderBottom: '0.5pt solid windowtext', + }} + > + 发货地址:广东省东莞市厚街镇锦丰路9号科路得产业园 + </td> + <td className="xl73">开户银行及账号</td> + <td + className="xl74" + colSpan={2} + style={{ + borderRight: '0.5pt solid windowtext', + borderBottom: '0.5pt solid windowtext', + }} + > + 招商银行股份有限公司东莞东骏路支行 + <br /> + 账号:769906437110802 + </td> + </tr> + <tr style={{ height: 30 }}> + <td height="30" style={{ height: '15.00pt' }}></td> + <td className="xl76" colSpan={2} style={{ msoIgnore: 'colspan' }}> + 客户签名: + </td> + <td className="xl76">核准:屠亚辉</td> + <td + className="xl78" + colSpan={2} + style={{ borderRight: 'none', borderBottom: 'none' }} + > + 业务员:Peter + </td> + <td + className="xl78" + colSpan={2} + style={{ borderRight: 'none', borderBottom: 'none' }} + > + 开单人:张玉红 + </td> + </tr> + <tr style={{ display: 'none', width: 0 }}> + <td width="26" style={{ width: 13 }}></td> + <td width="53" style={{ width: 26 }}></td> + <td width="116" style={{ width: 58 }}></td> + <td width="170" style={{ width: 85 }}></td> + <td width="165" style={{ width: 83 }}></td> + <td width="96" style={{ width: 48 }}></td> + <td width="114" style={{ width: 57 }}></td> + </tr> + </table> </div> </div> ); diff --git a/src/utils/index.ts b/src/utils/index.ts index 2a83aa1..e0a76e9 100644 --- a/src/utils/index.ts +++ b/src/utils/index.ts @@ -16,4 +16,14 @@ function enumValueToLabel(value: any, enumObj: any) { return ''; } -export { customMessage, enumToSelect, enumValueToLabel }; +//从缓存中获取用户信息 +function getUserInfo() { + let userInfoString = localStorage.getItem('userInfo'); + if (userInfoString === null) { + return {}; + } + + return JSON.parse(userInfoString); +} + +export { customMessage, enumToSelect, enumValueToLabel, getUserInfo };