diff --git a/config/routes.js b/config/routes.js index a5c011c..64dac7e 100644 --- a/config/routes.js +++ b/config/routes.js @@ -587,7 +587,7 @@ export default [ access: 'k31', }, { - name: '营销报表', + name: '营收报表', path: '/order/order-market-report', component: './order/order-market-report', access: 'k31', @@ -605,7 +605,7 @@ export default [ access: 'k31', }, { - name: '营收报表', + name: '营销报表', path: '/order/order-revenue-statement', component: './order/order-revenue-statement', access: 'k31', diff --git a/src/app.jsx b/src/app.jsx index 656335a..5855dc4 100644 --- a/src/app.jsx +++ b/src/app.jsx @@ -571,7 +571,7 @@ export async function getInitialState() { access: 'k32', }, { - name: '营销报表', + name: '营收报表', path: '/order/order-market-report', component: './order/order-market-report', access: 'k31', @@ -583,7 +583,7 @@ export async function getInitialState() { access: 'k31', }, { - name: '营收报表', + name: '营销报表', path: '/order/order-revenue-statement', component: './order/order-revenue-statement', access: 'k31', diff --git a/src/pages/order/order-market-report/index.jsx b/src/pages/order/order-market-report/index.jsx index b9403b5..ea52c2a 100644 --- a/src/pages/order/order-market-report/index.jsx +++ b/src/pages/order/order-market-report/index.jsx @@ -391,7 +391,7 @@ const LoadingCard = () => { } /** - * 营销报表 + * 营收报表 * @returns */ export default function Index() { diff --git a/src/pages/order/order-member-statement/index.jsx b/src/pages/order/order-member-statement/index.jsx index 38f1763..c0ca33d 100644 --- a/src/pages/order/order-member-statement/index.jsx +++ b/src/pages/order/order-member-statement/index.jsx @@ -149,6 +149,14 @@ export default function Index() { title: { text: '新增会员' }, + tooltip: { + trigger: 'axis' + }, + toolbox: { + feature: { + saveAsImage: {} + } + }, xAxis: { type: 'category', data: xAxisData @@ -191,6 +199,11 @@ export default function Index() { } } }, + toolbox: { + feature: { + saveAsImage: {} + } + }, xAxis: { type: 'category', data: xAxisData diff --git a/src/pages/order/order-product-report/index.jsx b/src/pages/order/order-product-report/index.jsx index 3fd206f..17a3110 100644 --- a/src/pages/order/order-product-report/index.jsx +++ b/src/pages/order/order-product-report/index.jsx @@ -154,6 +154,11 @@ export default function Index() { } } }, + toolbox: { + feature: { + saveAsImage: {} + } + }, xAxis: { type: 'category', data: xData @@ -184,6 +189,11 @@ export default function Index() { show: true, text: '热销商品' }, + toolbox: { + feature: { + saveAsImage: {} + } + }, tooltip: { trigger: 'axis', axisPointer: { diff --git a/src/pages/order/order-revenue-statement/index.jsx b/src/pages/order/order-revenue-statement/index.jsx index c2e0ebd..1d325ba 100644 --- a/src/pages/order/order-revenue-statement/index.jsx +++ b/src/pages/order/order-revenue-statement/index.jsx @@ -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 ( - -
- -
- - -
-
-
- - 营收报表 - + + + + + +
+
+ + + +
+
+ +
) } diff --git a/src/pages/order/order-revenue-statement/index.less b/src/pages/order/order-revenue-statement/index.less index 74d0c92..1fcef07 100644 --- a/src/pages/order/order-revenue-statement/index.less +++ b/src/pages/order/order-revenue-statement/index.less @@ -12,5 +12,7 @@ margin-left: 20px; } -.table-card { +.activity-echarts, .coupon-ehcarts { + width: 100%; + height: 300px; } \ No newline at end of file diff --git a/src/pages/order/order-revenue-statement/service.js b/src/pages/order/order-revenue-statement/service.js new file mode 100644 index 0000000..a079fa0 --- /dev/null +++ b/src/pages/order/order-revenue-statement/service.js @@ -0,0 +1,17 @@ +import { request } from 'umi'; + +export default { + //获取组织架构 + getOrgTree() { + return request(`/kitchen/api/report-statistics/org-tree`, { + method: 'GET', + }); + }, + + //获取营销报表 + getReportStatisticsMarketing() { + return request(`/kitchen/api/report-statistics/marketing`, { + method: 'POST', + }); + } +};