508 lines
27 KiB
TypeScript
508 lines
27 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 { Drawer } from "antd";
|
||
import { Button, message, Space, Spin, Tree } from "antd";
|
||
import useRequest from "@ahooksjs/use-request";
|
||
import { getFieldEnum, 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 { handleGetServerPartShopNewList, handleSynchroServerPartShopNew } from "./service";
|
||
import session from "@/utils/session";
|
||
import moment from 'moment'
|
||
import Detail from "./component/detail";
|
||
import PageTitleBox from "@/components/PageTitleBox";
|
||
|
||
|
||
const serviceArea: React.FC<{ currentUser: CurrentUser }> = (props) => {
|
||
const { currentUser } = props
|
||
const downloadBtnRef = useRef<any>()
|
||
const detailChildrenRef = useRef<any>()
|
||
const actionRef = useRef<ActionType>();
|
||
const formRef = useRef<FormInstance>();
|
||
const [reqDetailList, setReqDetailList] = useState<any>(); // 合计项数据源
|
||
const [printOut, setPrintOut] = useState<any>(); // 打印数据的内容
|
||
const [collapsible, setCollapsible] = useState<boolean>(false)
|
||
const [treeView, setTreeView] = useState<any>()
|
||
const [printIndex, setPrintIndex] = useState<number>(new Date().getTime())
|
||
|
||
// 加载服务区树
|
||
const { loading: treeLoading, data: treeViews } = useRequest(async () => {
|
||
const data = await getServerpartTree(currentUser?.ProvinceCode, currentUser?.CityAuthority, true, true, true)
|
||
setTreeView(data)
|
||
return data
|
||
})
|
||
const businessTypeObj = session.get('BUSINESSTYPEObj')
|
||
const businessStateObj = session.get('businessStateObj')
|
||
// 树相关的属性和方法
|
||
const [selectedId, setSelectedId] = useState<string>()
|
||
// 导出的加载效果
|
||
const [showLoading, setShowLoading] = useState<boolean>(false)
|
||
// 是否显示打印的表格
|
||
const [showExportTable, setShowExportTable] = useState<boolean>(false)
|
||
// 显示添加和编辑的抽屉
|
||
const [showDetailDrawer, setShowDetailDrawer] = useState<boolean>(false)
|
||
// 点击行的数据
|
||
const [currentRow, setCurrentRow] = useState<any>()
|
||
// 抽屉的类型 编辑还是新增
|
||
const [drawerType, setDrawerType] = useState<string>('')
|
||
// 新增和编辑的保存的loading效果
|
||
const [btnLoading, setBtnLoading] = useState<boolean>(false)
|
||
|
||
const columns: any = [
|
||
{
|
||
title: '商品业态',
|
||
width: 120,
|
||
align: 'center',
|
||
dataIndex: 'SHOPTRADE',
|
||
hideInSearch: true,
|
||
valueType: 'select',
|
||
request: async () => {
|
||
return await getFieldEnum({ FieldExplainField: 'BUSINESSTYPE', sessionName: 'BUSINESSTYPE', notformate: true });
|
||
},
|
||
},
|
||
{
|
||
title: '经营品牌',
|
||
width: 120,
|
||
align: 'center',
|
||
dataIndex: 'BRAND_NAME',
|
||
hideInSearch: true,
|
||
},
|
||
{
|
||
title: '服务区名称',
|
||
width: 150,
|
||
align: 'center',
|
||
ellipsis: true,
|
||
dataIndex: 'SERVERPART_NAME',
|
||
hideInSearch: true,
|
||
},
|
||
{
|
||
title: <div style={{ textAlign: 'center' }}>门店名称</div>,
|
||
width: 300,
|
||
dataIndex: 'SHOPNAME',
|
||
align: 'left',
|
||
ellipsis: true,
|
||
hideInSearch: true,
|
||
render: (_, record) => {
|
||
return <a onClick={() => {
|
||
console.log('record', record);
|
||
setDrawerType('edit')
|
||
setCurrentRow(record)
|
||
setShowDetailDrawer(true)
|
||
}}>{record?.SHOPNAME || ''}</a>
|
||
}
|
||
},
|
||
{
|
||
width: 150,
|
||
title: '停业时间',
|
||
align: 'center',
|
||
dataIndex: 'BUSINESS_ENDDATE',
|
||
hideInSearch: true,
|
||
render: (_, record) => {
|
||
return record?.BUSINESS_ENDDATE ? moment(record?.BUSINESS_ENDDATE).format('YYYY-MM-DD') : '-'
|
||
}
|
||
},
|
||
{
|
||
width: 150,
|
||
title: '经营模式',
|
||
align: 'center',
|
||
dataIndex: 'BUSINESS_TYPE',
|
||
valueType: 'select',
|
||
valueEnum: businessTypeObj
|
||
},
|
||
{
|
||
width: 150,
|
||
title: '经营状态',
|
||
dataIndex: 'BUSINESS_STATE',
|
||
valueType: 'select',
|
||
align: 'center',
|
||
valueEnum: businessStateObj,
|
||
render: (_, record) => {
|
||
return <div style={{ display: 'flex', alignItems: 'center', justifyContent: 'center' }}>
|
||
<div style={{ display: 'flex', justifyContent: 'flex-start', alignItems: 'center', marginRight: '12px' }}>
|
||
<span className={record?.BUSINESS_STATE === 1000 ? 'ant-badge-status-dot ant-badge-status-processing' :
|
||
record?.BUSINESS_STATE === 1010 ? 'ant-badge-status-dot ant-badge-status-default' :
|
||
record?.BUSINESS_STATE === 2000 ? 'ant-badge-status-dot ant-badge-status-warning' :
|
||
record?.BUSINESS_STATE === 3000 ? 'ant-badge-status-dot ant-badge-status-error'
|
||
: ''}></span>
|
||
</div>
|
||
<span>{record?.BUSINESS_STATE ? businessStateObj[record?.BUSINESS_STATE] : ''}</span>
|
||
</div>
|
||
}
|
||
},
|
||
{
|
||
width: 150,
|
||
title: '经营单位',
|
||
dataIndex: 'BUSINESS_UNIT',
|
||
align: 'center',
|
||
hideInSearch: 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-serviceArea'); // 给table添加id,值与按钮上的table字段对应
|
||
|
||
container.appendChild(tempTable); // 把创建的节点添加到页面容器中
|
||
|
||
setShowLoading(false)
|
||
|
||
downloadBtnRef.current.handleDownload();
|
||
setShowExportTable(false)
|
||
tempTable.remove() // 防止重复打印一个内容
|
||
}
|
||
// 查询的条件
|
||
const [searchParams, setSearchParams] = useState<any>()
|
||
|
||
return (
|
||
<div ref={(el) => {
|
||
// 打印报表
|
||
if (!reqDetailList || reqDetailList.length === 0) return;
|
||
setPrintOut(el);
|
||
}} >
|
||
|
||
{
|
||
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' }}>
|
||
<ProCard
|
||
style={{ width: !collapsible ? "300px" : "60px" }}
|
||
className="pageTable-leftnav"
|
||
bodyStyle={{ padding: 0, paddingTop: 20, paddingLeft: 20, width: !collapsible ? "300px" : "60px" }}
|
||
extra={<MenuFoldOutlined onClick={() => {
|
||
setCollapsible(!collapsible)
|
||
}} />}
|
||
colSpan={!collapsible ? "300px" : "60px"}
|
||
title={!collapsible ? "请选择服务区" : ""}
|
||
headerBordered
|
||
collapsed={collapsible}
|
||
>
|
||
{treeView && treeView.length > 0 ? <Tree
|
||
checkable
|
||
treeData={[{
|
||
label: '全部',
|
||
value: 0,
|
||
key: '0-0',
|
||
children: treeView
|
||
}]}
|
||
fieldNames={{
|
||
title: "label",
|
||
key: "key"
|
||
}}
|
||
blockNode
|
||
defaultExpandedKeys={['0-0']}
|
||
onCheck={(checkedKeys: React.Key[] | any, info) => {
|
||
const selectedIds = info.checkedNodes.filter(n => n?.type === 1)
|
||
setSelectedId(selectedIds.map(n => n?.value)?.toString() || '')
|
||
// actionRef?.current?.reload()
|
||
// getData(selectedIds.map(n => n?.value)?.toString() || '')
|
||
}}
|
||
// switcherIcon={<PlusOutlined />}
|
||
/> : ''}
|
||
</ProCard>
|
||
<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
|
||
}}
|
||
headerTitle={<PageTitleBox props={props} />}
|
||
search={{ span: 6 }}
|
||
request={async (params) => {
|
||
if (!selectedId) {
|
||
return
|
||
}
|
||
|
||
setSearchParams(params)
|
||
|
||
console.log('params', params);
|
||
const req: any = {
|
||
serverPartId: selectedId || '',
|
||
businessState: params?.BUSINESS_STATE || '',
|
||
businessType: params?.BUSINESS_TYPE || ''
|
||
}
|
||
console.log('req', req);
|
||
const data = await handleGetServerPartShopNewList(req)
|
||
console.log('data', data);
|
||
if (data && data.length > 0) {
|
||
return { data, success: true }
|
||
}
|
||
return { data: [], success: true }
|
||
|
||
}}
|
||
toolbar={{
|
||
actions: [
|
||
<span style={{ visibility: 'hidden' }}>
|
||
<ReactHTMLTableToExcel
|
||
buttonText={'导出excel'}
|
||
ref={downloadBtnRef}
|
||
table="table-to-xls-serviceArea"
|
||
filename={`单品销售排行统计${searchParams?.StartDate}-${searchParams?.EndDate}`}
|
||
sheet="sheet1"
|
||
/>
|
||
</span>,
|
||
<Button
|
||
key="new"
|
||
type="primary"
|
||
onClick={(e) => {
|
||
if (reqDetailList && reqDetailList.length > 0) {
|
||
setShowLoading(true)
|
||
setTimeout(() => {
|
||
setShowExportTable(true)
|
||
setTimeout(() => {
|
||
exportTable(e)
|
||
}, 100)
|
||
}, 100)
|
||
} else {
|
||
message.error('暂无数据可导出!')
|
||
}
|
||
}}
|
||
>
|
||
导出excel
|
||
</Button>,
|
||
<Button type={"primary"} onClick={() => {
|
||
setShowDetailDrawer(true)
|
||
}}>
|
||
添加门店
|
||
</Button>
|
||
]
|
||
}}
|
||
/>
|
||
</div>
|
||
</div>
|
||
<Drawer
|
||
width="60%"
|
||
visible={showDetailDrawer} // 抽屉弹框是否显示状态
|
||
onClose={() => { // 关闭抽屉 则在清空选中行数据 并 设置抽屉状态为关闭
|
||
setDrawerType('')
|
||
setCurrentRow(undefined)
|
||
setShowDetailDrawer(false)
|
||
}}
|
||
bodyStyle={{ backgroundColor: "#f9f9f9", padding: 0 }}
|
||
closable={false}
|
||
destroyOnClose
|
||
footer={
|
||
<div style={{ width: '100%', display: 'flex', alignItems: 'center', justifyContent: 'flex-end', boxSizing: 'border-box', paddingRight: '16px' }}>
|
||
<Button loading={btnLoading} type='primary' onClick={() => {
|
||
detailChildrenRef?.current.formRef.current?.validateFields().then((res: any) => {
|
||
if (res) {
|
||
detailChildrenRef?.current.formSecondRef.current?.validateFields().then(async (result: any) => {
|
||
|
||
if (result) {
|
||
let req: any = {}
|
||
setBtnLoading(true)
|
||
if (drawerType === 'edit') {
|
||
|
||
console.log('detailChildrenRef', detailChildrenRef);
|
||
// 不是两个数据的数据
|
||
// 查到的详情数据 然后表格数据 顶掉查的相同字段的数据
|
||
const formDetail: any = detailChildrenRef?.current.formRef?.current.getFieldsValue()
|
||
const oldDetail: any = detailChildrenRef?.current.detailData?.ServerPartShop
|
||
const topDetail: any = {
|
||
...oldDetail,
|
||
...formDetail,
|
||
}
|
||
const selectType: number = detailChildrenRef?.current.radioValue
|
||
topDetail.BUSINESS_REGION = selectType === 2 ? 1000 : selectType === 1 ? 1010 : selectType === 4 ? 2000 : selectType === 3 ? 2010 : null
|
||
topDetail.BUSINESS_DATE = topDetail?.BUSINESS_DATE ? moment(topDetail?.BUSINESS_DATE).format('YYYY-MM-DD') : ''
|
||
topDetail.BUSINESS_ENDDATE = topDetail?.BUSINESS_ENDDATE ? moment(topDetail?.BUSINESS_ENDDATE).format('YYYY-MM-DD') : ''
|
||
|
||
console.log('topDetail', topDetail);
|
||
// 底部表格数据
|
||
const bottomTableData = detailChildrenRef?.current.tableData
|
||
// 中间表格数据
|
||
const midOldFormDataList: any = detailChildrenRef?.current.detailData.ShopBusinessStateList
|
||
const midFormData: any = detailChildrenRef?.current.formSecondRef?.current.getFieldsValue()
|
||
console.log('detailChildrenRef?.current.detailData', detailChildrenRef?.current.detailData);
|
||
console.log('中间的表格数据', midFormData);
|
||
|
||
const list: any = []
|
||
|
||
if (midOldFormDataList && midOldFormDataList.length > 0) {
|
||
midOldFormDataList.forEach((item: any, index: number) => {
|
||
if (index === 0) {
|
||
item.ShopRegion = midFormData.ShopRegion
|
||
item.ShopName = midFormData.ShopName
|
||
item.BusinessType = midFormData.BusinessType
|
||
item.BusinessState = midFormData.BusinessState
|
||
item.BusinessDate = midFormData.BusinessDate ? moment(midFormData.BusinessDate).format('YYYY-MM-DD') : ''
|
||
item.BusinessEndDate = midFormData.BusinessEndDate ? moment(midFormData.BusinessEndDate).format('YYYY-MM-DD') : ''
|
||
list.push(item)
|
||
} else if (index === 1) {
|
||
item.ShopRegion = midFormData.ShopRegionSecond
|
||
item.ShopName = midFormData.SHOPNAMESecond
|
||
item.BusinessType = midFormData.BUSINESS_TYPESecond
|
||
item.BusinessState = midFormData.BUSINESS_STATESecond
|
||
item.BusinessDate = midFormData.BusinessDateSecond ? moment(midFormData.BusinessDateSecond).format('YYYY-MM-DD') : ''
|
||
item.BusinessEndDate = midFormData.BusinessEndDateSecond ? moment(midFormData.BusinessEndDateSecond).format('YYYY-MM-DD') : ''
|
||
list.push(item)
|
||
}
|
||
})
|
||
}
|
||
|
||
|
||
req = {
|
||
ServerPartShop: {
|
||
...topDetail,
|
||
STAFF_ID: currentUser?.ID,
|
||
STAFF_NAME: currentUser?.Name,
|
||
OPERATE_DATE: moment().format('YYYY-MM-DD HH:mm:ss')
|
||
},
|
||
ShopBusinessStateList: list,
|
||
RtServerPartShopList: bottomTableData && bottomTableData.length > 0 ? bottomTableData : []
|
||
}
|
||
} else {
|
||
const formDetail: any = detailChildrenRef?.current.formRef?.current.getFieldsValue()
|
||
const selectType: number = detailChildrenRef?.current.radioValue
|
||
const topDetail: any = {
|
||
ISVALID: 1,
|
||
...formDetail,
|
||
}
|
||
topDetail.BUSINESS_REGION = selectType === 2 ? 1000 : selectType === 1 ? 1010 : selectType === 4 ? 2000 : selectType === 3 ? 2010 : null
|
||
const list: any = []
|
||
const midFormData: any = detailChildrenRef?.current.formSecondRef?.current.getFieldsValue()
|
||
if (selectType === 2 || selectType === 4) {
|
||
list.push(
|
||
{
|
||
ShopRegion: midFormData.ShopRegion,
|
||
ShopName: midFormData.ShopName,
|
||
BusinessType: midFormData.BusinessType,
|
||
BusinessState: midFormData.BusinessState,
|
||
BusinessDate: midFormData.BusinessDate ? moment(midFormData.BusinessDate).format('YYYY-MM-DD') : '',
|
||
BusinessEndDate: midFormData.BusinessEndDate ? moment(midFormData.BusinessEndDate).format('YYYY-MM-DD') : '',
|
||
}
|
||
)
|
||
list.push(
|
||
{
|
||
ShopRegion: midFormData.ShopRegionSecond,
|
||
ShopName: midFormData.SHOPNAMESecond,
|
||
BusinessType: midFormData.BUSINESS_TYPESecond,
|
||
BusinessState: midFormData.BUSINESS_STATESecond,
|
||
BusinessDate: midFormData.BusinessDateSecond ? moment(midFormData.BusinessDateSecond).format('YYYY-MM-DD') : '',
|
||
BusinessEndDate: midFormData.BusinessEndDateSecond ? moment(midFormData.BusinessEndDateSecond).format('YYYY-MM-DD') : '',
|
||
}
|
||
)
|
||
} else {
|
||
list.push(
|
||
{
|
||
ShopRegion: midFormData.ShopRegion,
|
||
ShopName: midFormData.ShopName,
|
||
BusinessType: midFormData.BusinessType,
|
||
BusinessState: midFormData.BusinessState,
|
||
BusinessDate: midFormData.BusinessDate ? moment(midFormData.BusinessDate).format('YYYY-MM-DD') : '',
|
||
BusinessEndDate: midFormData.BusinessEndDate ? moment(midFormData.BusinessEndDate).format('YYYY-MM-DD') : '',
|
||
}
|
||
)
|
||
}
|
||
|
||
console.log('reqListdsds', list);
|
||
req = {
|
||
ServerPartShop: {
|
||
...topDetail,
|
||
STAFF_ID: currentUser?.ID,
|
||
STAFF_NAME: currentUser?.Name,
|
||
OPERATE_DATE: moment().format('YYYY-MM-DD HH:mm:ss')
|
||
},
|
||
ShopBusinessStateList: list,
|
||
RtServerPartShopList: []
|
||
}
|
||
}
|
||
|
||
console.log('req', req);
|
||
|
||
const data = await handleSynchroServerPartShopNew(req)
|
||
console.log('data', data);
|
||
if (data.Result_Code === 100) {
|
||
message.success(data.Result_Desc)
|
||
// 关闭抽屉带的执行方法
|
||
setDrawerType('')
|
||
setCurrentRow(undefined)
|
||
setShowDetailDrawer(false)
|
||
actionRef.current?.reload()
|
||
} else {
|
||
message.error(data.Result_Desc)
|
||
}
|
||
setBtnLoading(false)
|
||
}
|
||
|
||
})
|
||
}
|
||
})
|
||
}}>{drawerType === 'edit' ? '保存' : '新增'}</Button>
|
||
</div>
|
||
|
||
}
|
||
>
|
||
<Detail onRef={detailChildrenRef} currentRow={currentRow} type={drawerType} showDrawer={showDetailDrawer} closeDrawer={setShowDetailDrawer} />
|
||
</Drawer>
|
||
</div>
|
||
)
|
||
}
|
||
|
||
export default connect(({ user }: ConnectState) => ({
|
||
currentUser: user.currentUser
|
||
}))(serviceArea);
|