feat: 搜索组件: 基础信息字典获取

feature/2.0-sales-trade
Lei OT 2 years ago
parent 44647bee3b
commit 76a3c3c94d

@ -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}</>
) : (
<Form.Item noStyle {...extProps}>
{children}
</Form.Item>
);
//
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 (
<div>
<Row>
<Col span={24}>
<Form.Item name={`applyDate`} noStyle initialValue={[date_picker_store.start_date, date_picker_store.end_date]}>
<SectionWrapper {...{isform: isform || false, initialValue: defaultV, name: `applyDate`}} >
<DatePicker.RangePicker
style={{width: '100%'}}
format={config.DATE_FORMAT}
locale={locale}
allowClear={false}
// value={[date_picker_store.start_date, date_picker_store.end_date]}
{...(isform ? {} : {value: defaultV})}
onChange={(e) => {
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")],
}}
/></Form.Item>
/>
</SectionWrapper>
</Col>
{this.props.hide_vs ? (
""
) : (
<Col span={24}>
<Form.Item name={`applyDate2`} noStyle initialValue={[date_picker_store.start_date_cp, date_picker_store.end_date_cp]}>
<SectionWrapper {...{isform: isform || false, initialValue: defaultVdiff, name: `applyDate2`}} >
<DatePicker.RangePicker
bordered={false}
style={{width: '100%'}}
format={config.DATE_FORMAT}
locale={locale}
// value={[date_picker_store.start_date_cp, date_picker_store.end_date_cp]}
{...(isform ? {} : {value: defaultVdiff})}
placeholder={["对比 Start date", "End date"]}
// onChange={date_picker_store.onChange_dataPicker_cp}
onChange={(value) => {
@ -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")],
}}
/></Form.Item>
/></SectionWrapper>
</Col>
)}
</Row>

@ -32,7 +32,7 @@ class GroupSelect extends Component {
{...extProps}
>
{_show_all ? (
<Select.Option key="0" value="0">
<Select.Option key="ALL" value="ALL">
所有小组
</Select.Option>
) : (

@ -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 => <Option key={d.key} extradata={d.options}>{d.label}</Option>);
const { onSearchAfter, defaultOptions, autoGet, ...props } = this.props;
return (
<Select
{...props}
style={this.props.style || { width: '100%' }}
showSearch
labelInValue
value={this.state.value || this.props.value}
placeholder={this.props.placeholder}
defaultActiveFirstOption={false}
showArrow={false}
filterOption={false}
onSearch={this.handleSearch}
onChange={this.handleChange}
notFoundContent={null}
allowClear={true}
onClear={this.handleClear}
>
{options}
</Select>
);
}
}
export default observer(SearchInput);

@ -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) => {
<Form form={form} name="advanced_search" className="orders-search-form" onFinish={onFinish}>
<EditableContext.Provider value={form}>
<Row gutter={10} style={{ background: '#f9fafa', margin: '0px 0px 10px 0px', padding: '16px 8px' }}>
{getFields({ sort, initialValue, hides, shows, fieldProps })}
{getFields({ sort, initialValue, hides, shows, fieldProps, form })}
{/* 'textAlign': 'right' */}
<Col flex="1 0 120px" style={{ padding: '0px 5px', }}>
<Space align="center">
@ -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,
<Form.Item name={`DepartmentList`} initialValue={at(props, 'initialValue.DepartmentList')[0] || (fieldProps?.DepartmentList?.show_all ? { key: '0', label: '所有小组' } : undefined)}>
<Form.Item name={`DepartmentList`} initialValue={at(props, 'initialValue.DepartmentList')[0] || (fieldProps?.DepartmentList?.show_all ? { key: 'ALL', label: '所有小组' } : undefined)}>
<GroupSelect {...fieldProps.DepartmentList} />
</Form.Item>
),
@ -263,7 +274,7 @@ function getFields(props) {
'dates',
99,
<Form.Item>
<DatePickerCharts {...fieldProps.dates} />
<DatePickerCharts isform={true} {...fieldProps.dates} form={form} />
</Form.Item>,
midCol
),
@ -273,14 +284,30 @@ function getFields(props) {
<Form.Item>
{/* <DatePicker picker="year" placeholder='年份' /> */}
<YearPickerCharts {...fieldProps.years} />
</Form.Item>,2
</Form.Item>,
2
),
item(
'months',
99,
<Form.Item>
<DatePicker picker="month" placeholder='月份' />
</Form.Item>,2
<DatePicker picker="month" placeholder="月份" />
</Form.Item>,
2
),
item(
'operator',
99,
<Form.Item name={'operator'}>
<SearchInput autoGet url="/service-Analyse2/GetOperatorInfo" map={{ 'op_id': 'key' , 'cn_name': 'label' }} resultkey={'result'} placeholder="输入搜索顾问: 中/英名字" />
</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>
),
];
baseChildren = baseChildren

@ -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 },

Loading…
Cancel
Save