You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
405 lines
14 KiB
JavaScript
405 lines
14 KiB
JavaScript
import { createContext, useContext, useEffect } from 'react';
|
|
import { toJS } from 'mobx';
|
|
import { observer } from 'mobx-react';
|
|
import { DATE_FORMAT, SMALL_DATETIME_FORMAT, stores_Context } from './../../config';
|
|
import { SearchOutlined } from '@ant-design/icons';
|
|
import { Form, Row, Col, Select, Button, Space, DatePicker } from 'antd';
|
|
import moment from 'moment';
|
|
// import locale from 'antd/es/date-picker/locale/zh_CN';
|
|
import BusinessSelect from './BusinessSelect';
|
|
import BusinessUnitSelect from './BusinessUnitSelect';
|
|
import GroupSelect from './GroupSelect';
|
|
import SiteSelect from './SiteSelect';
|
|
import DateTypeSelect from './DataTypeSelect';
|
|
import DatePickerCharts from './DatePickerCharts';
|
|
import YearPickerCharts from './YearPickerCharts';
|
|
import SearchInput from './Input';
|
|
import { objectMapper, at, empty, isEmpty } from './../../utils/commons';
|
|
|
|
import './search.css';
|
|
|
|
const EditableContext = createContext();
|
|
const Option = Select.Option;
|
|
|
|
/**
|
|
* 搜索表单
|
|
* @property defaultValue { initialValue, fieldProps, hides, shows, sort }
|
|
* * {object} initialValue 默认值
|
|
* * {object} fieldProps 表单项属性
|
|
* * {array} hides 隐藏的表单项
|
|
* * {array} shows 显示的表单项
|
|
* * {object} sort 表单项排序
|
|
* @property onSubmit
|
|
*/
|
|
export default observer((props) => {
|
|
const { date_picker_store: searchFormStore } = useContext(stores_Context);
|
|
const [form] = Form.useForm();
|
|
const { sort, initialValue, hides, shows, fieldProps } = {
|
|
sort: '',
|
|
initialValue: '',
|
|
fieldProps: '',
|
|
hides: [],
|
|
shows: [],
|
|
...props.defaultValue,
|
|
};
|
|
const { onSubmit, confirmText } = props;
|
|
|
|
|
|
const formValuesMapper = (values) => {
|
|
const destinationObject = {
|
|
'DateType': {
|
|
key: 'DateType',
|
|
transform: (value) => value?.key || '',
|
|
default: '',
|
|
},
|
|
'HTBusinessUnits': {
|
|
key: 'HTBusinessUnits',
|
|
transform: (value) => {
|
|
return Array.isArray(value) ? value.map((ele) => ele.key).join(',') : value ? (!isNaN(parseInt(value.key), 10) ? value.key : '') : '';
|
|
},
|
|
default: '',
|
|
},
|
|
'businessUnits': {
|
|
key: 'businessUnits',
|
|
transform: (value) => {
|
|
return Array.isArray(value) ? value.map((ele) => ele.key).join(',') : value ? (!isNaN(parseInt(value.key), 10) ? value.key : '') : '';
|
|
},
|
|
default: '',
|
|
},
|
|
'DepartmentList': {
|
|
key: 'DepartmentList',
|
|
transform: (value) => {
|
|
return Array.isArray(value) ? value.map((ele) => ele.key).join(',') : value ? value.key : '';
|
|
},
|
|
default: '',
|
|
},
|
|
'WebCode': {
|
|
key: 'WebCode',
|
|
transform: (value) => {
|
|
return isEmpty(value) ? 'ALL': Array.isArray(value) ? value.map((ele) => ele.key).filter(ele => ele !== 'ALL').join(',') : value ? value.key : '';
|
|
},
|
|
default: '',
|
|
},
|
|
'IncludeTickets': {
|
|
key: 'IncludeTickets',
|
|
transform: (value) => value?.key || '',
|
|
default: '',
|
|
},
|
|
'operator': {
|
|
key: 'operator',
|
|
transform: (value) => value?.key || '',
|
|
default: '',
|
|
},
|
|
'applyDate': [
|
|
{
|
|
key: 'Date1',
|
|
transform: (value) => (value === '' || !Array.isArray(value) ? undefined : moment(value[0]).format(DATE_FORMAT)),
|
|
default: '',
|
|
},
|
|
{
|
|
key: 'Date2',
|
|
transform: (value) => (value === '' || !Array.isArray(value) ? undefined : moment(value[1]).format(SMALL_DATETIME_FORMAT)),
|
|
default: '',
|
|
},
|
|
],
|
|
'applyDate2': [
|
|
{
|
|
key: 'DateDiff1',
|
|
transform: (value) => (value === '' || !Array.isArray(value) ? undefined : value[0] ? moment(value[0]).format(DATE_FORMAT) : undefined),
|
|
default: '',
|
|
},
|
|
{
|
|
key: 'DateDiff2',
|
|
transform: (value) => (value === '' || !Array.isArray(value) ? undefined : value[1] ? moment(value[1]).format(SMALL_DATETIME_FORMAT) : undefined),
|
|
default: '',
|
|
},
|
|
],
|
|
'year': [
|
|
{
|
|
key: 'Date1',
|
|
transform: (value) => (value ? moment(value).format(`YYYY-01-01`) : undefined),
|
|
default: '',
|
|
},
|
|
{
|
|
key: 'Date2',
|
|
transform: (value) => (value ? moment(value).format(`YYYY-12-31 23:59:00`) : undefined),
|
|
default: '',
|
|
},
|
|
],
|
|
'yearDiff': [
|
|
{
|
|
key: 'DateDiff1',
|
|
transform: (value) => (value ? moment(value).format(`YYYY-01-01`) : undefined),
|
|
default: '',
|
|
},
|
|
{
|
|
key: 'DateDiff2',
|
|
transform: (value) => (value ? moment(value).format(`YYYY-12-31 23:59:00`) : undefined),
|
|
default: '',
|
|
},
|
|
],
|
|
'country': {
|
|
key: 'country',
|
|
transform: (value) => value?.key || '',
|
|
default: '',
|
|
},
|
|
'city': {
|
|
key: 'city',
|
|
transform: (value) => value?.key || '',
|
|
default: '',
|
|
},
|
|
};
|
|
let dest = {};
|
|
const { applyDate, applyDate2, year, yearDiff, dates, months, ...omittedValue } = values;
|
|
dest = { ...omittedValue, ...objectMapper(values, destinationObject) };
|
|
for (const key in dest) {
|
|
if (Object.prototype.hasOwnProperty.call(dest, key)) {
|
|
dest[key] = typeof dest[key] === 'string' ? (dest[key] || '').trim() : dest[key];
|
|
}
|
|
}
|
|
// omit empty
|
|
Object.keys(dest).forEach((key) => (dest[key] == null || dest[key] === '' || dest[key].length === 0) && delete dest[key]);
|
|
return dest;
|
|
};
|
|
|
|
useEffect(() => {
|
|
const dest = formValuesMapper(searchFormStore.formValues);
|
|
searchFormStore.setFormValuesToSub(dest);
|
|
return () => {};
|
|
}, []);
|
|
|
|
const onFinish = (values) => {
|
|
console.log('Received values of form, origin form value: ', values);
|
|
const dest = formValuesMapper(values);
|
|
console.log('form value send to onSubmit:', dest);
|
|
const str = new URLSearchParams(dest).toString();
|
|
searchFormStore.setFormValues(values);
|
|
searchFormStore.setFormValuesToSub(dest);
|
|
if (typeof onSubmit === 'function') {
|
|
onSubmit(null, dest, values, str);
|
|
}
|
|
};
|
|
|
|
const onReset = () => {
|
|
form.setFieldsValue({
|
|
// 'DateType': undefined,
|
|
});
|
|
};
|
|
const onValuesChange = (...args) => {
|
|
const [changedValues, allValues] = args;
|
|
// console.log('form onValuesChange', Object.keys(changedValues), args);
|
|
|
|
const dest = formValuesMapper(allValues);
|
|
searchFormStore.setFormValues(allValues);
|
|
searchFormStore.setFormValuesToSub(dest);
|
|
};
|
|
|
|
return (
|
|
// layout="inline"
|
|
<Form form={form} name="advanced_search" className="orders-search-form" onFinish={onFinish} onValuesChange={onValuesChange}>
|
|
<EditableContext.Provider value={form}>
|
|
<Row gutter={10} style={{ background: '#f9fafa', margin: '0px 0px 10px 0px', padding: '16px 8px 0 8px', boxShadow: '0px 0px 3px 0px rgba(0,0,0,0.15)' }}>
|
|
{getFields({ sort, initialValue, hides, shows, fieldProps, form })}
|
|
{/* 'textAlign': 'right' */}
|
|
<Col flex="1 0 120px" style={{ padding: '0px 5px', display: 'flex', justifyContent: 'flex-end', alignItems: 'flex-start' }}>
|
|
<Space align="center">
|
|
<Button size={'middle'} type="primary" icon={<SearchOutlined />} htmlType="submit">
|
|
{confirmText || '统计'}
|
|
</Button>
|
|
{/* <Button size="small" onClick={onReset}>
|
|
重置
|
|
</Button> */}
|
|
</Space>
|
|
</Col>
|
|
</Row>
|
|
</EditableContext.Provider>
|
|
</Form>
|
|
);
|
|
});
|
|
|
|
function getFields(props) {
|
|
const { fieldProps, form } = props;
|
|
const bigCol = 4 * 2;
|
|
const midCol = 6;
|
|
const layoutProps = {
|
|
gutter: { xs: 8, sm: 8, lg: 16 },
|
|
lg: { span: 4 },
|
|
md: { span: 8 },
|
|
sm: { span: 12 },
|
|
xs: { span: 24 },
|
|
};
|
|
const item = (name, sort = 0, render, col) => {
|
|
const customCol = col || 4;
|
|
const mdCol = customCol * 2;
|
|
return {
|
|
'key': '',
|
|
sort,
|
|
name,
|
|
render,
|
|
'hide': false,
|
|
'col': { lg: { span: customCol }, md: { span: mdCol < 8 ? 10 : mdCol}, flex: mdCol < 8 ? "1 0" : "" },
|
|
};
|
|
};
|
|
let baseChildren = [];
|
|
baseChildren = [
|
|
item(
|
|
'HTBusinessUnits',
|
|
99,
|
|
<Form.Item name={`HTBusinessUnits`} initialValue={at(props, 'initialValue.HTBusinessUnits')[0] || undefined}>
|
|
<BusinessUnitSelect {...fieldProps.HTBusinessUnits} labelInValue={true} />
|
|
</Form.Item>
|
|
),
|
|
item(
|
|
'businessUnits',
|
|
99,
|
|
<Form.Item name={`businessUnits`} initialValue={at(props, 'initialValue.businessUnits')[0] || undefined}>
|
|
<BusinessSelect {...fieldProps.businessUnits} labelInValue={true} />
|
|
</Form.Item>
|
|
),
|
|
item(
|
|
'DepartmentList',
|
|
99,
|
|
<Form.Item name={`DepartmentList`} initialValue={at(props, 'initialValue.DepartmentList')[0] || (fieldProps?.DepartmentList?.show_all ? { key: 'ALL', label: '所有小组' } : undefined)}>
|
|
<GroupSelect {...fieldProps.DepartmentList} labelInValue={true} />
|
|
</Form.Item>
|
|
),
|
|
item(
|
|
'WebCode',
|
|
99,
|
|
<Form.Item name={`WebCode`} initialValue={at(props, 'initialValue.WebCode')[0] || (fieldProps?.WebCode?.show_all ? { key: 'ALL', label: '所有来源' } : undefined)}>
|
|
<SiteSelect {...fieldProps.WebCode} labelInValue={true} />
|
|
</Form.Item>
|
|
),
|
|
item(
|
|
'IncludeTickets',
|
|
99,
|
|
// value={orders_store.include_tickets} onChange={orders_store.handleChange_include_tickets}
|
|
<Form.Item name={`IncludeTickets`} initialValue={at(props, 'initialValue.IncludeTickets')[0] || { key: '1', label: '含门票' }}>
|
|
<Select style={{ width: '100%' }} placeholder="是否含门票" labelInValue>
|
|
<Option key="1" value="1">
|
|
含门票
|
|
</Option>
|
|
<Option key="0" value="0">
|
|
不含门票
|
|
</Option>
|
|
</Select>
|
|
</Form.Item>,
|
|
3
|
|
),
|
|
//
|
|
item(
|
|
'DateType',
|
|
99,
|
|
<Form.Item name={`DateType`} initialValue={at(props, 'initialValue.DateType')[0] || { key: 'applyDate', label: '提交日期' }}>
|
|
<DateTypeSelect labelInValue={true} />
|
|
</Form.Item>,
|
|
3
|
|
),
|
|
item(
|
|
'years',
|
|
99,
|
|
<Form.Item>
|
|
{/* <DatePicker picker="year" placeholder='年份' /> */}
|
|
<YearPickerCharts {...fieldProps.years} />
|
|
</Form.Item>,
|
|
3
|
|
),
|
|
item(
|
|
'months',
|
|
99,
|
|
<Form.Item>
|
|
<DatePicker picker="month" placeholder="月份" />
|
|
</Form.Item>,
|
|
3
|
|
),
|
|
item(
|
|
'dates',
|
|
99,
|
|
<Form.Item>
|
|
<DatePickerCharts isform={true} {...fieldProps.dates} form={form} />
|
|
</Form.Item>,
|
|
midCol
|
|
),
|
|
item(
|
|
'operator',
|
|
99,
|
|
<Form.Item name={'operator'} dependencies={['DepartmentList']} >
|
|
<SearchInput
|
|
autoGet
|
|
url="/service-Analyse2/GetOperatorInfo"
|
|
map={{ 'op_id': 'key', 'cn_name': 'label' }}
|
|
resultkey={'result'}
|
|
placeholder="输入搜索顾问: 中/英名字"
|
|
dependenciesFun={() => ({ dept_id: (form.getFieldValue('DepartmentList')?.value || '').replace('ALL', ''), ...(fieldProps?.operator?.param || {}) })}
|
|
/>
|
|
</Form.Item>
|
|
),
|
|
item(
|
|
'country',
|
|
99,
|
|
<Form.Item name={'country'}>
|
|
<SearchInput autoGet url="/service-Analyse2/GetCountryInfo" map={{ 'c_id': 'key', 'cn_name': 'label' }} resultkey={'result'} placeholder="输入搜索国籍: 中/英名字" />
|
|
</Form.Item>
|
|
),
|
|
item(
|
|
'city',
|
|
99,
|
|
<Form.Item name={'city'}>
|
|
<SearchInput autoGet url="/service-Analyse2/GetDestinationInfo" map={{ 'c_id': 'key', 'cn_name': 'label' }} resultkey={'result'} placeholder="输入搜索城市: 中/英名字" />
|
|
</Form.Item>
|
|
),
|
|
item(
|
|
'globalCity',
|
|
99,
|
|
<Form.Item name={'globalCity'}>
|
|
<SearchInput autoGet url="/service-Analyse2/GetGlobalDestinationInfo" map={{ 'c_id': 'key', 'cn_name': 'label' }} resultkey={'result'} placeholder="输入搜索城市: 中/英名字" />
|
|
</Form.Item>
|
|
),
|
|
];
|
|
baseChildren = baseChildren
|
|
.map((x) => {
|
|
x.hide = false;
|
|
if (props.sort === undefined) {
|
|
return x;
|
|
}
|
|
const tmpSort = props.sort;
|
|
for (const key in tmpSort) {
|
|
if (Object.prototype.hasOwnProperty.call(tmpSort, key)) {
|
|
if (x.name === key) {
|
|
x.sort = tmpSort[key];
|
|
}
|
|
}
|
|
}
|
|
return x;
|
|
})
|
|
.map((x) => {
|
|
if (props.hides.length === 0 && props.shows.length === 0) {
|
|
return x;
|
|
}
|
|
if (props.hides.length === 0) {
|
|
x.hide = !props.shows.includes(x.name);
|
|
} else if (props.shows.length === 0) {
|
|
x.hide = props.hides.includes(x.name);
|
|
}
|
|
return x;
|
|
})
|
|
.filter((x) => !x.hide)
|
|
.sort((a, b) => {
|
|
return a.sort < b.sort ? -1 : 1;
|
|
});
|
|
const children = [];
|
|
const leftStyle = {}; // { borderRight: '1px solid #dedede' };
|
|
for (let i = 0; i < baseChildren.length; i++) {
|
|
let style = { padding: '0px 2px' };
|
|
style = i % 2 === 0 && baseChildren[i].col === 12 ? { ...style, ...leftStyle } : style;
|
|
style = !baseChildren[i].hide ? { ...style, display: 'block' } : { ...style, display: 'none' };
|
|
const Item = (
|
|
<Col key={String(i)} style={style} {...layoutProps} {...baseChildren[i].col}>
|
|
{baseChildren[i].render}
|
|
</Col>
|
|
);
|
|
children.push(Item);
|
|
}
|
|
return children;
|
|
}
|