570 lines
25 KiB
TypeScript
570 lines
25 KiB
TypeScript
import { connect } from "umi";
|
||
import type { CurrentUser } from "umi";
|
||
import type { ConnectState } from "@/models/connect";
|
||
import React, { useRef, useState } from "react";
|
||
import ProCard from "@ant-design/pro-card";
|
||
import { MenuFoldOutlined } from "@ant-design/icons";
|
||
import type { FormInstance } from "antd";
|
||
import { Button, Col, Descriptions, message, Modal, Row, Space, Spin, Table, Tree, Typography } from "antd";
|
||
import useRequest from "@ahooksjs/use-request";
|
||
import { getServerpartTree } from "@/services/options";
|
||
import type { ActionType } from "@ant-design/pro-table";
|
||
import ProTable from "@ant-design/pro-table";
|
||
import ReactHTMLTableToExcel from "react-html-table-to-excel";
|
||
import LeftSelectTree from "@/pages/reports/settlementAccount/component/leftSelectTree";
|
||
import PageTitleBox from "@/components/PageTitleBox";
|
||
import moment from "moment";
|
||
import Draggable from "react-draggable";
|
||
import ModalFooter from "@/pages/travelMember/scenicSpotConfig/component/modalFooter";
|
||
import ProForm, { ProFormDatePicker, ProFormDateTimePicker, ProFormDigit, ProFormMoney, ProFormSelect, ProFormText, ProFormTextArea } from "@ant-design/pro-form";
|
||
import session from "@/utils/session";
|
||
import { handleGetServiceShopList } from "@/pages/DataVerification/service";
|
||
import shop from "@/pages/BussinessProject/shop";
|
||
import { getMyShopList } from "@/pages/account/center/sevice";
|
||
import { handleGetRECEIVESERVERPARTList } from "../service";
|
||
import WarehouseInfo from "./components/warehouseInfo";
|
||
import { exportXlsxFromProColumnsExcelJS } from "@/utils/exportExcelFun";
|
||
import { formatTreeData } from "@/utils/format";
|
||
|
||
const { Text } = Typography;
|
||
|
||
const shopProcurement: React.FC<{ currentUser: CurrentUser }> = (props) => {
|
||
const { currentUser } = props
|
||
const actionRef = useRef<ActionType>();
|
||
const formRef = useRef<FormInstance>();
|
||
const downloadBtnRef = useRef<any>()
|
||
const modalFormRef = useRef<any>();
|
||
// 查询的条件
|
||
const [searchParams, setSearchParams] = useState<any>()
|
||
// 显示申请的modal
|
||
const [handleShowModal, setHandleShowModal] = useState<boolean>(false)
|
||
// 树相关的属性和方法
|
||
const [selectedId, setSelectedId] = useState<string>()
|
||
const [collapsible, setCollapsible] = useState<boolean>(false)
|
||
// 行数据
|
||
const [currentRow, setCurrentRow] = useState<any>()
|
||
const [disabled, setDraggleDisabled] = useState<boolean>() // 是否拖动
|
||
const [confirmLoading, handleConfirmLoading] = useState<boolean>(false) // 弹出框的内容表单是否在提交
|
||
// 弹出框拖动效果
|
||
const [bounds, setBounds] = useState<{ left: number, right: number, top: number, bottom: number }>() // 移动的位置
|
||
const draggleRef = React.createRef<any>()
|
||
// 门店列表
|
||
const [shopList, setShopList] = useState<any>([])
|
||
const [printIndex, setPrintIndex] = useState<number>(new Date().getTime())
|
||
// 导出的加载效果
|
||
const [showLoading, setShowLoading] = useState<boolean>(false)
|
||
// 是否显示打印的表格
|
||
const [showExportTable, setShowExportTable] = useState<boolean>(false)
|
||
const [reqDetailList, setReqDetailList] = useState<any>(); // 合计项数据源
|
||
// 表格的合计值
|
||
const [tableSumObj, setTableSumObj] = useState<any>();
|
||
// 表格加载效果
|
||
const [tableLoading, setTableLoading] = useState<boolean>(false)
|
||
|
||
|
||
const onDraggaleStart = (event, uiData) => {
|
||
const { clientWidth, clientHeight } = window.document.documentElement;
|
||
const targetRect = draggleRef.current?.getBoundingClientRect();
|
||
if (!targetRect) {
|
||
return;
|
||
}
|
||
setBounds({
|
||
left: -targetRect.left + uiData.x,
|
||
right: clientWidth - (targetRect.right - uiData.x),
|
||
top: -targetRect.top + uiData.y,
|
||
bottom: clientHeight - (targetRect.bottom - uiData.y),
|
||
});
|
||
};
|
||
// 当前的门店列表
|
||
const [currentShopList, setCurrentShopList] = useState<any>()
|
||
// 显示详情的悬浮框
|
||
const [showDetail, setShowDetail] = useState<boolean>(false)
|
||
|
||
const columns: any = [
|
||
// {
|
||
// title: "服务区",
|
||
// dataIndex: "servicePartId",
|
||
// hideInTable: true,
|
||
// valueType: 'select',
|
||
// fieldProps: {
|
||
// showSearch: true,
|
||
// onChange: async (value: any, label: any) => {
|
||
// formRef.current?.setFieldsValue({ serverpartShopId: undefined, InventoryTime: undefined })
|
||
// await handleGetShopList(value)
|
||
// }
|
||
// },
|
||
// request: async () => {
|
||
// const list = session.get('ServerpartIdsTree')
|
||
// return list || []
|
||
// },
|
||
// },
|
||
// {
|
||
// title: "门店",
|
||
// dataIndex: "serverpartShopId",
|
||
// hideInTable: true,
|
||
// valueType: 'select',
|
||
// fieldProps: {
|
||
// showSearch: true,
|
||
// options: currentShopList,
|
||
// }
|
||
// },
|
||
{
|
||
dataIndex: 'searchText',
|
||
title: '查询内容',
|
||
hideInTable: true,
|
||
fieldProps: {
|
||
placeholder: "请输入商品名称/商品条码"
|
||
}
|
||
},
|
||
{
|
||
title: '查询时间',
|
||
dataIndex: 'search_date',
|
||
valueType: 'dateRange',
|
||
hideInTable: true,
|
||
hideInDescriptions: true,
|
||
search: {
|
||
transform: (value) => {
|
||
return {
|
||
RECEIVECENTER_DATE_Start: value[0],
|
||
RECEIVECENTER_DATE_End: value[1],
|
||
};
|
||
},
|
||
},
|
||
fieldProps: {
|
||
ranges: {
|
||
"本月": [moment().startOf('M'), moment()],
|
||
"上月": [moment().subtract(1, 'M').startOf('M'), moment().subtract(1, 'M').endOf('M')],
|
||
"近三月": [moment().subtract(3, 'M').startOf('M'), moment().endOf('M')],
|
||
"近半年": [moment().subtract(6, 'M').startOf('M'), moment().endOf('M')],
|
||
}
|
||
},
|
||
initialValue: [moment().startOf('M'), moment()],
|
||
},
|
||
|
||
{
|
||
title: "序号",
|
||
dataIndex: "index",
|
||
valueType: 'index',
|
||
align: 'center',
|
||
width: 80,
|
||
ellipsis: true,
|
||
hideInSearch: true,
|
||
},
|
||
{
|
||
title: <div style={{ textAlign: 'center' }}>服务区名</div>,
|
||
dataIndex: "SERVERPART_NAME",
|
||
align: 'left',
|
||
width: 150,
|
||
ellipsis: true,
|
||
hideInSearch: true,
|
||
},
|
||
{
|
||
title: <div style={{ textAlign: 'center' }}>门店方向</div>,
|
||
dataIndex: "SHOPNAME",
|
||
align: 'left',
|
||
width: 150,
|
||
ellipsis: true,
|
||
hideInSearch: true,
|
||
},
|
||
{
|
||
title: '入库单号',
|
||
dataIndex: "RECEIVECENTER_CODE",
|
||
align: 'center',
|
||
width: 150,
|
||
ellipsis: true,
|
||
hideInSearch: true,
|
||
render: (_, record) => {
|
||
return record?.RECEIVECENTER_CODE ?
|
||
<a onClick={() => {
|
||
setCurrentRow(record)
|
||
setShowDetail(true)
|
||
}}>{record?.RECEIVECENTER_CODE}</a> :
|
||
"-"
|
||
}
|
||
},
|
||
{
|
||
title: "单据状态",
|
||
dataIndex: "RECEIVECENTER_STATE",
|
||
align: 'center',
|
||
valueType: 'select',
|
||
valueEnum: {
|
||
"1000": "订单发起申请",
|
||
"2000": "总部业务审核",
|
||
"3000": "总部订单配送",
|
||
"4000": "订单入库审核",
|
||
"5000": "订单商品入库",
|
||
},
|
||
width: 120,
|
||
hideInSearch: true,
|
||
ellipsis: true,
|
||
},
|
||
{
|
||
title: <div style={{ textAlign: 'center' }}>采购说明</div>,
|
||
dataIndex: "RECEIVESERVERPART_DESC",
|
||
align: 'left',
|
||
width: 200,
|
||
ellipsis: true,
|
||
hideInSearch: true,
|
||
},
|
||
// {
|
||
// title: '采购模式',
|
||
// dataIndex: "PURCHASE_PATTERN",
|
||
// align: 'center',
|
||
// valueType: 'select',
|
||
// valueEnum: {
|
||
// "0": "铺货",
|
||
// "1000": "订货",
|
||
// "2000": "补货",
|
||
// "3000": "退货",
|
||
// },
|
||
// width: 120,
|
||
// hideInSearch: true,
|
||
// ellipsis: true,
|
||
// },
|
||
{
|
||
title: <div style={{ textAlign: 'center' }}>入库总数</div>,
|
||
dataIndex: "RECEIVE_TOTALCOUNT",
|
||
align: 'right',
|
||
valueType: 'digit',
|
||
width: 120,
|
||
sorter: true,
|
||
// sorter: (a, b) => a.RECEIVE_TOTALCOUNT - b.RECEIVE_TOTALCOUNT,
|
||
defaultSortOrder: 'descend',
|
||
ellipsis: true,
|
||
hideInSearch: true,
|
||
},
|
||
{
|
||
title: <div style={{ textAlign: 'center' }}>入库金额</div>,
|
||
dataIndex: "RECEIVE_TOTALPRICE",
|
||
align: 'right',
|
||
valueType: 'digit',
|
||
width: 120,
|
||
sorter: true,
|
||
// sorter: (a, b) => a.RECEIVE_TOTALPRICE - b.RECEIVE_TOTALPRICE,
|
||
ellipsis: true,
|
||
hideInSearch: true,
|
||
},
|
||
{
|
||
title: '入库时间',
|
||
dataIndex: "RECEIVECENTER_DATE",
|
||
align: 'center',
|
||
width: 150,
|
||
sorter: true,
|
||
// sorter: (a, b) => new Date(a?.RECEIVECENTER_DATE).getTime() - new Date(b?.RECEIVECENTER_DATE).getTime(),
|
||
ellipsis: true,
|
||
hideInSearch: true,
|
||
},
|
||
|
||
// {
|
||
// title: '单据类型',
|
||
// dataIndex: "PURCHASE_TYPE",
|
||
// align: 'center',
|
||
// valueType: 'select',
|
||
// valueEnum: {
|
||
// "1000": "自采单",
|
||
// "4000": "统配单"
|
||
// },
|
||
// hideInSearch: true,
|
||
// width: 150,
|
||
// ellipsis: true,
|
||
// }
|
||
]
|
||
|
||
const exportTable = (e) => {
|
||
e.stopPropagation(); // 防止Collapse组件收起
|
||
const main = document.getElementsByClassName(`saleReportHideBox${printIndex}`)[0]
|
||
const thead = main.querySelector('thead').cloneNode(true); // 深克隆DOM节点
|
||
const tbody = main.querySelector('tbody').cloneNode(true); // 深克隆DOM节点
|
||
const container = document.querySelector('#hiddenBox');
|
||
|
||
const tempTable = document.createElement('table');
|
||
tempTable.appendChild(thead);
|
||
tempTable.appendChild(tbody);
|
||
|
||
tempTable.setAttribute('id', 'table-to-xls-shopProcurement'); // 给table添加id,值与按钮上的table字段对应
|
||
|
||
container.appendChild(tempTable); // 把创建的节点添加到页面容器中
|
||
|
||
setShowLoading(false)
|
||
|
||
downloadBtnRef.current.handleDownload();
|
||
setShowExportTable(false)
|
||
tempTable.remove() // 防止重复打印一个内容
|
||
}
|
||
|
||
// 拿到服务区 对应的门店列表数据
|
||
const handleGetShopList = async (id: any) => {
|
||
if (!id) {
|
||
setCurrentShopList([])
|
||
return
|
||
}
|
||
const req: any = {
|
||
// 调用的接口 里面 自己包了一层
|
||
// SearchParameter: {
|
||
ISVALID: 1,
|
||
SERVERPART_ID: id,
|
||
INSALES_TYPE: 1,
|
||
// },
|
||
PageIndex: 1,
|
||
PageSize: 999999,
|
||
SortStr: "SHOPTRADE,SHOPREGION,SHOPCODE"
|
||
}
|
||
const data = await getMyShopList(req)
|
||
let list: any = []
|
||
if (data && data.length > 0) {
|
||
data.forEach((item: any) => {
|
||
list.push({ label: item.SHOPNAME, value: item.SERVERPARTSHOP_ID })
|
||
})
|
||
}
|
||
setCurrentShopList(list)
|
||
}
|
||
|
||
// 关闭详情执行的方法
|
||
const handleGetClose = () => {
|
||
setCurrentRow(null)
|
||
setShowDetail(false)
|
||
}
|
||
|
||
return (
|
||
<div>
|
||
{
|
||
showLoading ?
|
||
<div
|
||
style={{
|
||
width: '100%',
|
||
height: '100%',
|
||
background: 'rgba(0,0,0,0.1)',
|
||
position: 'fixed',
|
||
zIndex: 5,
|
||
display: 'flex',
|
||
alignItems: 'center',
|
||
justifyContent: 'center'
|
||
}}
|
||
>
|
||
<div style={{
|
||
display: 'flex',
|
||
alignItems: 'center',
|
||
justifyContent: 'center',
|
||
padding: '15px 20px 10px',
|
||
background: '#fff',
|
||
borderRadius: '8px',
|
||
width: '200px'
|
||
}}>
|
||
<Spin />
|
||
<span style={{ marginLeft: '5px' }}>数据导出中...</span>
|
||
</div>
|
||
</div> : ''
|
||
}
|
||
|
||
<div className={`saleReportHideBox${printIndex}`} style={{ position: 'fixed', zIndex: -1, top: 0, left: 0 }}>
|
||
{
|
||
showExportTable && reqDetailList && reqDetailList.length > 0 ?
|
||
<ProTable
|
||
columns={columns}
|
||
dataSource={reqDetailList}
|
||
pagination={false}
|
||
expandable={{
|
||
defaultExpandAllRows: true
|
||
}}
|
||
/> : ''
|
||
}
|
||
</div>
|
||
<div id='hiddenBox' style={{ position: 'fixed', zIndex: -1, top: 0, left: 0 }} />
|
||
|
||
<div style={{ backgroundColor: '#fff', display: 'flex' }}>
|
||
<LeftSelectTree setSelectedId={setSelectedId} setCollapsible={setCollapsible} collapsible={collapsible} pageType={'ahjg'} collapsibleTitle={'请选择门店'} />
|
||
|
||
<div style={{
|
||
width: !collapsible ? 'calc(100% - 300px)' : 'calc(100% - 60px)',
|
||
paddingTop: 0,
|
||
paddingBottom: 0,
|
||
paddingRight: 0
|
||
}}>
|
||
<ProTable
|
||
actionRef={actionRef}
|
||
formRef={formRef}
|
||
columns={columns}
|
||
bordered
|
||
expandable={{
|
||
expandRowByClick: true
|
||
}}
|
||
loading={tableLoading}
|
||
scroll={{ x: "100%", y: "calc(100vh - 520px)" }}
|
||
headerTitle={<PageTitleBox props={props} />} // 列表表头
|
||
search={{ span: 6, defaultCollapsed: false }} // 查询表单
|
||
request={async (params, sorter) => {
|
||
if (!selectedId) {
|
||
return
|
||
}
|
||
// 排序字段
|
||
const sortstr = Object.keys(sorter).map(n => {
|
||
const value = sorter[n]
|
||
return value ? `${n} ${value.replace('end', '')}` : ''
|
||
})
|
||
const req: any = {
|
||
SearchParameter: {
|
||
SERVERPARTSHOP_IDS: selectedId,
|
||
RECEIVECENTER_DATE_Start: params?.RECEIVECENTER_DATE_Start || "",
|
||
RECEIVECENTER_DATE_End: params?.RECEIVECENTER_DATE_End || "",
|
||
SearchOtherKeyName: "COMMODITY_NAME,COMMODITY_BARCODE",
|
||
SearchOtherKeyValue: params?.searchText || '',
|
||
},
|
||
// keyWord: {
|
||
// Key: 'RECEIVECENTER_CODE',
|
||
// Value: params?.searchText || ''
|
||
// },
|
||
PageIndex: 1,
|
||
PageSize: 999999,
|
||
sortstr: sortstr.length ? sortstr.toString() : "",
|
||
}
|
||
setSearchParams(params)
|
||
setTableLoading(true)
|
||
const data = await handleGetRECEIVESERVERPARTList(req)
|
||
setTableLoading(false)
|
||
console.log('表格数据', data);
|
||
|
||
|
||
let fieldData: any = [
|
||
"RECEIVE_TOTALCOUNT",
|
||
"RECEIVE_TOTALPRICE",
|
||
]
|
||
|
||
|
||
let enumList: any = []
|
||
let newPrintData: any = formatTreeData(JSON.parse(JSON.stringify(data)), fieldData, enumList, [], [])
|
||
|
||
setReqDetailList(newPrintData)
|
||
if (data && data.length > 0) {
|
||
// 总数合计
|
||
let RECEIVE_TOTALCOUNTSUM: number = 0
|
||
// 金额合计
|
||
let RECEIVE_TOTALPRICESUM: number = 0
|
||
data.forEach((item: any) => {
|
||
RECEIVE_TOTALCOUNTSUM += item.RECEIVE_TOTALCOUNT
|
||
RECEIVE_TOTALPRICESUM += item.RECEIVE_TOTALPRICE
|
||
})
|
||
setTableSumObj({
|
||
RECEIVE_TOTALCOUNT: Number(RECEIVE_TOTALCOUNTSUM.toFixed(2)),
|
||
RECEIVE_TOTALPRICE: Number(RECEIVE_TOTALPRICESUM.toFixed(2))
|
||
})
|
||
return { data, success: true }
|
||
}
|
||
return { data: [], success: true }
|
||
}}
|
||
toolbar={{
|
||
actions: [
|
||
<span style={{ visibility: 'hidden' }}>
|
||
<ReactHTMLTableToExcel
|
||
buttonText={'导出excel'}
|
||
ref={downloadBtnRef}
|
||
table="table-to-xls-shopProcurement"
|
||
filename={`商品入库统计表${searchParams?.RECEIVECENTER_DATE_Start}-${searchParams?.RECEIVECENTER_DATE_End}`}
|
||
sheet="sheet1"
|
||
/>
|
||
</span>,
|
||
<Button
|
||
key="new"
|
||
type="primary"
|
||
onClick={(e) => {
|
||
if (reqDetailList && reqDetailList.length > 0) {
|
||
// 尝试一下 导出新方法
|
||
exportXlsxFromProColumnsExcelJS(columns,
|
||
reqDetailList,
|
||
`商品入库统计表${searchParams?.RECEIVECENTER_DATE_Start}-${searchParams?.RECEIVECENTER_DATE_End}`,
|
||
{
|
||
topTitle: `商品入库统计表`, // 顶部大标题
|
||
}
|
||
)
|
||
} else {
|
||
message.error('暂无数据可导出!')
|
||
}
|
||
|
||
|
||
// if (reqDetailList && reqDetailList.length > 0) {
|
||
// setShowLoading(true)
|
||
// setTimeout(() => {
|
||
// setShowExportTable(true)
|
||
// setTimeout(() => {
|
||
// exportTable(e)
|
||
// }, 100)
|
||
// }, 100)
|
||
// } else {
|
||
// message.error('暂无数据可导出!')
|
||
// }
|
||
}}
|
||
>
|
||
导出excel
|
||
</Button>
|
||
// <Button type={'primary'} onClick={() => {
|
||
// setHandleShowModal(true)
|
||
// }}>填写申请</Button>
|
||
]
|
||
}}
|
||
tableExtraRender={
|
||
(_, data) => {
|
||
return <div style={{ paddingLeft: 24 }}>
|
||
<Descriptions
|
||
size="small" column={5}
|
||
className="commity-sale-description"
|
||
contentStyle={{ fontWeight: "bolder" }} labelStyle={{ color: "#00000073" }}
|
||
>
|
||
<Descriptions.Item label="入库总数">{tableSumObj?.RECEIVE_TOTALCOUNT ? tableSumObj?.RECEIVE_TOTALCOUNT.toLocaleString('zh-CN') : ""}<Text
|
||
type="secondary"> </Text></Descriptions.Item>
|
||
<Descriptions.Item label="入库金额">{tableSumObj?.RECEIVE_TOTALPRICE ? tableSumObj?.RECEIVE_TOTALPRICE.toLocaleString('zh-CN') : ""}<Text
|
||
type="secondary"> </Text></Descriptions.Item>
|
||
</Descriptions>
|
||
</div>
|
||
}
|
||
}
|
||
summary={(pageData) => {
|
||
// 总数合计
|
||
let RECEIVE_TOTALCOUNTSUM: number = 0
|
||
// 金额合计
|
||
let RECEIVE_TOTALPRICESUM: number = 0
|
||
|
||
if (pageData && pageData.length > 0) {
|
||
pageData.forEach((item: any) => {
|
||
RECEIVE_TOTALCOUNTSUM += item.RECEIVE_TOTALCOUNT
|
||
RECEIVE_TOTALPRICESUM += item.RECEIVE_TOTALPRICE
|
||
})
|
||
}
|
||
return (
|
||
<Table.Summary fixed="top">
|
||
<Table.Summary.Row>
|
||
<Table.Summary.Cell index={0} colSpan={3}>
|
||
<div style={{ textAlign: 'center', fontWeight: 600 }}>本页合计</div>
|
||
</Table.Summary.Cell>
|
||
<Table.Summary.Cell index={1}></Table.Summary.Cell>
|
||
<Table.Summary.Cell index={2}></Table.Summary.Cell>
|
||
<Table.Summary.Cell index={3}></Table.Summary.Cell>
|
||
<Table.Summary.Cell index={4}>
|
||
<div style={{ textAlign: 'right' }}>
|
||
{RECEIVE_TOTALCOUNTSUM ? Number(RECEIVE_TOTALCOUNTSUM.toFixed(2)).toLocaleString('zh-CN') : ''}
|
||
</div>
|
||
</Table.Summary.Cell>
|
||
<Table.Summary.Cell index={5}>
|
||
<div style={{ textAlign: 'right' }}>
|
||
{RECEIVE_TOTALPRICESUM ? Number(RECEIVE_TOTALPRICESUM.toFixed(2)).toLocaleString('zh-CN') : ''}
|
||
</div>
|
||
</Table.Summary.Cell>
|
||
<Table.Summary.Cell index={6}></Table.Summary.Cell>
|
||
</Table.Summary.Row>
|
||
</Table.Summary>
|
||
)
|
||
}}
|
||
/>
|
||
</div>
|
||
</div>
|
||
|
||
|
||
|
||
{/* 说是要里面高亮 查询的内容 那么就要传入 searchParams */}
|
||
<WarehouseInfo onShow={showDetail} parentRow={currentRow} onCencel={handleGetClose} searchParams={searchParams} />
|
||
</div>
|
||
)
|
||
}
|
||
|
||
export default connect(({ user }: ConnectState) => ({
|
||
currentUser: user.currentUser
|
||
}))(shopProcurement);
|