diff --git a/src/components/search/DatePickerCharts.jsx b/src/components/search/DatePickerCharts.jsx index bb73445..d6dc4f0 100644 --- a/src/components/search/DatePickerCharts.jsx +++ b/src/components/search/DatePickerCharts.jsx @@ -7,6 +7,16 @@ import "moment/locale/zh-cn"; import locale from "antd/es/date-picker/locale/zh_CN"; import { stores_Context } from "../../config"; +// 1.0的搜索组件 不需要Form包裹 +const SectionWrapper = ({ isform, id, title, children, right, ...extProps }) => + !isform ? ( + <>{children} + ) : ( + + {children} + + ); + // 用于日期选择,计算上一时间段、同比时间等 class DatePickerCharts extends Component { static contextType = stores_Context; @@ -17,17 +27,20 @@ class DatePickerCharts extends Component { render() { const { date_picker_store } = this.context; + const { isform } = this.props; + const defaultV = [date_picker_store.start_date, date_picker_store.end_date]; + const defaultVdiff = [date_picker_store.start_date_cp, date_picker_store.end_date_cp]; return (
- + { date_picker_store.onChange_dataPicker(e); if (typeof this.props.onChange === 'function') { @@ -46,19 +59,20 @@ class DatePickerCharts extends Component { 今年: [moment().startOf("year"), moment().endOf("year")], 去年: [moment().subtract(1, "year").startOf("year"), moment().subtract(1, "year").endOf("year")], }} - /> + /> + {this.props.hide_vs ? ( "" ) : ( - + { @@ -76,7 +90,7 @@ class DatePickerCharts extends Component { 前三个月: [moment().subtract(5, "month").startOf("month"), moment().subtract(3, "month").endOf("month")], 去年: [moment().subtract(1, "year").startOf("year"), moment().subtract(1, "year").endOf("year")], }} - /> + /> )} diff --git a/src/components/search/GroupSelect.jsx b/src/components/search/GroupSelect.jsx index 0dc2fc6..24daa00 100644 --- a/src/components/search/GroupSelect.jsx +++ b/src/components/search/GroupSelect.jsx @@ -32,7 +32,7 @@ class GroupSelect extends Component { {...extProps} > {_show_all ? ( - + 所有小组 ) : ( diff --git a/src/components/search/Input.jsx b/src/components/search/Input.jsx new file mode 100644 index 0000000..2317d5c --- /dev/null +++ b/src/components/search/Input.jsx @@ -0,0 +1,133 @@ +import React from 'react'; +import { Select } from 'antd'; +import querystring from 'querystring'; +// import * as oMapper from 'object-mapper'; +import { fetchJSON } from './../../utils/request'; +import { observer } from 'mobx-react'; +import { objectMapper } from './../../utils/commons'; + +const { Option } = Select; + +let timeout; +let currentValue; + +function curl(opts, callback) { + if (timeout) { + clearTimeout(timeout); + timeout = null; + } + currentValue = opts.value; + + function fake() { + // console.log(currentValue, opts.value); + if (currentValue === opts.value && opts.value === '空') { + const _p = [{ 'key': '0', 'label': '空' }]; + return callback(_p); + } + const param = { + code: 'utf-8', + q: opts.value, + }; + // const str = new URLSearchParams({ + // code: 'utf-8', + // q: opts.value, + // }).toString(); + + fetchJSON(`${opts.url}`, param) + .then(d => { + if (currentValue === opts.value) { + const result = objectMapper(d.result, opts.map) || []; + callback(result); + } + }); + } + + timeout = setTimeout(fake, 300); +} + +/** + * 异步请求的下拉菜单, 可搜索 + * @property {array} defaultOptions 默认选项 [{key: '', label: '' }] + * @property {string} url + * @property {object} map 异步结果的字段转换定义 + * @property {boolean} autoGet 首次默认请求 + * @property {string} resultkey 结果的根字段 + */ +class SearchInput extends React.Component { + + constructor(props) { + super(props); + this.state = { + data: this.props.defaultOptions || [], + value: undefined, + autoData: this.props.defaultOptions || [], + }; + } + + componentDidMount() { + if (this.props.autoGet === true) { + const { map, resultkey } = this.props; + const mapKey = Object.keys(map).reduce((r, v) => ({ ...r, [v]: { key: map[v] } }), {}); + curl({ value: '', url: this.props.url || '', map: mapKey, resultkey }, (data) => + this.setState({ data, autoData: data }, () => (typeof this.props.onSearchAfter === 'function' ? this.props.onSearchAfter(data, this.state.value) : '')) + ); + } + } + + componentDidUpdate(prevProps) { + if (this.props.value !== prevProps.value) { + this.setState({ value: undefined }); + } + } + + handleClear = () => { + this.setState({ data: this.state.autoData }); + }; + + handleSearch = value => { + if ( ! this.props.url && this.props.defaultOptions?.length) { + const f = this.props.defaultOptions.filter(r => String(r.label).indexOf(value) !== -1); + this.setState({ data: f || [] }); + return false; + } + const { map, resultkey } = this.props; + const mapKey = Object.keys(map).reduce((r, v) => ({ ...r, [v]: { key: map[v] } }), {}); + if (value) { + curl({ value, url: this.props.url || '', map: mapKey, resultkey }, (data) => + this.setState({ data }, () => (typeof this.props.onSearchAfter === 'function' ? this.props.onSearchAfter(data, this.state.value) : '')) + ); + } else { + this.setState({ data: this.state.autoData || [] }); + } + }; + + handleChange = (value, option) => { + this.setState({ value }, () => this.props.onChange(value, option)); + }; + + render() { + const options = this.state.data.map(d => ); + const { onSearchAfter, defaultOptions, autoGet, ...props } = this.props; + return ( + + ); + } +} +export default observer(SearchInput); diff --git a/src/components/search/SearchForm.jsx b/src/components/search/SearchForm.jsx index 74d634e..02b0ad6 100644 --- a/src/components/search/SearchForm.jsx +++ b/src/components/search/SearchForm.jsx @@ -1,4 +1,5 @@ import { createContext } from 'react'; +import { toJS } from "mobx"; import { observer } from 'mobx-react'; import { DATE_FORMAT } from './../../config'; import { SearchOutlined, } from "@ant-design/icons"; @@ -11,7 +12,9 @@ import SiteSelect from './SiteSelect'; import DateTypeSelect from './DataTypeSelect'; import DatePickerCharts from './DatePickerCharts'; import YearPickerCharts from './YearPickerCharts'; +import SearchInput from './Input'; import { objectMapper, at } from './../../utils/commons'; + import './search.css'; const EditableContext = createContext(); @@ -19,8 +22,12 @@ const Option = Select.Option; /** * 搜索表单 - * @property defaultValue - * * { initialValue, fieldProps, hides, shows, sort } + * @property defaultValue { initialValue, fieldProps, hides, shows, sort } + * * {object} initialValue 默认值 + * * {object} fieldProps 表单项属性 + * * {array} hides 隐藏的表单项 + * * {array} shows 显示的表单项 + * * {object} sort 表单项排序 * @property onSubmit */ export default observer((props) => { @@ -33,7 +40,6 @@ export default observer((props) => { shows: [], ...props.defaultValue, }; - const { onSubmit } = props; const onFinish = (values) => { @@ -54,14 +60,14 @@ export default observer((props) => { 'DepartmentList': { key: 'DepartmentList', transform: (value) => { - return Array.isArray(value) ? value.map((ele) => ele.key).join(',') : value ? (!isNaN(parseInt(value.key), 10) ? value.key : '') : '-1'; + return Array.isArray(value) ? value.map((ele) => ele.key).join(',') : value ? value.key : 'ALL'; }, default: '', }, 'WebCode': { key: 'WebCode', transform: (value) => { - return Array.isArray(value) ? value.map((ele) => ele.key).join(',') : value ? (!isNaN(parseInt(value.key), 10) ? value.key : '') : '-1'; + return Array.isArray(value) ? value.map((ele) => ele.key).join(',') : value ? (value.key) : 'ALL'; }, default: '', }, @@ -70,6 +76,11 @@ export default observer((props) => { transform: (value) => value?.key || '', default: '', }, + 'operator': { + key: 'operator', + transform: (value) => value?.key || '', + default: '', + }, 'applyDate': [ { key: 'Date1', @@ -147,7 +158,7 @@ export default observer((props) => {
- {getFields({ sort, initialValue, hides, shows, fieldProps })} + {getFields({ sort, initialValue, hides, shows, fieldProps, form })} {/* 'textAlign': 'right' */} @@ -166,7 +177,7 @@ export default observer((props) => { }); function getFields(props) { - const { fieldProps } = props; + const { fieldProps, form } = props; const bigCol = 4 * 2; const midCol = 6; const layoutProps = { @@ -198,7 +209,7 @@ function getFields(props) { item( 'DepartmentList', 99, - + ), @@ -263,7 +274,7 @@ function getFields(props) { 'dates', 99, - + , midCol ), @@ -273,14 +284,30 @@ function getFields(props) { {/* */} - ,2 + , + 2 ), item( 'months', 99, - - ,2 + + , + 2 + ), + item( + 'operator', + 99, + + + + ), + item( + 'country', + 99, + + + ), ]; baseChildren = baseChildren diff --git a/src/libs/ht.js b/src/libs/ht.js index ed93759..381fbcc 100644 --- a/src/libs/ht.js +++ b/src/libs/ht.js @@ -7,29 +7,40 @@ export const biz = [ { key: '2', label: '国际事业部', code: '' }, { key: '4', label: '孵化学院', code: '' }, ]; +export const bu = [ + { key: '91001', value: '91001', label: 'CH事业部' }, + { key: '91002', value: '91002', label: '商旅事业部' }, + { key: '91003', value: '91003', label: '国际事业部' }, + { key: '91004', value: '91004', label: 'CT事业部' }, + { key: '91005', value: '91005', label: '德语事业部' }, + { key: '91006', value: '91006', label: 'AH亚洲项目组' }, + { key: '91009', value: '91009', label: 'Trippest项目组' }, + { key: '91010', value: '91010', label: '花梨鹰' }, + { key: '91012', value: '91012', label: '西语组' }, +]; /** * 小组 */ export const groups = [ - { key: '1,2,28,7,33', label: 'GH事业部', code: 'GH', children: [] }, - { key: '8,9,11,12,20,21', label: '国际事业部', code: 'INT', children: [] }, - { key: '10,18,16,30', label: '孵化学院', code: '', children: [] }, - { key: '1', label: 'CH直销', code: '', children: [] }, - { key: '2', label: 'CH大客户', code: '', children: [] }, - { key: '28', label: 'AH亚洲项目组', code: 'AH', children: [] }, - { key: '33', label: 'GH项目组', code: '', children: [] }, - { key: '7', label: '市场推广', code: '', children: [] }, - { key: '8', label: '德语', code: '', children: [] }, - { key: '9', label: '日语', code: '', children: [] }, - { key: '11', label: '法语', code: '', children: [] }, - { key: '12', label: '西语', code: '', children: [] }, - { key: '20', label: '俄语', code: '', children: [] }, - { key: '21', label: '意语', code: '', children: [] }, - { key: '10', label: '商旅', code: '', children: [] }, - { key: '18', label: 'CT', code: 'CT', children: [] }, - { key: '16', label: 'APP', code: 'APP', children: [] }, - { key: '30', label: 'Trippest', code: 'TP', children: [] }, - { key: '31', label: '花梨鹰', code: '', children: [] }, + { value: '1,2,28,7,33', key: '1,2,28,7,33', label: 'GH事业部', code: 'GH', children: [1,2,28,7,33] }, + { value: '8,9,11,12,20,21', key: '8,9,11,12,20,21', label: '国际事业部', code: 'INT', children: [8,9,11,12,20,21] }, + { value: '10,18,16,30', key: '10,18,16,30', label: '孵化学院', code: '', children: [10,18,16,30] }, + { value: '1', key: '1', label: 'CH直销', code: '', children: [] }, + { value: '2', key: '2', label: 'CH大客户', code: '', children: [] }, + { value: '28', key: '28', label: 'AH亚洲项目组', code: 'AH', children: [] }, + { value: '33', key: '33', label: 'GH项目组', code: '', children: [] }, + { value: '7', key: '7', label: '市场推广', code: '', children: [] }, + { value: '8', key: '8', label: '德语', code: '', children: [] }, + { value: '9', key: '9', label: '日语', code: '', children: [] }, + { value: '11', key: '11', label: '法语', code: '', children: [] }, + { value: '12', key: '12', label: '西语', code: '', children: [] }, + { value: '20', key: '20', label: '俄语', code: '', children: [] }, + { value: '21', key: '21', label: '意语', code: '', children: [] }, + { value: '10', key: '10', label: '商旅', code: '', children: [] }, + { value: '18', key: '18', label: 'CT', code: 'CT', children: [] }, + { value: '16', key: '16', label: 'APP', code: 'APP', children: [] }, + { value: '30', key: '30', label: 'Trippest', code: 'TP', children: [] }, + { value: '31', key: '31', label: '花梨鹰', code: '', children: [] }, ]; export const groupsMappedByCode = groups.reduce((a, c) => ({ ...a, [String(c.code || c.key)]: c }), {}); @@ -42,7 +53,7 @@ export const sites = [ { key: '163', label: 'GH', code: 'GH' }, { key: '28', label: '客运中国', code: 'GHKYZG' }, { key: '7', label: '客运海外', code: 'GHKYHW' }, - { key: '172', label: 'B业务', code: 'GHTOB' }, + { key: '172', label: 'GH TO B业务', code: 'GHTOB' }, { key: '11,12,20,21,10,18', label: '国际(入境)', code: 'JP,VAC,IT,GM,RU,VC' }, { key: '122,200,211,100,188', label: '国际(海外)', code: 'VACHW,ITHW,GMHW,RUHW,VCHW' }, { key: '11', label: '日语', code: 'JP' }, @@ -70,7 +81,7 @@ export const dateTypes = [ * 结果字段 */ export const dataFieldOptions = [ - { label: '毛利', value: 'SumML', formatter: (v) => `${v / 1000} K` }, + { label: '毛利', value: 'SumML', formatter: (v) => `${v / 1000} K`, nestkey: { p: 'MLKPIrates', v: 'MLKPIvalue' } }, { label: '订单数', value: 'OrderCount', formatter: (v) => v }, { label: '成交数', value: 'CJCount', formatter: (v) => v }, // { label: '成交人数', value: 'CJPersonNum', formatter: (v) => v },