KPI 批量设置; 增加日期范围类型

feature/2.0-sales-trade
Lei OT 2 years ago
parent 1c78a0c64f
commit a5e9e8aaf0

@ -6,6 +6,7 @@ import SearchForm from './../search/SearchForm';
import { bu, KPIObjects, KPISubjects } from './../../libs/ht';
import { isEmpty, fixTo2Decimals, fixTo4Decimals, cloneDeep, numberFormatter, fixToInt, merge } from './../../utils/commons';
import ProfitTable from './SubjectTable/Profit';
import { toJS } from 'mobx';
const Todo = (props) => {
return <h2>TODO</h2>;
@ -28,7 +29,7 @@ export default observer((props) => {
const { KPIStore, DictDataStore, date_picker_store: searchFormStore } = useContext(stores_Context);
const { sort, initialValue, hides, shows, fieldProps: _fieldProps } = {
sort: '',
initialValue: searchFormStore.formValues,
initialValue: '', // searchFormStore.formValues,
fieldProps: {},
hides: [],
shows: ['DateType', 'years'],
@ -43,15 +44,15 @@ export default observer((props) => {
<Col className="gutter-row mb-n1 p-none" span={24}>
<SearchForm
defaultValue={{
initialValue,
sort, initialValue,
shows,
fieldProps,
}}
confirmText="查询"
onSubmit={(_err, obj, form, str) => {
console.log('invoke kpi setting search');
// console.log('invoke kpi setting search');
if (typeof onSearchSubmit === 'function') {
onSearchSubmit(obj);
onSearchSubmit(obj, form);
}
}}
/>
@ -63,6 +64,7 @@ export default observer((props) => {
tabPosition={'left'}
onChange={(sub) => {
KPIStore.setSettingSubject(sub);
// onSearchSubmit(searchFormStore.formValuesToSub);
}}
items={KPISubjects.map((ele, i) => {
const SubjectTableComponent = subjectComponents[ele.key];

@ -1,16 +1,15 @@
import { useContext } from 'react';
import { observer } from 'mobx-react';
// import { stores_Context } from '../config';
import { Table } from 'antd';
import KPISettings from './KPISettings';
import { bu, KPISubjects } from '../../libs/ht';
const sort = { DateType: 10, years: 11 };
const yearInitial = {};
const searchFormItemSet = {
'bu': { shows: ['DateType', 'years', 'HTBusinessUnits'] },
'dept': { shows: ['DateType', 'years', 'DepartmentList'], fieldProps: { DepartmentList: { allowClear: true } } },
'operator': { shows: ['DateType', 'years', 'DepartmentList'] }, // , 'operator'
'destination': { shows: ['DateType', 'years', 'destination'] },
'country': { shows: ['DateType', 'years', 'country'] },
'bu': { shows: ['DateType', 'years', 'HTBusinessUnits'], sort },
'dept': { shows: ['DateType', 'years', 'DepartmentList'], sort, fieldProps: { DepartmentList: { allowClear: true,isLeaf: true, show_all: false } }, },
'operator': { shows: ['DateType', 'years', 'DepartmentList', 'operator'], fieldProps: { DepartmentList: { allowClear: true, isLeaf: true }, operator: { param: { is_assign: 1 } } }, sort },
'destination': { shows: ['DateType', 'years', 'destination'], sort },
'country': { shows: ['DateType', 'years', 'country'], sort },
};
export default observer((props) => {

@ -129,6 +129,7 @@ export default observer((props) => {
value: mVal,
kpi_id: curObj.kpiDataMapped?.[`M${mIndex}`]?.kpi_id || undefined,
key: undefined,
group_date_type: 'month',
};
});
return r.concat(allMonth);
@ -143,6 +144,7 @@ export default observer((props) => {
start_date: moment([KPIStore.settingYear, 0, 1]).format('YYYY-MM-DD'),
end_date: moment([KPIStore.settingYear, 11, 1]).endOf('M').format('YYYY-MM-DD HH:mm'),
kpi_id: kpiYear?.kpi_id || undefined,
group_date_type: 'year',
}))(dataSource?.[0] || {});
tableData.unshift(yearRow);
console.log('sub', tableData, delKpiIds);

@ -24,11 +24,11 @@ export default observer((props) => {
const [editableRowsKeys, setEditableRowKeys] = useState([]);
useEffect(() => {
setDataSource(KPIStore.pageData);
setEditableRowKeys([]);
setEditOpen(false);
return () => {};
}, [KPIStore.pageData]);
const PercentInput = useMemo(
() =>
// eslint-disable-next-line react/display-name
@ -84,7 +84,7 @@ export default observer((props) => {
title: '年度目标',
dataIndex: 'yearValue',
valueType: 'digit',
fieldProps: { style: { width: '100%' }, step: 10000*100 },
fieldProps: { style: { width: '100%' }, step: 10000 * 100 },
formItemProps: {
style: { width: '100%' },
},
@ -138,10 +138,9 @@ export default observer((props) => {
value: mVal,
kpi_id: curObj.kpiDataMapped?.[`M${mIndex}`]?.kpi_id || undefined,
key: undefined,
group_date_type: 'month',
};
});
return r.concat(allMonth);
}, []);
const yearRow = (({ object, object_name, object_id, subject, date_type, yearValue, kpiYear }) => ({
object,
object_name,
@ -152,8 +151,10 @@ export default observer((props) => {
start_date: moment([KPIStore.settingYear, 0, 1]).format('YYYY-MM-DD'),
end_date: moment([KPIStore.settingYear, 11, 1]).endOf('M').format('YYYY-MM-DD HH:mm'),
kpi_id: kpiYear?.kpi_id || undefined,
}))(dataSource?.[0] || {});
tableData.unshift(yearRow);
group_date_type: 'year',
}))(curObj);
return r.concat(allMonth, yearRow);
}, []);
console.log('sub', tableData, 'del:', delKpiIds);
// return false; // debug:
KPIStore.onSubmit(tableData, { delQueue: delKpiIds }).then((res) => {
@ -180,28 +181,37 @@ export default observer((props) => {
date_type: searchFormStore.formValuesToSub.DateType,
kpiDataMapped: {},
key: Date.now().toString(32),
group_date_type: 'month',
}),
{}
); // v.formItemProps.initialValue
const makeInitialTable = (e) => {
setEditOpen(e);
// todo: ,
if (e && isEmpty(dataSource)) {
// test: ,
const _initialRow = Object.assign({}, initialRow, initialPercentKey);
const _objects = isEmpty(objects) ? (curObjectItem?.data || []) : objects;
console.log('ooo', objects, isEmpty(objects), curObjectItem?.data || []);
const _objects = isEmpty(objects) ? curObjectItem?.data || [] : objects;
// console.log('ooo', objects, isEmpty(objects), curObjectItem?.data || []);
const _initialTable = _objects.map((obj) => ({
...cloneDeep(_initialRow),
object_name: obj.label,
object_id: obj.value,
key: Date.now().toString(32) + obj.value,
}));
console.log(_initialRow, 'iiiii');
// console.log(_initialRow, 'iiiii');
const mergePageData = Object.values(
Object.assign(
{},
_initialTable.reduce((r, v) => ({ ...r, [v.object_name]: v }), {}),
dataSource.reduce((r, v) => ({ ...r, [v.object_name]: v }), {})
)
);
if (e && isEmpty(dataSource)) {
setDataSource(_initialTable);
setEditableRowKeys(_initialTable.map((ele) => ele.key));
return false;
}
setEditableRowKeys(e ? dataSource.map((ele) => ele.key) : []);
setDataSource(mergePageData);
setEditableRowKeys(e ? mergePageData.map((ele) => ele.key) : []);
};
const [delKpiIds, setDelKpiIds] = useState([]);
return (
@ -226,13 +236,11 @@ export default observer((props) => {
return [defaultDoms.delete];
},
onDelete: (_key, _row) => {
// console.log('del', _key, _row);
const rowKpiIds = (_row?.kpiData || []).map((ele) => ele.kpi_id);
rowKpiIds.push(_row?.kpiYear?.kpi_id);
setDelKpiIds(rowKpiIds);
},
onValuesChange: (record, recordList) => {
// console.log('on edit, onValuesChange',record, recordList);
onTableChange(recordList);
},
onChange: (editableKeys, editableRows) => {
@ -242,9 +250,14 @@ export default observer((props) => {
/>
</Col>
<Col className="gutter-row mb-n1 p-none mt-1 align_center" span={24}>
<Space size={'large'}>
<Button className="mt-1 mb-1 align_center" disabled={!editOpen} type="primary" key="save" onClick={onTableSubmit}>
保存数据
</Button>
{!editOpen && <Button className="mt-1 mb-1 align_center" disabled={false} type={'ghost'} key="initTable" onClick={() => {makeInitialTable(true);}}>
编辑设置
</Button>}
</Space>
</Col>
</Row>
</>

@ -2,8 +2,8 @@ import { useContext } from 'react';
import { observer } from 'mobx-react';
// import { stores_Context } from '../config';
import { Button, Table, Switch, Input, Space, Typography, Row, Col, Spin, Radio, Tabs } from 'antd';
import SearchForm from './../search/SearchForm';
import { bu, KPIObjects } from './../../libs/ht';
import SearchForm from '../../search/SearchForm';
import { bu, KPIObjects } from '../../../libs/ht';
export default observer((props) => {
// const { } = useContext(stores_Context);

@ -1,7 +1,7 @@
import React, { Component } from 'react';
import { Select } from 'antd';
import { observer } from 'mobx-react';
import { groups } from '../../libs/ht';
import { groups, leafGroup } from '../../libs/ht';
class GroupSelect extends Component {
constructor(props) {
@ -9,9 +9,10 @@ class GroupSelect extends Component {
}
render() {
const { store, mode, value, onChange, show_all, ...extProps } = this.props;
const { store, mode, value, onChange, show_all, isLeaf, ...extProps } = this.props;
const _mode = mode || store?.group_select_mode || null;
const _show_all = ['tags', 'multiple'].includes(_mode) ? false : show_all;
const options = isLeaf===true ? leafGroup : groups;
return (
<div>
<Select
@ -38,7 +39,7 @@ class GroupSelect extends Component {
) : (
''
)}
{groups.map((ele) => (
{options.map((ele) => (
<Select.Option key={ele.key} value={ele.key}>
{ele.label}
</Select.Option>

@ -4,7 +4,7 @@ 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';
import { merge, objectMapper } from './../../utils/commons';
const { Option } = Select;
@ -24,10 +24,7 @@ function curl(opts, callback) {
const _p = [{ 'key': '0', 'label': '空' }];
return callback(_p);
}
const param = {
code: 'utf-8',
q: opts.value,
};
const param = merge({ code: 'utf-8', q: opts.value }, opts.param);
// const str = new URLSearchParams({
// code: 'utf-8',
// q: opts.value,
@ -66,9 +63,9 @@ class SearchInput extends React.Component {
componentDidMount() {
if (this.props.autoGet === true) {
const { map, resultkey } = this.props;
const { map, resultkey, param } = 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) =>
curl({ value: '', url: this.props.url || '', map: mapKey, resultkey, param }, (data) =>
this.setState({ data, autoData: data }, () => (typeof this.props.onSearchAfter === 'function' ? this.props.onSearchAfter(data, this.state.value) : ''))
);
}
@ -90,10 +87,10 @@ class SearchInput extends React.Component {
this.setState({ data: f || [] });
return false;
}
const { map, resultkey } = this.props;
const { map, resultkey, param } = 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) =>
curl({ value, url: this.props.url || '', map: mapKey, resultkey, param }, (data) =>
this.setState({ data }, () => (typeof this.props.onSearchAfter === 'function' ? this.props.onSearchAfter(data, this.state.value) : ''))
);
} else {
@ -102,6 +99,7 @@ class SearchInput extends React.Component {
};
handleChange = (value, option) => {
console.log('invoke denpendencies change', value);
this.setState({ value }, () => this.props.onChange(value, option));
};

@ -45,7 +45,6 @@ export default observer((props) => {
const { onSubmit, confirmText } = props;
const formValuesMapper = (values) => {
console.log('Received values of form, origin form value: ', values);
const destinationObject = {
'DateType': {
key: 'DateType',
@ -55,28 +54,28 @@ export default observer((props) => {
'HTBusinessUnits': {
key: 'HTBusinessUnits',
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 ? (!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 : '') : '-1';
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 : 'ALL';
return Array.isArray(value) ? value.map((ele) => ele.key).join(',') : value ? value.key : '';
},
default: '',
},
'WebCode': {
key: 'WebCode',
transform: (value) => {
return Array.isArray(value) ? value.map((ele) => ele.key).join(',') : value ? value.key : 'ALL';
return Array.isArray(value) ? value.map((ele) => ele.key).join(',') : value ? value.key : '';
},
default: '',
},
@ -154,12 +153,13 @@ export default observer((props) => {
}
// omit empty
Object.keys(dest).forEach((key) => (dest[key] == null || dest[key] === '' || dest[key].length === 0) && delete dest[key]);
console.log('form value send to onSubmit:', dest);
return dest;
};
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);
@ -175,8 +175,11 @@ export default observer((props) => {
};
const onValuesChange = (...args) => {
const [changedValues, allValues] = args;
console.log('form onValuesChange', args);
console.log('form onValuesChange', Object.keys(changedValues), args);
const dest = formValuesMapper(allValues);
searchFormStore.setFormValues(allValues);
searchFormStore.setFormValuesToSub(dest);
};
return (
@ -306,8 +309,15 @@ function getFields(props) {
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 name={'operator'} dependencies={['DepartmentList']} >
<SearchInput
autoGet
url="/service-Analyse2/GetOperatorInfo"
map={{ 'op_id': 'key', 'cn_name': 'label' }}
resultkey={'result'}
placeholder="输入搜索顾问: 中/英名字"
param={{ dept_id: (form.getFieldValue('DepartmentList')?.value || '').replace('ALL', ''), ...(fieldProps?.operator?.param || {}) }}
/>
</Form.Item>
),
item(

@ -55,7 +55,7 @@ export const groups = [
{ value: '31', key: '31', label: '花梨鹰', code: '', children: [] },
];
export const groupsMappedByCode = groups.reduce((a, c) => ({ ...a, [String(c.code || c.key)]: c }), {});
export const leafGroup = groups.slice(3);
/**
* 来源
*/

@ -1,15 +1,13 @@
{
"get|/service-web/baseinfo/operator/test": {
"get|/service-Analyse2/GetDestinationInfo/test": {
"errcode": 0,
"errmsg": "",
"data": null,
"loading": null,
"result|10": [
{
"mobile": "13@integer(99999999,999999999)",
"op_id": "@integer(10,99)",
"id": "@integer(10,99)",
"cn_name": "@cname",
"email": "@email",
"en_name": "@first",
"code": "@word(2,3)",
"key": "@increment"

@ -19,6 +19,14 @@ const modelMapper = {
en_name: { key: 'label_alias' },
},
},
'destination': {
url: '/service-Analyse2/GetDestinationInfo/test',
mapper: {
id: [{ key: 'key' }, { key: 'value' }],
cn_name: { key: 'label' },
en_name: { key: 'label_alias' },
},
},
'vendor': {
url: '/service-web/QueryData/GetVEIName',
mapper: {
@ -48,7 +56,7 @@ class DictData {
runInAction(() => {
this[mkey].loading = false;
this[mkey].dataSource = objectMapper(json.result, modelMapper[mkey].mapper);
console.log({ loading: false, ...json }, model, 'DictData', toJS(this[mkey]));
// console.log({ loading: false, ...json }, model, 'DictData', toJS(this[mkey]));
});
}
return this[mkey];

@ -44,7 +44,7 @@ class KPI {
this.listLoading = false;
this.originData = json.result;
const yearData = parseKPI(json.result, ['subject', 'object_id']);
console.log(111, yearData, yearData[this.settingYear]);
// console.log(111, yearData, yearData[this.settingYear]);
this.pageData = yearData?.[this.settingYear]?.[this.settingSubject] || [];
});
}

@ -2,7 +2,7 @@ import { useContext, useEffect, useState } from 'react';
import { stores_Context } from './../config';
import { observer } from 'mobx-react';
import { Row, Col, Tabs, Spin } from 'antd';
import { flush, objectMapper } from './../utils/commons';
import { flush, isEmpty, objectMapper } from './../utils/commons';
import { KPIObjects } from './../libs/ht';
import ObjectPanel from '../components/kpi/ObjectPanel';
import OverviewPanel from './../components/kpi/OverviewPanel';
@ -23,7 +23,7 @@ const objectFilterKey = {
// 'du': 'du',
// 'operator': 'operator',
// 'destination': 'destination',
// 'country': 'country',
'country': 'country',
};
export default observer((props) => {
const { KPIStore, DictDataStore, date_picker_store: searchFormStore } = useContext(stores_Context);
@ -42,13 +42,13 @@ export default observer((props) => {
}, [curObject]);
const [retObjects, setRetObjects] = useState([]);
const onSearchSubmit = (obj, formVal={}) => {
const onSearchSubmit = async (obj, formVal={}) => {
const getkpiParam = objectMapper(obj, {
DateType: { key: 'date_type' },
Date1: { key: 'start_date' },
Date2: { key: 'end_date' },
HTBusinessUnits: { key: 'object_id' },
DepartmentList: { key: 'object_id' },
DepartmentList: { key: curObject === 'dept' ? 'object_id' : 'dept_id' },
businessUnits: { key: 'object_id' },
WebCode: { key: 'object_id' },
operator: { key: 'object_id' },
@ -56,7 +56,24 @@ export default observer((props) => {
});
Object.assign(getkpiParam, { object: curObject });
KPIStore.setSettingYear(formVal?.year?.year() || KPIStore.settingYear);
console.log('invoke on search', obj, formVal, getkpiParam);
// console.log('invoke on search', obj, formVal, getkpiParam);
if (curObject === 'operator') {
const searchOperator = await DictDataStore.fetchDictData('operator', {
is_assign: 1,
dept_id: (obj?.DepartmentList || '').replace('ALL', ''),
q: searchFormStore.formValues?.operator?.label || '',
});
if ((!isEmpty(getkpiParam.dept_id) && getkpiParam.dept_id !== 'ALL')
|| !isEmpty(searchFormStore.formValues?.operator)) {
// && isEmpty(getkpiParam.object_id)
setRetObjects(searchOperator.dataSource);
getkpiParam.object_id = searchOperator.dataSource.map((ele) => ele.key).join(',');
delete getkpiParam.dept_id;
}
}
getKPIList(getkpiParam);
};
const getKPIList = (getkpiParam) => {
KPIStore.getList(getkpiParam).then((data) => {
// setDataSource(data);
if (objectFilterKey?.[curObject]) {

Loading…
Cancel
Save