首页 年度 时间轴切换

feature/2.0-sales-trade
Lei OT 2 years ago
parent 33751b3eca
commit 11e0684edf

@ -1,11 +1,11 @@
import { observer } from 'mobx-react';
import { Radio, Select } from 'antd';
import { dataFieldOptions } from './../libs/ht';
import { dataFieldOptions } from '../libs/ht';
export default observer((props) => {
const { visible, dataRaw, dataMapper, fieldMapper, onChange, ...extProps } = props;
const handleChange = (value) => {
console.log('handleChange', value);
// console.log('handleChange', value);
if (typeof onChange === 'function') {
onChange(value);
}

@ -4,7 +4,7 @@ export const datePartOptions = [
{ label: '日', value: 'day' },
{ label: '周', value: 'week' },
{ label: '月', value: 'month' },
{ label: '季', value: 'quarter' },
{ label: '季', value: 'season' },
{ label: '年', value: 'year' },
];
export const datePartMethod = {
@ -20,7 +20,7 @@ export const datePartMethod = {
const dateKey = `${year}-W${String(week).padStart(2, '0')}`;
return { dateKey, 'groupKey': dateKey, date };
},
'quarter': (date) => {
'season': (date) => {
const dateO = moment(date);
// const key = dateO.format('YYYY-Q');
const key = `${dateO.year()}-${String(dateO.quarter()).padStart(2, 'Q')}`;

@ -2,6 +2,10 @@ import { Radio } from 'antd';
import { observer } from 'mobx-react';
import { datePartOptions, resultDataCb } from './date';
/**
* 仅前端转换数据
* 把按天的数据转换成 按周,,,
*/
export default observer((props) => {
const { visible, dataRaw, dataMapper, fieldMapper, onChange, ...extProps } = props;
const _dataMapper = dataMapper || { 'data1': null, data2: null };

@ -1,13 +1,15 @@
import { observer } from "mobx-react";
import { observer } from 'mobx-react';
import { Card, Statistic, Progress } from 'antd';
import { ArrowUpOutlined, ArrowDownOutlined } from '@ant-design/icons';
export default observer((props) => {
const valueStyle = { color: props.VSrate < 0 ? '#3f8600' : '#cf1322' };
const VSIcon = () => (props.VSrate < 0 ? <ArrowDownOutlined /> : <ArrowUpOutlined />);
const ValueIcon = props.icon;
const valueStyle = { color: (props?.VSrate || -1) < 0 ? '#3f8600' : '#cf1322' };
const VSIcon = () => ((props?.VSrate || -1) < 0 ? <ArrowDownOutlined /> : <ArrowUpOutlined />);
return (
<Card>
<Statistic
{...props}
className={'__hn-sta-wrapper'}
valueStyle={valueStyle}
suffix={
@ -19,7 +21,8 @@ export default observer((props) => {
</>
)
}
{...props}
prefix={<ValueIcon twoToneColor="#89B67F" />}
// title={<Space><ValueIcon twoToneColor="#89B67F" /><span>{props.title}</span></Space>}
/>
{props.showProgress !== false && <Progress percent={props.KPIrate} size="small" format={(percent) => `${props.KPIrate}%`} />}
</Card>

@ -28,7 +28,8 @@ class Trade {
value: summary?.ConfirmOrder,
// VSrate: summary?.ConfirmOrderrate,
KPIrate: summary?.[dataFieldAlias.ConfirmOrder.nestkey.p],
hasKPI: !isEmpty(summary?.[dataFieldAlias.ConfirmOrder.nestkey.p]),
// hasKPI: !isEmpty(summary?.[dataFieldAlias.ConfirmOrder.nestkey.p]),
hasKPI: false
},
{ title: '毛利', value: summary?.SumML, KPIrate: summary?.[dataFieldAlias.SumML.nestkey.p], hasKPI: false },
{ title: '完成率', value: `${summary?.[dataFieldAlias.SumML.nestkey.p] || ''}%`, hasKPI: false },
@ -54,7 +55,8 @@ class Trade {
*/
fetchTradeDataByDate(queryData) {
this.timeData.loading = true;
Object.assign(queryData, { groupType: 'overview', groupDateType: 'week' });
queryData = queryData || this.searchPayloadHome;
Object.assign(queryData, { groupType: 'overview', groupDateType: this.timeLineKey });
this.fetchTradeData(queryData).then((json) => {
if (json.errcode === 0) {
runInAction(() => {
@ -92,16 +94,11 @@ class Trade {
*/
fetchTradeDataByMonth(queryData) {
this.sideData.loading = true;
// todo: groupType: bizarea
// Object.assign(queryData, { groupType: 'bu', groupDateType: 'month' });
Object.assign(queryData, { groupType: 'bizarea', groupDateType: 'month' });
this.fetchTradeData(queryData).then((json) => {
if (json.errcode === 0) {
runInAction(() => {
const sortResult = json.result1.sort(sortBy('groupDateVal'));
/**
* test: '91006'
*/
const groupsData = sortResult.reduce((r, v) => {
if (v.groupsLabel ) { // && ['91001', '91006'].includes(v.groupsKey)
(r[v.groupsLabel] || (r[v.groupsLabel] = [])).push(v);
@ -111,8 +108,6 @@ class Trade {
this.sideData.loading = false;
this.sideData.dataSource = groupsData;
this.sideData.monthData = sortResult;
// const kpi = { label: '', value: 1200000 }; // 标注KPI
// this.sideData.kpi = kpi;
});
}
});
@ -149,13 +144,17 @@ class Trade {
this.searchPayloadHome = body;
}
timeLineKey = 'week';
setTimeLineKey(v) {
this.timeLineKey = v;
}
summaryData = { loading: false, dataSource: [], kpi: {}, };
timeData = { loading: false, dataSource: [] };
BuData = { loading: false, dataSource: [] };
sideData = { loading: false, dataSource: {}, monthData: [] };
dataForSort = {};
topData = {};
defaultDataSubject = 'CJCount';
searchPayloadHome = {};
}

@ -1,30 +1,36 @@
import { useContext, useEffect, useState } from 'react';
import { observer } from 'mobx-react';
import { Row, Col, Spin, Space } from 'antd';
import { Row, Col, Spin, Space, Radio } from 'antd';
import { CheckCircleTwoTone, MoneyCollectTwoTone, FlagTwoTone, SmileTwoTone, } from '@ant-design/icons';
import { stores_Context } from '../config';
import { useNavigate } from 'react-router-dom';
import StatisticCard from '../components/StatisticCard';
import Bullet from '../components/BulletWithSort';
import Waterfall from '../components/Waterfall';
import DataFieldRadio from './../components/DateFieldRadio';
import DataFieldRadio from '../components/DataFieldRadio';
import { datePartOptions } from './../components/DateGroupRadio/date';
import SearchForm from './../components/search/SearchForm';
import { empty, cloneDeep } from './../utils/commons';
import { empty, cloneDeep, isEmpty } from './../utils/commons';
import { dataFieldAlias } from './../libs/ht';
import { Line } from '@ant-design/charts';
import './home.css';
export default observer(() => {
const navigate = useNavigate();
const { TradeStore } = useContext(stores_Context);
const { searchPayloadHome, sideData, summaryData, BuData, topData, timeData } = TradeStore;
const topSeries = [
{ key: 'country', label: '国籍' },
{ key: 'dept', label: '小组' },
{ key: 'operator', label: '顾问' },
{ key: 'destination', label: '目的地' },
// { key: 'GuestGroupType', label: '' },
];
// const iconSets = [CheckCircleTwoTone, <MoneyCollectTwoTone />, <FlagTwoTone />, <ClockCircleTwoTone />, <DashboardTwoTone />,<SmileTwoTone />,];
const iconSets = [CheckCircleTwoTone, MoneyCollectTwoTone, FlagTwoTone, SmileTwoTone];
const topSeries = [
{ key: 'country', label: '国籍' },
{ key: 'dept', label: '小组' },
{ key: 'operator', label: '顾问' },
{ key: 'destination', label: '目的地' },
// { key: 'GuestGroupType', label: '' },
];
export default observer(() => {
// const navigate = useNavigate();
const { TradeStore, date_picker_store: searchFormStore } = useContext(stores_Context);
const { sideData, summaryData, BuData, topData, timeData, timeLineKey } = TradeStore;
const { formValues, } = searchFormStore;
useEffect(() => {
if (empty(summaryData.dataSource)) {
@ -137,6 +143,14 @@ export default observer(() => {
},
});
};
const [dateField, setDateField] = useState(timeLineKey);
const handleChangeDateType = ({target: {value}}) => {
setDateField(value);
TradeStore.setTimeLineKey(value);
if (!isEmpty(TradeStore.searchPayloadHome)) {
TradeStore.fetchTradeDataByDate();
}
};
return (
<>
<Row gutter={16} style={{ margin: '-16px -8px' }}>
@ -145,7 +159,7 @@ export default observer(() => {
<SearchForm
defaultValue={{
initialValue: {
...searchPayloadHome,
...formValues,
},
shows: ['DateType', 'DepartmentList', 'WebCode', 'IncludeTickets', 'years'],
fieldProps: {
@ -155,7 +169,7 @@ export default observer(() => {
},
}}
onSubmit={(_err, obj, form, str) => {
TradeStore.setStateSearch(form);
TradeStore.setStateSearch(obj);
pageRefresh(obj);
}}
/>
@ -167,9 +181,9 @@ export default observer(() => {
</Space>
<Spin spinning={summaryData.loading}>
<Row gutter={layoutProps.gutter}>
{summaryData.dataSource.map((item) => (
{summaryData.dataSource.map((item, i) => (
<Col {...layoutProps} key={item.title}>
<StatisticCard {...item} showProgress={item.hasKPI} />
<StatisticCard {...item} showProgress={item.hasKPI} icon={iconSets[i]} />
</Col>
))}
</Row>
@ -177,11 +191,13 @@ export default observer(() => {
</section>
<section>
<Space gutter={16} size={'large'}>
<h3></h3>
<h3></h3>
<DataFieldRadio value={timeDataField} onChange={handleChangetimeDataField} />
<div></div>
<Radio.Group options={datePartOptions} optionType="button" onChange={handleChangeDateType} value={dateField} />
</Space>
<Line {...lineConfig} data={timeData.dataSource} />
<Spin spinning={timeData.loading}>
<Line {...lineConfig} data={timeData.dataSource} />
</Spin>
</section>
<section>
<h3>市场进度</h3>
@ -189,11 +205,12 @@ export default observer(() => {
<Row gutter={layoutProps3.gutter}>
<Col {...layoutProps3}>
<Bullet {...BUConfig} dataSource={BuData?.dataSource || []} />
<h3 style={{ textAlign: 'center' }}>{`各事业部总业绩`}</h3>
</Col>
{Object.keys(sideData.dataSource).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>
<h3 style={{ textAlign: 'center' }}>{`${key}每月业绩`}</h3>
</Col>
))}
</Row>

Loading…
Cancel
Save