// 收银员统计表 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, message, Space, Spin, Tree } from "antd"; import useRequest from "@ahooksjs/use-request"; import { getServerpartTree, handleGetServiceShopTreeList } 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 { handleGetPERSONSELLList } from "@/pages/reports/BusinessAnalysis/personSellReport/service"; import moment from "moment"; import ProDescriptions from "@ant-design/pro-descriptions"; import numeral from "numeral"; import { contractType } from "@/pages/contract/emun"; import { handleGetShopShortNamesGet } from "@/pages/reports/BusinessAnalysis/transactionAnalysis/service"; import PageTitleBox from "@/components/PageTitleBox"; import { exportXlsxFromProColumnsExcelJS } from "@/utils/exportExcelFun"; import { formatTreeData } from "@/utils/format"; const personSellReport: React.FC<{ currentUser: CurrentUser }> = (props) => { const { currentUser } = props const downloadBtnRef = useRef() const actionRef = useRef(); const formRef = useRef(); const [reqDetailList, setReqDetailList] = useState(); // 合计项数据源 const [printOut, setPrintOut] = useState(); // 打印数据的内容 const [collapsible, setCollapsible] = useState(false) const [treeView, setTreeView] = useState() // 加载服务区树 const { loading: treeLoading, data: treeViews } = useRequest(async () => { const data = await handleGetServiceShopTreeList({ ProvinceCode: currentUser?.ProvinceCode, BusinessState: "1000,2000,3000", ShowState: true, SortStr: 'BUSINESS_STATE,SHOPSHORTNAME' }); setTreeView(data) return data }) // 树相关的属性和方法 const [selectedId, setSelectedId] = useState() // 导出的加载效果 const [showLoading, setShowLoading] = useState(false) // 是否显示打印的表格 const [showExportTable, setShowExportTable] = useState(false) // 自营业态的选择列表 const [shopNamesList, setShopNamesList] = useState() // 表格数据 const [tableData, setTableData] = useState() // 自营业态的选择的列表方法 const handleGetShopNamesList = async (id: any) => { const req: any = { ProvinceCode: currentUser?.USER_PROVINCE, BusinessType: 1000, ServerpartId: id || selectedId } const data = await handleGetShopShortNamesGet(req) console.log('data', data) if (data && data.length > 0) { const obj: any = {} if (data && data.length > 0) { data.forEach((item: any) => { obj[item] = item }) } setShopNamesList(obj) } } const columns: any = [ { title: '统计时间', dataIndex: 'search_date', valueType: 'dateTimeRange', hideInTable: true, hideInDescriptions: true, colSize: 1, initialValue: [moment(`${moment().add(-1, 'day').format('YYYY-MM-DD')} 12:00:00`).format('YYYY-MM-DD hh:mm:ss'), moment(`${moment().format('YYYY-MM-DD')} 12:00:00`).format('YYYY-MM-DD hh:mm:ss')], search: { transform: (value) => { return { SELL_ENDDATE_Start: value[0], SELL_ENDDATE_End: value[1], }; }, }, fieldProps: { disabledDate: (current: any) => current && current < moment() } }, { title: '经营模式', key: 'BusinessType', dataIndex: 'BusinessType', valueType: 'select', valueEnum: contractType, hideInTable: true, }, { title: '自营业态', dataIndex: 'shopNames', hideInTable: true, valueType: 'select', valueEnum: shopNamesList, // request: async () => { // return await getFieldEnum({ FieldExplainField: 'BUSINESSTYPE' }) // }, fieldProps: { multiple: true, showSearch: true, filterOption: (input, option) => (option?.label ?? '').toLowerCase().includes(input.toLowerCase()), } }, { title: '序号', dataIndex: 'index', align: 'center', width: 90, hideInSearch: true, }, { title: '服务区名称', dataIndex: 'SERVERPART_NAME', align: 'center', width: 150, hideInSearch: true, }, { title:
门店名称
, dataIndex: 'SHOPNAME', align: 'left', width: 200, ellipsis: true, hideInSearch: true, }, { title: '交班时间', dataIndex: 'SELL_ENDDATE', width: 150, align: 'center', hideInSearch: true, }, { title:
客单数量
, dataIndex: 'TICKETCOUNT', width: 120, align: 'right', valueType: 'digit', hideInSearch: true, }, { title:
销售数量
, dataIndex: 'TOTALCOUNT', width: 120, align: 'right', valueType: 'digit', hideInSearch: true, }, { title:
优惠金额
, dataIndex: 'TOTALOFFAMOUNT', width: 120, valueType: 'digit', align: 'right', hideInSearch: true, }, { title:
实收金额
, dataIndex: 'RealActualCashpay', width: 120, valueType: 'digit', align: 'right', hideInSearch: true, }, { title:
对客营收
, dataIndex: 'TOTALSELLAMOUNT', width: 120, valueType: 'digit', align: 'right', hideInSearch: true, }, { title:
缴款金额
, dataIndex: 'CASHPAY', width: 120, valueType: 'digit', align: 'right', hideInSearch: true, }, { title:
现金支付
, dataIndex: 'CASH', width: 120, valueType: 'digit', align: 'right', hideInSearch: true, }, { title:
长短款
, dataIndex: 'DIFFERENT_PRICE', width: 120, valueType: 'digit', align: 'right', hideInSearch: true, }, { title:
移动支付
, dataIndex: 'MobilyPay', width: 120, valueType: 'digit', align: 'right', hideInSearch: true, }, { title: '机器号码', dataIndex: 'MACHINECODE', align: 'center', width: 120, hideInSearch: true, }, { title: '收银员工号', dataIndex: 'CASHWORKER_CODE', align: 'center', width: 140, hideInSearch: true, }, { title: '收银员名称', dataIndex: 'CASHIER_NAME', width: 140, align: 'center', hideInSearch: true, }, ] const exportTable = (e) => { e.stopPropagation(); // 防止Collapse组件收起 const main = document.getElementsByClassName('saleReportHideBox')[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-personSellReport'); // 给table添加id,值与按钮上的table字段对应 container.appendChild(tempTable); // 把创建的节点添加到页面容器中 setShowLoading(false) downloadBtnRef.current.handleDownload(); setShowExportTable(false) tempTable.remove() // 防止重复打印一个内容 } // 查询的条件 const [searchParams, setSearchParams] = useState() return (
{ // 打印报表 if (!reqDetailList || reqDetailList.length === 0) return; setPrintOut(el); }} > { showLoading ?
数据导出中...
: '' }
{ showExportTable && reqDetailList && reqDetailList.length > 0 ? : '' }
{ setCollapsible(!collapsible) }} />} colSpan={!collapsible ? "300px" : "60px"} title={!collapsible ? "请选择服务区" : ""} headerBordered collapsed={collapsible} > {treeView && treeView.length > 0 ? { const selectedIds = info.checkedNodes.filter(n => n?.type === 2) setSelectedId(selectedIds.map(n => n?.value)?.toString() || '') handleGetShopNamesList(selectedIds.map(n => n?.value)?.toString() || '') // actionRef?.current?.reload() // getData(selectedIds.map(n => n?.value)?.toString() || '') }} // switcherIcon={} /> : ''}
} search={{ span: 8, defaultCollapsed: false }} request={async (params) => { if (!selectedId) { return } const req = { SearchParameter: { ...params, SHOPCODES: selectedId }, PageIndex: 1, PageSize: 999999, SortStr: 'SELL_ENDDATE desc' } setSearchParams(params) console.log('req', req) const data = await handleGetPERSONSELLList(req) if (data.List && data.List.length > 0) { const list: any = [] data.List.forEach((item: any, index: number) => { item.index = index + 1 list.push(item) }) list.unshift({ ...data.OtherData, SERVERPART_NAME: '合计' }) console.log('list', list) let fieldData: any = [ "TICKETCOUNT", "TOTALCOUNT", "TOTALOFFAMOUNT", "RealActualCashpay", "TOTALSELLAMOUNT", "CASHPAY", "CASH", "DIFFERENT_PRICE", "MobilyPay", ] let enumList: any = [] let newPrintData: any = formatTreeData(JSON.parse(JSON.stringify(list)), fieldData, enumList, [], []) setReqDetailList(newPrintData) setTableData(list) return { data: list, success: true } } setReqDetailList([]) setTableData([]) return { data: [], success: true } }} toolbar={{ actions: [ // // // , ] }} tableExtraRender={() => { if (tableData && tableData.length > 0) { let TICKETCOUNTSum: number = 0 let TOTALCOUNTSum: number = 0 let TOTALOFFAMOUNTSum: number = 0 let RealActualCashpaySum: number = 0 let TOTALSELLAMOUNTSum: number = 0 let CASHPAYSum: number = 0 let CASHSum: number = 0 let DIFFERENT_PRICESum: number = 0 let MobilyPaySum: number = 0 tableData.forEach((item: any) => { TICKETCOUNTSum += item.TICKETCOUNT TOTALCOUNTSum += item.TOTALCOUNT TOTALOFFAMOUNTSum += item.TOTALOFFAMOUNT RealActualCashpaySum += item.RealActualCashpay TOTALSELLAMOUNTSum += item.TOTALSELLAMOUNT CASHPAYSum += item.CASHPAY CASHSum += item.CASH DIFFERENT_PRICESum += item.DIFFERENT_PRICE MobilyPaySum += item.MobilyPay }) return
{TICKETCOUNTSum ? numeral(TICKETCOUNTSum).format('0,0') : '0'} {TOTALCOUNTSum ? numeral(TOTALCOUNTSum).format('0,0') : '0'} {TOTALOFFAMOUNTSum || '0.00'} {RealActualCashpaySum || '0.00'} {TOTALSELLAMOUNTSum || '0.00'} {CASHPAYSum || '0.00'} {CASHSum || '0.00'} {DIFFERENT_PRICESum || '0.00'} {MobilyPaySum || '0.00'} {`${moment(searchParams?.SELL_ENDDATE_Start).format('YYYY-MM-DD HH时')}至${moment(searchParams?.SELL_ENDDATE_End).format('YYYY-MM-DD HH时')}`}
} }} />
) } export default connect(({ user }: ConnectState) => ({ currentUser: user.currentUser }))(personSellReport);