|
|
@@ -1,28 +1,285 @@ |
|
|
|
import React from 'react'; |
|
|
|
import React, { useState, useEffect } from 'react'; |
|
|
|
import { PageContainer } from '@ant-design/pro-layout'; |
|
|
|
import { Button, Card, DatePicker } from 'antd'; |
|
|
|
import { Card, Col, Row, message } from 'antd'; |
|
|
|
import ConditionQuery from "../../../components/ConditionQuery"; |
|
|
|
import * as echarts from 'echarts'; |
|
|
|
import moment from 'moment'; |
|
|
|
import styles from './index.less'; |
|
|
|
const { RangePicker } = DatePicker; |
|
|
|
import reportAPI from "./service"; |
|
|
|
/** |
|
|
|
* 营收报表 |
|
|
|
* 营销报表 |
|
|
|
* @returns |
|
|
|
*/ |
|
|
|
export default function Index() { |
|
|
|
|
|
|
|
//日期选择下标:0:今天、1:昨天、2:近7天、3、近30天 |
|
|
|
const [searchDayIndex, setSearchDayIndex] = useState(0); |
|
|
|
//日期选择器 |
|
|
|
const [timeRange, setTimeRange] = useState([ |
|
|
|
moment(moment(new Date(Date.now())).format('YYYY-MM-DD 00:00:00')), |
|
|
|
moment(moment(new Date(Date.now())).format('YYYY-MM-DD 23:59:59')) |
|
|
|
]); |
|
|
|
//组织树 |
|
|
|
const [orgTree, setOrgTree] = useState([]); |
|
|
|
//加载中 |
|
|
|
const [showLoading, setShowLoading] = useState(false); |
|
|
|
//当前选中门店 |
|
|
|
const [currentOrg, setCurrentOrg] = useState(""); |
|
|
|
//营销活动 |
|
|
|
const [reportActivity, setReportActivity] = useState([]); |
|
|
|
//营销优惠券 |
|
|
|
const [reportCoupon, setReportCoupon] = useState([]); |
|
|
|
|
|
|
|
//活动报表图表实例 |
|
|
|
let activityEcharts = null; |
|
|
|
//优惠券报表图表实例 |
|
|
|
let couponEcharts = null; |
|
|
|
|
|
|
|
//切换时间 |
|
|
|
const onChangeTimeIndex = (dayIndex) => { |
|
|
|
setSearchDayIndex(dayIndex); |
|
|
|
let tempDate = []; |
|
|
|
switch (dayIndex) { |
|
|
|
case 0: |
|
|
|
tempDate = [ |
|
|
|
moment(moment(new Date(Date.now())).format('YYYY-MM-DD 00:00:00')), |
|
|
|
moment(moment(new Date(Date.now())).format('YYYY-MM-DD 23:59:59')) |
|
|
|
] |
|
|
|
break; |
|
|
|
case 1: |
|
|
|
tempDate = [ |
|
|
|
moment(moment(new Date(Date.now() - 24 * 60 * 60 * 1000)).format('YYYY-MM-DD 00:00:00')), |
|
|
|
moment(moment(new Date(Date.now() - 24 * 60 * 60 * 1000)).format('YYYY-MM-DD 23:59:59')) |
|
|
|
] |
|
|
|
break; |
|
|
|
case 2: |
|
|
|
tempDate = [ |
|
|
|
moment(moment(new Date(Date.now() - 24 * 60 * 60 * 1000 * 7)).format('YYYY-MM-DD 00:00:00')), |
|
|
|
moment(moment(new Date(Date.now())).format('YYYY-MM-DD 23:59:59')), |
|
|
|
] |
|
|
|
break; |
|
|
|
case 3: |
|
|
|
tempDate = [ |
|
|
|
moment(moment(new Date(Date.now() - 24 * 60 * 60 * 1000 * 30)).format('YYYY-MM-DD 00:00:00')), |
|
|
|
moment(moment(new Date(Date.now())).format('YYYY-MM-DD 23:59:59')), |
|
|
|
] |
|
|
|
break; |
|
|
|
} |
|
|
|
setTimeRange(tempDate); |
|
|
|
} |
|
|
|
|
|
|
|
//获取组织树 |
|
|
|
const onGetOrgTree = async () => { |
|
|
|
setShowLoading(true); |
|
|
|
const response = await reportAPI.getOrgTree(); |
|
|
|
setShowLoading(false); |
|
|
|
if (response.statusCode === 200) { |
|
|
|
const originTree = response.data; |
|
|
|
onSetOrgTreeStatus(originTree); |
|
|
|
setOrgTree(originTree); |
|
|
|
} else { |
|
|
|
message.error(response.errors || '获取组织树出错'); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
//设置组织树不可选择状态 |
|
|
|
const onSetOrgTreeStatus = (originTree) => { |
|
|
|
originTree.forEach(treeItem => { |
|
|
|
if (treeItem.children && treeItem.children.length > 0) { |
|
|
|
onSetOrgTreeStatus(treeItem.children); |
|
|
|
} else { |
|
|
|
if (treeItem.type === 2 || treeItem.type === 3) { |
|
|
|
treeItem.disabled = false; |
|
|
|
} else { |
|
|
|
treeItem.disabled = true; |
|
|
|
} |
|
|
|
} |
|
|
|
}); |
|
|
|
} |
|
|
|
|
|
|
|
//重置 |
|
|
|
const onResetSearch = () => { |
|
|
|
setCurrentOrg(""); |
|
|
|
} |
|
|
|
|
|
|
|
//子组件切换组织架构 |
|
|
|
const onCurrentOrgChange = (curOrg) => { |
|
|
|
setCurrentOrg(curOrg) |
|
|
|
} |
|
|
|
|
|
|
|
//子组件时间改变 |
|
|
|
const onTimePickerChange = (nowTimeRange) => { |
|
|
|
setTimeRange(nowTimeRange); |
|
|
|
} |
|
|
|
|
|
|
|
//获取营销报表列表 |
|
|
|
const onQueryMarketing = async () => { |
|
|
|
setShowLoading(true); |
|
|
|
const response = await reportAPI.getReportStatisticsMarketing(); |
|
|
|
setShowLoading(false); |
|
|
|
if (response.statusCode === 200) { |
|
|
|
setReportActivity(response.data.activity); |
|
|
|
setReportCoupon(response.data.coupon); |
|
|
|
} else { |
|
|
|
message.error(response.errors || '获取营销报表列表出错'); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
//生成营销报表活动信息柱状图 |
|
|
|
const initActivityEcharts = () => { |
|
|
|
const chartDom = document.getElementById('activity-echarts'); |
|
|
|
activityEcharts = echarts.init(chartDom); |
|
|
|
const xAxisData = []; |
|
|
|
const seriesData = []; |
|
|
|
reportActivity.forEach(item => { |
|
|
|
xAxisData.push(item.activityName); |
|
|
|
seriesData.push(item.numberParticipants); |
|
|
|
}); |
|
|
|
const option = { |
|
|
|
title: { |
|
|
|
text: '活动报表' |
|
|
|
}, |
|
|
|
tooltip: { |
|
|
|
trigger: 'axis' |
|
|
|
}, |
|
|
|
toolbox: { |
|
|
|
feature: { |
|
|
|
saveAsImage: {} |
|
|
|
} |
|
|
|
}, |
|
|
|
xAxis: { |
|
|
|
type: 'category', |
|
|
|
data: xAxisData |
|
|
|
}, |
|
|
|
yAxis: { |
|
|
|
type: 'value' |
|
|
|
}, |
|
|
|
series: [ |
|
|
|
{ |
|
|
|
data: seriesData, |
|
|
|
type: 'bar', |
|
|
|
showBackground: true, |
|
|
|
backgroundStyle: { |
|
|
|
color: 'rgba(180, 180, 180, 0.2)' |
|
|
|
} |
|
|
|
} |
|
|
|
] |
|
|
|
}; |
|
|
|
|
|
|
|
option && activityEcharts.setOption(option); |
|
|
|
} |
|
|
|
|
|
|
|
//生成优惠券报表折线图 |
|
|
|
const initCouponEcharts = () => { |
|
|
|
const chartDom = document.getElementById('coupon-ehcarts'); |
|
|
|
couponEcharts = echarts.init(chartDom); |
|
|
|
const xAxisData = []; |
|
|
|
const seriesPreferentialAmount = []; |
|
|
|
const seriesSend = []; |
|
|
|
const seriesGet = []; |
|
|
|
reportCoupon.forEach(item => { |
|
|
|
xAxisData.push(item.couponName); |
|
|
|
seriesPreferentialAmount.push(item.preferentialAmount); |
|
|
|
seriesSend.push(item.send); |
|
|
|
seriesGet.push(item.get); |
|
|
|
}); |
|
|
|
const option = { |
|
|
|
title: { |
|
|
|
text: '优惠券报表' |
|
|
|
}, |
|
|
|
tooltip: { |
|
|
|
trigger: 'axis' |
|
|
|
}, |
|
|
|
legend: { |
|
|
|
data: ['优惠金额', '发放数量', '领取数量'] |
|
|
|
}, |
|
|
|
grid: { |
|
|
|
left: '3%', |
|
|
|
right: '4%', |
|
|
|
bottom: '3%', |
|
|
|
containLabel: true |
|
|
|
}, |
|
|
|
toolbox: { |
|
|
|
feature: { |
|
|
|
saveAsImage: {} |
|
|
|
} |
|
|
|
}, |
|
|
|
xAxis: { |
|
|
|
type: 'category', |
|
|
|
boundaryGap: false, |
|
|
|
data: xAxisData |
|
|
|
}, |
|
|
|
yAxis: { |
|
|
|
type: 'value' |
|
|
|
}, |
|
|
|
series: [ |
|
|
|
{ |
|
|
|
name: '优惠金额', |
|
|
|
type: 'line', |
|
|
|
stack: 'Total', |
|
|
|
data: seriesPreferentialAmount |
|
|
|
}, |
|
|
|
{ |
|
|
|
name: '发放数量', |
|
|
|
type: 'line', |
|
|
|
stack: 'Total', |
|
|
|
data: seriesSend |
|
|
|
}, |
|
|
|
{ |
|
|
|
name: '领取数量', |
|
|
|
type: 'line', |
|
|
|
stack: 'Total', |
|
|
|
data: seriesGet |
|
|
|
} |
|
|
|
] |
|
|
|
}; |
|
|
|
option && couponEcharts.setOption(option); |
|
|
|
} |
|
|
|
|
|
|
|
useEffect(() => { |
|
|
|
onGetOrgTree(); |
|
|
|
onQueryMarketing(); |
|
|
|
}, []); |
|
|
|
|
|
|
|
useEffect(() => { |
|
|
|
initActivityEcharts(); |
|
|
|
initCouponEcharts(); |
|
|
|
window.onresize = () => { |
|
|
|
if (activityEcharts && couponEcharts) { |
|
|
|
activityEcharts.resize(); |
|
|
|
couponEcharts.resize(); |
|
|
|
} |
|
|
|
} |
|
|
|
}, [reportActivity, reportCoupon]); |
|
|
|
|
|
|
|
|
|
|
|
return ( |
|
|
|
<PageContainer> |
|
|
|
<Card className={styles['data-search-card']}> |
|
|
|
<div className={styles['data-search-box']}> |
|
|
|
<RangePicker /> |
|
|
|
<div className={styles['data-search-btns']}> |
|
|
|
<Button className={styles['search-btn-item']}>重置</Button> |
|
|
|
<Button className={styles['search-btn-item']} type="primary">查询</Button> |
|
|
|
</div> |
|
|
|
</div> |
|
|
|
</Card> |
|
|
|
<Card className={styles['table-card']}> |
|
|
|
营收报表 |
|
|
|
</Card> |
|
|
|
<ConditionQuery |
|
|
|
orgTree={orgTree} |
|
|
|
timeRange={timeRange} |
|
|
|
searchDayIndex={searchDayIndex} |
|
|
|
currentOrg={currentOrg} |
|
|
|
showLoading={showLoading} |
|
|
|
onTimePickerChange={onTimePickerChange} |
|
|
|
onChangeTimeIndex={onChangeTimeIndex} |
|
|
|
onCurrentOrgChange={onCurrentOrgChange} |
|
|
|
onResetSearch={onResetSearch} |
|
|
|
onQueryBtn={onQueryMarketing} |
|
|
|
> |
|
|
|
</ConditionQuery> |
|
|
|
<Row gutter={10}> |
|
|
|
<Col xs={24} sm={24} md={24} lg={8} xl={8}> |
|
|
|
<Card> |
|
|
|
<div id="activity-echarts" className={styles['activity-echarts']}></div> |
|
|
|
</Card> |
|
|
|
</Col> |
|
|
|
<Col xs={24} sm={24} md={24} lg={16} xl={16}> |
|
|
|
<Card> |
|
|
|
<div id="coupon-ehcarts" className={styles['coupon-ehcarts']}></div> |
|
|
|
</Card> |
|
|
|
</Col> |
|
|
|
</Row> |
|
|
|
</PageContainer> |
|
|
|
) |
|
|
|
} |