|
|
|
@ -1,6 +1,6 @@
|
|
|
|
|
import { useContext, useEffect, useState } from 'react';
|
|
|
|
|
import { observer } from 'mobx-react';
|
|
|
|
|
import { Row, Col, Spin, Space, Radio, Table } from 'antd';
|
|
|
|
|
import { Row, Col, Spin, Space, Radio, Table, Button } from 'antd';
|
|
|
|
|
import { CheckCircleTwoTone, MoneyCollectTwoTone, FlagTwoTone, SmileTwoTone } from '@ant-design/icons';
|
|
|
|
|
import { stores_Context } from '../config';
|
|
|
|
|
import StatisticCard2 from '../components/StatisticCard2';
|
|
|
|
@ -9,6 +9,7 @@ import Waterfall from '../components/Waterfall';
|
|
|
|
|
import MixTBWithKPI from './../components/MixTBWithKPI';
|
|
|
|
|
import Donut from './../components/Donut';
|
|
|
|
|
import MapCountry from './../components/MapCountry';
|
|
|
|
|
import LineWithKPI from '../components/LineWithKPI';
|
|
|
|
|
import DataFieldRadio from '../components/DataFieldRadio';
|
|
|
|
|
import { datePartOptions } from './../components/DateGroupRadio/date';
|
|
|
|
|
import SearchForm from './../components/search/SearchForm';
|
|
|
|
@ -17,11 +18,16 @@ import { dataFieldAlias } from './../libs/ht';
|
|
|
|
|
import './home.css';
|
|
|
|
|
|
|
|
|
|
const topSeries = [
|
|
|
|
|
{ key: 'dept', label: '小组', graphVisible: true },
|
|
|
|
|
{ key: 'operator', label: '顾问', graphVisible: true },
|
|
|
|
|
{ key: 'destination', label: '目的地', graphVisible: true },
|
|
|
|
|
{ key: 'GuestGroupType', label: '客群类别', graphVisible: false },
|
|
|
|
|
{ key: 'country', label: '国籍', graphVisible: true },
|
|
|
|
|
{ key: 'dept', value: 'dept', label: '小组', graphVisible: true },
|
|
|
|
|
{ key: 'operator', value: 'operator', label: '顾问', graphVisible: true },
|
|
|
|
|
{ key: 'destination', value: 'destination', label: '目的地', graphVisible: true },
|
|
|
|
|
{ key: 'GuestGroupType', value: 'GuestGroupType', label: '客群类别', graphVisible: false },
|
|
|
|
|
{ key: 'country', value: 'country', label: '国籍', graphVisible: true },
|
|
|
|
|
];
|
|
|
|
|
|
|
|
|
|
const allGroupTypes = [
|
|
|
|
|
{ key: 'overview', value: 'overview', label: '总额' },
|
|
|
|
|
...topSeries,
|
|
|
|
|
];
|
|
|
|
|
|
|
|
|
|
// const iconSets = [CheckCircleTwoTone, <MoneyCollectTwoTone />, <FlagTwoTone />, <ClockCircleTwoTone />, <DashboardTwoTone />,<SmileTwoTone />,];
|
|
|
|
@ -30,7 +36,7 @@ const iconSets = [CheckCircleTwoTone, MoneyCollectTwoTone, FlagTwoTone, SmileTwo
|
|
|
|
|
export default observer(() => {
|
|
|
|
|
// const navigate = useNavigate();
|
|
|
|
|
const { TradeStore, date_picker_store: searchFormStore } = useContext(stores_Context);
|
|
|
|
|
const { sideData, summaryData, BuData, topData, timeData, timeLineKey, targetTableProps } = TradeStore;
|
|
|
|
|
const { searchValues, sideData, summaryData, BuData, topData, timeData, timeLineKey, targetTableProps, timeDiffData, groupKey } = TradeStore;
|
|
|
|
|
const { formValues } = searchFormStore;
|
|
|
|
|
|
|
|
|
|
useEffect(() => {
|
|
|
|
@ -51,6 +57,7 @@ export default observer(() => {
|
|
|
|
|
TradeStore.resetData();
|
|
|
|
|
TradeStore.fetchSummaryData(Object.assign({}, queryData, { groupType }));
|
|
|
|
|
TradeStore.fetchTradeDataByDate(queryData);
|
|
|
|
|
TradeStore.fetchTradeDataDiffByDate(queryData);
|
|
|
|
|
// // TradeStore.fetchTradeDataByBU(queryData);
|
|
|
|
|
TradeStore.fetchTradeDataByMonth(queryData);
|
|
|
|
|
const topSeriesF = _overviewFlag ? topSeries : topSeries.filter((ele) => ele.key !== 'dept');
|
|
|
|
@ -133,7 +140,6 @@ export default observer(() => {
|
|
|
|
|
xAxis: {
|
|
|
|
|
type: 'cat',
|
|
|
|
|
},
|
|
|
|
|
// smooth: true,
|
|
|
|
|
point: {
|
|
|
|
|
size: 4,
|
|
|
|
|
shape: 'cicle',
|
|
|
|
@ -158,26 +164,38 @@ export default observer(() => {
|
|
|
|
|
TradeStore.setTimeLineKey(value);
|
|
|
|
|
if (!isEmpty(TradeStore.searchPayloadHome)) {
|
|
|
|
|
TradeStore.fetchTradeDataByDate({ groupType: groupTypeVal });
|
|
|
|
|
TradeStore.fetchTradeDataDiffByDate({ groupType: diffGroupKey });
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
const [diffGroupKey, setDiffGroupKey] = useState(groupKey);
|
|
|
|
|
const handleChangeDiffType = ({ target: { value } }) => {
|
|
|
|
|
console.log('diffGroupKey', diffGroupKey, value);
|
|
|
|
|
setDiffGroupKey(value);
|
|
|
|
|
TradeStore.setGroupKey(value);
|
|
|
|
|
if (!isEmpty(TradeStore.searchPayloadHome)) {
|
|
|
|
|
TradeStore.fetchTradeDataDiffByDate({ groupType: value });
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
const [showDiff, setShowDiff] = useState(false);
|
|
|
|
|
return (
|
|
|
|
|
<>
|
|
|
|
|
<Row gutter={16} className='sticky-top' >
|
|
|
|
|
<Row gutter={16} className="sticky-top">
|
|
|
|
|
<Col className="gutter-row" span={24}>
|
|
|
|
|
<SearchForm
|
|
|
|
|
defaultValue={{
|
|
|
|
|
initialValue: {
|
|
|
|
|
...formValues,
|
|
|
|
|
...searchValues,
|
|
|
|
|
},
|
|
|
|
|
shows: ['DateType', 'DepartmentList', 'WebCode', 'IncludeTickets', 'years'],
|
|
|
|
|
fieldProps: {
|
|
|
|
|
DepartmentList: { show_all: true },
|
|
|
|
|
WebCode: { show_all: true },
|
|
|
|
|
years: { hide_vs: true },
|
|
|
|
|
years: { hide_vs: false },
|
|
|
|
|
},
|
|
|
|
|
}}
|
|
|
|
|
onSubmit={(_err, obj, form, str) => {
|
|
|
|
|
TradeStore.setStateSearch(obj);
|
|
|
|
|
TradeStore.setSearch(obj, form);
|
|
|
|
|
pageRefresh(obj);
|
|
|
|
|
}}
|
|
|
|
|
/>
|
|
|
|
@ -185,7 +203,9 @@ export default observer(() => {
|
|
|
|
|
</Row>
|
|
|
|
|
<section>
|
|
|
|
|
<Space>
|
|
|
|
|
<h2>年度业绩<span style={{fontSize: 'small'}}> =传统+商务</span></h2>
|
|
|
|
|
<h2>
|
|
|
|
|
年度业绩<span style={{ fontSize: 'small' }}> =传统+商务</span>
|
|
|
|
|
</h2>
|
|
|
|
|
</Space>
|
|
|
|
|
<Spin spinning={summaryData.loading}>
|
|
|
|
|
<Row gutter={layoutProps.gutter}>
|
|
|
|
@ -195,7 +215,7 @@ export default observer(() => {
|
|
|
|
|
</Col>
|
|
|
|
|
))} */}
|
|
|
|
|
{summaryData.dataSource.map((item, i) => (
|
|
|
|
|
<Col {...layoutProps} key={item.title} lg={{span: ((item?.col || layoutProps.lg.span))}}>
|
|
|
|
|
<Col {...layoutProps} key={item.title} lg={{ span: item?.col || layoutProps.lg.span }}>
|
|
|
|
|
<StatisticCard2 {...item} showProgress={item.hasKPI} icon={iconSets[i]} />
|
|
|
|
|
</Col>
|
|
|
|
|
))}
|
|
|
|
@ -203,22 +223,41 @@ export default observer(() => {
|
|
|
|
|
</Spin>
|
|
|
|
|
</section>
|
|
|
|
|
<section>
|
|
|
|
|
<Space gutter={16} size={'large'}>
|
|
|
|
|
<h3>走势</h3>
|
|
|
|
|
<Space gutter={16} size={'small'}>
|
|
|
|
|
<h3>{showDiff === false ? '走势' : '对比'}</h3>
|
|
|
|
|
<DataFieldRadio value={timeDataField} onChange={handleChangetimeDataField} />
|
|
|
|
|
<Radio.Group options={datePartOptions} optionType="button" onChange={handleChangeDateType} value={dateField} />
|
|
|
|
|
{showDiff && <Radio.Group options={allGroupTypes} optionType="button" onChange={handleChangeDiffType} value={diffGroupKey} />}
|
|
|
|
|
{searchValues.yearDiff && (
|
|
|
|
|
<Button type="link" size={'small'} onClick={() => setShowDiff(!showDiff)}>
|
|
|
|
|
{showDiff === false ? '显示对比' : '返回总额'}
|
|
|
|
|
</Button>
|
|
|
|
|
)}
|
|
|
|
|
</Space>
|
|
|
|
|
<Spin spinning={timeData.loading}>
|
|
|
|
|
{/* <LineWithKPI dataSource={timeData.dataSource} {...lineConfig} /> */}
|
|
|
|
|
<MixTBWithKPI dataSource={timeData.dataSource} summaryData={timeData.origin?.summaryRows || []} {...lineConfig} />
|
|
|
|
|
</Spin>
|
|
|
|
|
{showDiff === false ? (
|
|
|
|
|
<Spin spinning={timeData.loading}>
|
|
|
|
|
<MixTBWithKPI dataSource={timeData.dataSource} summaryData={timeData.origin?.summaryRows || []} {...lineConfig} />
|
|
|
|
|
</Spin>
|
|
|
|
|
) : (
|
|
|
|
|
<Spin spinning={timeDiffData.loading}>
|
|
|
|
|
<LineWithKPI
|
|
|
|
|
dataSource={timeDiffData.dataSource}
|
|
|
|
|
showKPI={false}
|
|
|
|
|
{...lineConfig}
|
|
|
|
|
{...{ appendPadding: 10, legend: { position: 'right-top', title: { text: '虚线: 对比年份' } }, point: false }}
|
|
|
|
|
/>
|
|
|
|
|
</Spin>
|
|
|
|
|
)}
|
|
|
|
|
</section>
|
|
|
|
|
|
|
|
|
|
<section>
|
|
|
|
|
<h3>市场 (仅传统订单) </h3>
|
|
|
|
|
<Spin spinning={BuData.loading}>
|
|
|
|
|
<Spin spinning={sideData.loading}>
|
|
|
|
|
<Row gutter={layoutProps3.gutter}>
|
|
|
|
|
<Col {...layoutProps3}>
|
|
|
|
|
<><Donut {...{angleField: 'SumML', colorField: 'groupsLabel'}} title={formValues.DepartmentList?.label} dataSource={sideData.yearData} /></>
|
|
|
|
|
<>
|
|
|
|
|
<Donut {...{ angleField: 'SumML', colorField: 'groupsLabel' }} title={formValues.DepartmentList?.label} dataSource={sideData.yearData} />
|
|
|
|
|
</>
|
|
|
|
|
{/* {overviewFlag ? (
|
|
|
|
|
<>
|
|
|
|
|
<Bullet {...BUConfig} dataSource={BuData?.dataSource || []} />
|
|
|
|
@ -228,12 +267,14 @@ export default observer(() => {
|
|
|
|
|
<><Donut {...{angleField: 'SumML', colorField: 'groupsLabel'}} title={formValues.DepartmentList?.label} dataSource={sideData.yearData} /></>
|
|
|
|
|
)} */}
|
|
|
|
|
</Col>
|
|
|
|
|
{Object.keys(sideData.dataSource).sort().map((key) => (
|
|
|
|
|
<Col {...layoutProps3} key={key}>
|
|
|
|
|
<Waterfall key={key} {...WaterfallConfig} title={key} dataSource={sideData.dataSource[key]} line={summaryData.kpi} />
|
|
|
|
|
<h3 style={{ textAlign: 'center' }}>{`${key}每月业绩`}</h3>
|
|
|
|
|
</Col>
|
|
|
|
|
))}
|
|
|
|
|
{Object.keys(sideData.dataSource)
|
|
|
|
|
.sort()
|
|
|
|
|
.map((key) => (
|
|
|
|
|
<Col {...layoutProps3} key={key}>
|
|
|
|
|
<Waterfall key={key} {...WaterfallConfig} title={key} dataSource={sideData.dataSource[key]} line={summaryData.kpi} />
|
|
|
|
|
<h3 style={{ textAlign: 'center' }}>{`${key}每月业绩`}</h3>
|
|
|
|
|
</Col>
|
|
|
|
|
))}
|
|
|
|
|
</Row>
|
|
|
|
|
</Spin>
|
|
|
|
|
</section>
|
|
|
|
@ -265,9 +306,9 @@ export default observer(() => {
|
|
|
|
|
)}
|
|
|
|
|
<Col key={'mapG'} flex={'1 0 auto'}>
|
|
|
|
|
<Spin spinning={topData?.country?.loading || false}>
|
|
|
|
|
<div id='topC' style={{height: '700px'}}>
|
|
|
|
|
<MapCountry sourceField={'groupsLabel'} valueField={BUConfig.measureField} dataSource={topData?.country?.dataSource || []} />
|
|
|
|
|
</div>
|
|
|
|
|
<div id="topC" style={{ height: '700px' }}>
|
|
|
|
|
<MapCountry sourceField={'groupsLabel'} valueField={BUConfig.measureField} dataSource={topData?.country?.dataSource || []} />
|
|
|
|
|
</div>
|
|
|
|
|
</Spin>
|
|
|
|
|
</Col>
|
|
|
|
|
</Row>
|
|
|
|
|