feat: 客服: 酒店

main
Lei OT 2 months ago
parent 08aa01e33c
commit 17cedf14d9

@ -186,6 +186,21 @@ export default observer((props) => {
transform: (value) => value?.key || '',
default: '',
},
'hotelBookType': {
key: 'hotelBookType',
transform: (value) => value?.key || '',
default: '',
},
'hotelRecommandRate': {
key: 'hotelRecommandRate',
transform: (value) => value?.key || '',
default: '',
},
'hotelStar': {
key: 'hotelStar',
transform: (value) => value?.key || '',
default: '',
},
};
let dest = {};
const { departureDateType, applyDate, applyDate2, year, yearDiff, dates, months, date, ...omittedValue } = values;
@ -362,11 +377,11 @@ function getFields(props) {
item(
'countryArea',
99,
<Form.Item name={`countryArea`} initialValue={at(props, 'initialValue.countryArea')[0] || (fieldProps?.countryArea?.show_all ? { key: 'all', label: '所有国家' } : undefined)}>
<Select style={{ width: '100%' }} placeholder="所有国家" labelInValue>
<Form.Item name={`countryArea`} initialValue={at(props, 'initialValue.countryArea')[0] || (fieldProps?.countryArea?.show_all ? { key: 'all', label: '国内外' } : undefined)}>
<Select style={{ width: '100%' }} placeholder="国内外" labelInValue allowClear={fieldProps?.countryArea?.show_all || false}>
{fieldProps?.countryArea?.show_all && (
<Option key="all" value="">
所有国家
<Option key="all" value="" disabled>
国内外
</Option>
)}
<Option key="china" value="china">
@ -579,19 +594,19 @@ function getFields(props) {
fieldProps?.personRange?.col || 4
),
item(
'bookType',
'hotelBookType',
99,
<Form.Item name={`bookType`} initialValue={at(props, 'initialValue.bookType')[0] || (fieldProps?.bookType?.show_all ? { key: 'all', label: '预定类型' } : undefined)}>
<Select style={{ width: '100%' }} placeholder="预定类型" labelInValue allowClear>
{fieldProps?.bookType?.show_all && (
<Option key="all" value="">
所有
<Form.Item name={`hotelBookType`} initialValue={at(props, 'initialValue.hotelBookType')[0] || (fieldProps?.hotelBookType?.show_all ? { key: 'all', label: '预定类型' } : undefined)}>
<Select style={{ width: '100%' }} placeholder="预定类型" labelInValue allowClear={fieldProps?.hotelBookType?.show_all || false}>
{fieldProps?.hotelBookType?.show_all && (
<Option key="all" value="" disabled>
预定类型
</Option>
)}
<Option key="proxy" value="proxy">
<Option key="1" value="1">
代订
</Option>
<Option key="direct" value="direct">
<Option key="0" value="0">
自订
</Option>
</Select>
@ -599,18 +614,21 @@ function getFields(props) {
3
),
item(
'recommandRate',
'hotelRecommandRate',
99,
<Form.Item name={`recommandRate`} initialValue={at(props, 'initialValue.recommandRate')[0] || (fieldProps?.recommandRate?.show_all ? { key: 'all', label: '推荐' } : undefined)}>
<Select style={{ width: '100%' }} placeholder="推荐" labelInValue allowClear>
{fieldProps?.recommandRate?.show_all && (
<Option key="all" value="">
所有
<Form.Item name={`hotelRecommandRate`} initialValue={at(props, 'initialValue.hotelRecommandRate')[0] || (fieldProps?.hotelRecommandRate?.show_all ? { key: 'all', label: '推荐等级' } : undefined)}>
<Select style={{ width: '100%' }} placeholder="推荐等级" labelInValue allowClear={fieldProps?.hotelRecommandRate?.show_all || false}>
{fieldProps?.hotelRecommandRate?.show_all && (
<Option key="all" value="" disabled>
推荐等级
</Option>
)}
<Option key="proxy" value="proxy">
<Option key="1" value="1">
主推
</Option>
<Option key="0" value="0">
非主推
</Option>
</Select>
</Form.Item>,
3

@ -185,19 +185,16 @@ export const KPISubjects = [
];
export const HotelStars = [
{ key: '5', value: '5', label: '5星' },
{ key: '4', value: '4', label: '4星' },
{ key: '3', value: '3', label: '3星' },
{ key: '2', value: '2', label: '2星' },
{ key: 'intl', value: 'intl', label: '国际社' },
{ key: 'internal', value: 'internal', label: '国内社' },
{ key: 'other', value: 'other', label: '其它' },
{ key: 'f5', value: 'f5', label: '准5星' },
{ key: 'f4', value: 'f4', label: '准4星' },
{ key: 'inn', value: 'inn', label: '客栈' },
{ key: 'apartment', value: 'apartment', label: '公寓' },
{ key: 'siheyuan', value: 'siheyuan', label: '四合院酒店' },
{ key: 'luxury5', value: 'luxury5', label: '豪华五星' },
{ key: '1', value: '1', label: '五星' },
{ key: '2', value: '2', label: '四星' },
{ key: '3', value: '3', label: '三星' },
{ key: '4', value: '4', label: '二星' },
{ key: '8', value: '8', label: '准五星 ' },
{ key: '9', value: '9', label: '准四星' },
{ key: '10', value: '10', label: '客栈' },
{ key: '11', value: '11', label: '公寓' },
{ key: '12', value: '12', label: '四合院酒店' },
{ key: '13', value: '13', label: '豪华五星' },
];
/**

@ -7,24 +7,25 @@ import moment from 'moment';
const fetchHotelData = async (param) => {
const defaultParam = {
DEI_SN:'',
City:'',
OrderState:'',
BookingType:'-1',
RecommendedLevel:'-1',
Star:'-1',
ArriveDateCheck:'0',
ArriveDateStart:'',
ArriveDateEnd:'',
ConfirmDateCheck:'0',
ConfirmDateStart:'',
ConfirmDateEnd:'',
Compare:'0',
CompareDateStart:'',
CompareDateEnd:'',
DEI_SN: '',
City: '',
OrderState: '',
BookingType: '-1',
RecommendedLevel: '-1',
Star: '-1',
ArriveDateCheck: '0',
ArriveDateStart: '',
ArriveDateEnd: '',
ConfirmDateCheck: '0',
ConfirmDateStart: '',
ConfirmDateEnd: '',
Compare: '0',
CompareDateStart: '',
CompareDateEnd: '',
Area: '-1',
};
const json = await fetchJSON('/service-Analyse2/HotelReservation', { ...defaultParam, ...param });
return json.errcode === 0 ? json.result : [];
return json.errcode === 0 ? json.result || [] : [];
};
const fetchCruiseData = async (param) => {
@ -47,21 +48,27 @@ const fetchCruiseData = async (param) => {
Country: '-1',
};
const json = await fetchJSON('/service-Analyse2/CruiseReservation', { ...defaultParam, ...param });
return json.errcode === 0 ? json.result : [];
return json.errcode === 0 ? json.result || [] : [];
};
const keyMapped = {
'applyDate': { key: '' },
'startDate': { key: 'ArriveDateCheck'},
'comfirmDate': { key: 'ConfirmDateCheck'},
const paramKeyMapped = {
'DateType': [
{ key: 'ArriveDateCheck', transform: (val) => (val === 'startDate' ? '1' : '0') },
{ key: 'ConfirmDateCheck', transform: (val) => (val === 'confirmDate' ? '1' : '0') },
// { key: 'ApplyDateCheck', transform: (val) => (val === 'applyDate' ? '1' : '0') },
],
'DepartmentList': { key: 'DEI_SN' },
'orderStatus': { key: 'OrderState' },
'Date1': { key: 'ArriveDateStart' },
'Date2': { key: 'ArriveDateEnd' },
'Date1': [{ key: 'ArriveDateStart' }, { key: 'ConfirmDateStart' }],
'Date2': [{ key: 'ArriveDateEnd' }, { key: 'ConfirmDateEnd' }],
'DateDiff1': { key: 'CompareDateStart' },
'DateDiff2': { key: 'CompareDateEnd' },
'keyword': { key: 'ProductName' },
'cruiseDirection': { key: 'Direction' },
'hotelStar': { key: 'Star' },
'hotelRecommandRate': { key: 'RecommendedLevel' },
'hotelBookType': { key: 'BookingType' },
'countryArea': { key: 'Area', transform: (val) => (val === 'china' ? '1' : val === 'foreign' ? '0' : '-1') },
};
class HotelCruise {
@ -73,16 +80,7 @@ class HotelCruise {
async getCruiseData(param = {}) {
this.cruise.loading = true;
this.cruise.dataSource = [];
const _queryParam = objectMapper(param, {
'DepartmentList': { key: 'DEI_SN' },
'orderStatus': { key: 'OrderState' },
'Date1': { key: 'ArriveDateStart' },
'Date2': { key: 'ArriveDateEnd' },
'DateDiff1': { key: 'CompareDateStart' },
'DateDiff2': { key: 'CompareDateEnd' },
'keyword': { key: 'ProductName' },
'cruiseDirection': { key: 'Direction' },
});
const _queryParam = objectMapper(param, paramKeyMapped);
const queryParam = omit({ ...this.searchValuesToSub, ..._queryParam }, ['DepartmentList', 'orderStatus', 'keyword', 'Date1', 'Date2', 'DateDiff1', 'DateDiff2', 'cruiseDirection']);
queryParam.Compare = isEmpty(param.DateDiff1) ? '' : '1';
const res = await fetchCruiseData(queryParam);
@ -104,16 +102,34 @@ class HotelCruise {
async getHotelData(param = {}) {
this.hotel.loading = true;
this.hotel.dataSource = [];
const res = await fetchHotelData({ ...this.searchValuesToSub, ...param });
const _queryParam = objectMapper(param, paramKeyMapped);
const queryParam = omit({ ...this.searchValuesToSub, ..._queryParam }, [
'DepartmentList','orderStatus','keyword','Date1','Date2','DateDiff1','DateDiff2','DateType',
'hotelStar','hotelRecommandRate','hotelBookType','countryArea',
]);
queryParam.Compare = isEmpty(param.DateDiff1) ? '0' : '1';
const _res = await fetchHotelData(queryParam);
const res = (_res || []).map((ele) => ({ ...ele, RecommendRate_100: fixTo2Decimals(ele.RecommendRate * 100) + '%' }));
const resCP =
queryParam.Compare === '0'
? res
: (res || []).map((ele) => ({
...ele,
TotalNumPercent: ele.CPTotalNum ? fixTo2Decimals(((ele.TotalNum - ele.CPTotalNum) / ele.CPTotalNum) * 100) : '-',
RecomendNumPercent: ele.CPRecomendNum ? fixTo2Decimals(((ele.RecomendNum - ele.CPRecomendNum) / ele.CPRecomendNum) * 100) : '-',
RecommendRateDelta: fixTo2Decimals((ele.RecommendRate - (ele.CPRecommendRate || 0)) * 100),
CPRecommendRate_100: fixTo2Decimals(ele.CPRecommendRate * 100) + '%',
}));
console.log(resCP);
runInAction(() => {
this.hotel.loading = false;
this.hotel.dataSource = [].concat(this.hotel.dataSource, res);
this.hotel.dataSource = resCP;
});
}
searchValues = {
date: moment(),
DateType: { key: 'applyDate', label: '提交日期' },
DateType: { key: 'confirmDate', label: '确认日期' },
WebCode: { key: '', label: '所有来源' },
// IncludeTickets: { key: '1', label: '含门票'},
DepartmentList: [{ key: '', label: '所有小组' }],

@ -15,6 +15,7 @@ export default observer((props) => {
const { formValues, siderBroken } = searchFormStore;
const tableSorter = (a, b, colName) => (a[colName] - b[colName]);
const tableProps = {
size: 'small',
bordered: true, pagination: false,
@ -24,6 +25,7 @@ export default observer((props) => {
title: '房间数',
dataIndex: 'TotalNum',
key: 'TotalNum',
sorter: (a, b) => tableSorter(a, b, 'TotalNum'),
render: (v, r) => (
<>
<Space direction={'vertical'}>
@ -38,6 +40,7 @@ export default observer((props) => {
},
{ title: '人数', dataIndex: 'TotalPersonNum', key: 'TotalPersonNum' },
{ title: '总利润', dataIndex: 'TotalProfit', key: 'TotalProfit',
sorter: (a, b) => tableSorter(a, b, 'TotalProfit'),
render: (v, r) => (
<>
<Space direction={'vertical'}>

@ -1,22 +1,76 @@
import React, { useContext } from 'react';
import { observer } from 'mobx-react';
import { stores_Context } from '../config';
import { Row, Col, Table } from 'antd';
import { Row, Col, Table, Space, Typography } from 'antd';
import SearchForm from './../components/search/SearchForm';
import { VSTag, TableExportBtn } from './../components/Data';
const { Text } = Typography;
export default observer((props) => {
const { sale_store, date_picker_store: searchFormStore } = useContext(stores_Context);
const { customerServicesStore, date_picker_store } = useContext(stores_Context);
const { customerServicesStore, date_picker_store, HotelCruiseStore } = useContext(stores_Context);
const { loading, dataSource } = HotelCruiseStore.hotel;
const { formValues, siderBroken } = searchFormStore;
const tableSorter = (a, b, colName) => (a[colName] - b[colName]);
const tableProps = {
size: 'small',
bordered: true,
pagination: false,
columns: [
{ title: '目的地', dataIndex: 'op', key: 'op' },
{ title: '总间夜', dataIndex: 'action', key: 'action' },
{ title: '主推', dataIndex: 'action', key: 'action' },
{ title: '使用比例', dataIndex: 'action', key: 'action' },
{ title: '目的地', dataIndex: 'CityName', key: 'CityName' },
{
title: '总间夜',
dataIndex: 'TotalNum',
key: 'TotalNum',
sorter: (a, b) => tableSorter(a, b, 'TotalNum'),
render: (v, r) => (
<>
<Space direction={'vertical'}>
<Text strong>
{v}
{r.CPTotalNum && <Text type="secondary"> VS {r.CPTotalNum}</Text>}
</Text>
{r.CPTotalNum && <VSTag diffPercent={r.TotalNumPercent} />}
</Space>
</>
),
},
{
title: '主推',
dataIndex: 'RecomendNum',
key: 'RecomendNum',
sorter: (a, b) => tableSorter(a, b, 'RecomendNum'),
render: (v, r) => (
<>
<Space direction={'vertical'}>
<Text strong>
{v}
{r.CPRecomendNum && <Text type="secondary"> VS {r.CPRecomendNum}</Text>}
</Text>
{r.CPRecomendNum && <VSTag diffPercent={r.RecomendNumPercent} />}
</Space>
</>
),
},
{
title: '使用比例',
dataIndex: 'RecommendRate_100',
key: 'RecommendRate_100',
render: (v, r) => (
<>
<Space direction={'vertical'}>
<Text strong>
{v}
{r.RecommendRateDelta !== undefined && <Text type="secondary"> VS {r.CPRecommendRate_100}</Text>}
</Text>
{r.RecommendRateDelta !== undefined && <VSTag diffPercent={r.RecommendRateDelta} />}
</Space>
</>
),
},
],
};
@ -28,27 +82,30 @@ export default observer((props) => {
defaultValue={{
initialValue: {
...date_picker_store.formValues,
...customerServicesStore.searchValues,
...HotelCruiseStore.searchValues,
},
// 'countryArea', 'DateType', 'dates',
shows: ['DepartmentList', 'countryArea', 'orderStatus', 'bookType', 'recommandRate','hotelStar','DateType', 'dates',],
shows: ['DepartmentList', 'countryArea', 'orderStatus', 'hotelBookType', 'hotelRecommandRate', 'hotelStar', 'DateType', 'dates'],
sort: { DateType: 101, dates: 102 },
fieldProps: {
DepartmentList: { show_all: true, mode: 'multiple' },
countryArea: { show_all: true },
orderStatus: { show_all: true },
hotelBookType: { show_all: true },
hotelRecommandRate: { show_all: true },
// years: { hide_vs: false },
DateType: { disabledKeys: ['applyDate'] },
},
}}
onSubmit={(_err, obj, form) => {
customerServicesStore.setSearchValues(obj, form);
// customerServicesStore.fetchDestinationGroupCount();
HotelCruiseStore.setSearchValues(obj, form);
HotelCruiseStore.getHotelData(obj);
}}
/>
</Col>
</Row>
<section>
<Table {...tableProps} bordered />
<Table {...tableProps} bordered {...{ loading, dataSource }} rowKey={(record) => record.CityName} />
</section>
</>
);

Loading…
Cancel
Save