提交 53014a2d authored 作者: vipcxj's avatar vipcxj

最初的数据源到表格组件的实现

上级 c60b339d
import React from 'react'; import React from 'react';
import moment from 'moment'; import PropTypes from 'prop-types';
import modelCreator from './model'; import modelCreator from './model';
import connect from '../../hoc/stateful'; import connect from '../../hoc/stateful';
import TableEx from '../../../components/table/index'; import TableEx from '../../../components/table/index';
import config from '../../../utils/config';
import styles from './index.less'; import styles from './index.less';
const columns = [{ // const columns = [{
title: '流程', // title: '流程',
dataIndex: 'pName', // dataIndex: 'pName',
key: 'pName', // key: 'pName',
filterType: 'text', // filterType: 'text',
}, { // }, {
title: '任务', // title: '任务',
dataIndex: 'nName', // dataIndex: 'nName',
key: 'nName', // key: 'nName',
filterType: 'text', // filterType: 'text',
}, { // }, {
title: '状态', // title: '状态',
dataIndex: 'state', // dataIndex: 'state',
key: 'state', // key: 'state',
filterType: 'enum', // filterType: 'enum',
filterEnums: [{ // filterEnums: [{
text: '状态1', // text: '状态1',
value: '状态1', // value: '状态1',
}, { // }, {
text: '状态2', // text: '状态2',
value: '状态2', // value: '状态2',
}, { // }, {
text: '状态3', // text: '状态3',
value: '状态3', // value: '状态3',
}, { // }, {
text: '状态4', // text: '状态4',
value: '状态4', // value: '状态4',
}, { // }, {
text: '状态5', // text: '状态5',
value: '状态5', // value: '状态5',
}], // }],
}, { // }, {
title: '日期', // title: '日期',
dataIndex: 'date', // dataIndex: 'date',
key: 'date', // key: 'date',
filterType: 'date', // filterType: 'date',
render(date) { // render(date) {
return date.format(config.defaultDateTimeFormat); // return date.format(config.defaultDateTimeFormat);
}, // },
}, { // }, {
title: '期限', // title: '期限',
dataIndex: 'deadline', // dataIndex: 'deadline',
key: 'deadline', // key: 'deadline',
render(deadline) { // render(deadline) {
const now = moment(); // const now = moment();
const late = deadline.diff(now, 'days', true); // const late = deadline.diff(now, 'days', true);
if (late < 0) { // if (late < 0) {
const style = { // const style = {
color: '#f04134', // color: '#f04134',
}; // };
return <span style={style}>{ `超时 ${deadline.from(now, true)}` }</span>; // return <span style={style}>{ `超时 ${deadline.from(now, true)}` }</span>;
} else if (late < 1) { // } else if (late < 1) {
const style = { // const style = {
color: '#ffbf00', // color: '#ffbf00',
}; // };
return <span style={style}>{ `仅剩 ${deadline.to(now, true)}` }</span>; // return <span style={style}>{ `仅剩 ${deadline.to(now, true)}` }</span>;
} else { // } else {
const style = { // const style = {
color: '#00a854', // color: '#00a854',
}; // };
return <span style={style}>{ `还剩 ${deadline.to(now, true)}` }</span>; // return <span style={style}>{ `还剩 ${deadline.to(now, true)}` }</span>;
} // }
}, // },
}]; // }];
class DsTable extends React.Component { class DsTable extends React.Component {
...@@ -77,7 +76,6 @@ class DsTable extends React.Component { ...@@ -77,7 +76,6 @@ class DsTable extends React.Component {
constructor(props, context) { constructor(props, context) {
super(props, context); super(props, context);
this.loadData = this::this.loadData; this.loadData = this::this.loadData;
this.getCurrent = this::this.getCurrent;
this.state = { this.state = {
filters: [], filters: [],
current: 1, current: 1,
...@@ -87,12 +85,6 @@ class DsTable extends React.Component { ...@@ -87,12 +85,6 @@ class DsTable extends React.Component {
componentDidMount() { componentDidMount() {
this.loadData(); this.loadData();
} }
getCurrent() {
const { num } = this.props.task;
const pageNum = ((num / this.state.pageSize) | 0) + 1;
const current = this.state.current > pageNum ? pageNum : this.state.current;
return current;
}
loadData() { loadData() {
const filters0 = this.state.filters const filters0 = this.state.filters
.filter(({ filter }) => !!filter) .filter(({ filter }) => !!filter)
...@@ -102,15 +94,16 @@ class DsTable extends React.Component { ...@@ -102,15 +94,16 @@ class DsTable extends React.Component {
])); ]));
const psz = this.state.pageSize; // eslint-disable-line no-shadow const psz = this.state.pageSize; // eslint-disable-line no-shadow
const pst = (this.state.current - 1) * psz; const pst = (this.state.current - 1) * psz;
this.props.dispatchLocal({ type: 'fetchTasks', payload: { pst, psz, filters: filters0 } }); this.props.dispatchLocal({ type: 'fetchData', payload: { coordinate: this.props.coordinate, pst, psz, filters: filters0 } });
} }
render() { render() {
const { list, num } = this.props.task; const { rowKey, columns, list, num } = this.props.model;
const tableProps = { const tableProps = {
dataSource: list, dataSource: list,
rowKey,
columns, columns,
filters: this.state.filters.map(filter => filter.filter), filters: this.state.filters.map(filter => filter.filter),
loading: this.props.loading.effect.fetchTasks, loading: this.props.loading.effect.fetchData,
pagination: { pagination: {
current: this.state.current, current: this.state.current,
total: num, total: num,
...@@ -143,6 +136,19 @@ class DsTable extends React.Component { ...@@ -143,6 +136,19 @@ class DsTable extends React.Component {
} }
} }
DsTable.propTypes = {
coordinate: PropTypes.oneOfType(
[
PropTypes.string,
PropTypes.shape({
containerType: PropTypes.string,
containerName: PropTypes.string,
datasourceName: PropTypes.string,
}),
],
).isRequired,
};
export default connect(modelCreator, { export default connect(modelCreator, {
mapStateToProps: ({ loading }) => ({ loading }), mapStateToProps: ({ loading }) => ({ loading }),
})(DsTable); })(DsTable);
import moment from 'moment';
import uuid from 'uuid/v4'; import uuid from 'uuid/v4';
import _ from 'lodash'; import _ from 'lodash';
import { datasourceApi } from '../../../services/datasource'; import { datasourceApi } from '../../../services/datasource';
import { countTasks, fetchTasks } from '../../../services/bpm';
import config from '../../../utils/config';
const prefix = uuid(); const prefix = uuid();
...@@ -24,6 +21,12 @@ const getMeta = (property, name, parsed = false, defaultValue) => { ...@@ -24,6 +21,12 @@ const getMeta = (property, name, parsed = false, defaultValue) => {
return result.length > 0 ? result[0] : defaultValue; return result.length > 0 ? result[0] : defaultValue;
}; };
const getRowIndex = (meta) => {
return _(meta.properties || [])
.filter(property => !property.skip)
.findIndex(property => property.key);
};
const makeColumns = (meta) => { const makeColumns = (meta) => {
return (meta.properties || []) return (meta.properties || [])
.filter(property => !property.skip) .filter(property => !property.skip)
...@@ -40,7 +43,7 @@ const makeColumns = (meta) => { ...@@ -40,7 +43,7 @@ const makeColumns = (meta) => {
const getArrayData = ({ dataType, arrayData, singularData }, meta) => { const getArrayData = ({ dataType, arrayData, singularData }, meta) => {
if (dataType === 'TABLE') { if (dataType === 'TABLE') {
return arrayData || []; return (arrayData && arrayData.map(v => _.toPlainObject(v))) || [];
} else if (dataType === 'PROPERTIES') { } else if (dataType === 'PROPERTIES') {
const data = []; const data = [];
(meta.properties || []) (meta.properties || [])
...@@ -48,14 +51,14 @@ const getArrayData = ({ dataType, arrayData, singularData }, meta) => { ...@@ -48,14 +51,14 @@ const getArrayData = ({ dataType, arrayData, singularData }, meta) => {
.forEach((property) => { .forEach((property) => {
data.push((singularData || {})[property.name]); data.push((singularData || {})[property.name]);
}); });
return [data]; return [_.toPlainObject(data)];
} else { } else {
throw new Error(`Unsupported data type: ${dataType}`); throw new Error(`Unsupported data type: ${dataType}`);
} }
}; };
const modelCreator = () => { const modelCreator = () => {
const name = 'task'; const name = 'model';
const namespace = _.uniqueId(prefix); const namespace = _.uniqueId(prefix);
return { return {
name, name,
...@@ -63,13 +66,15 @@ const modelCreator = () => { ...@@ -63,13 +66,15 @@ const modelCreator = () => {
namespace, namespace,
state: { state: {
columns: [], columns: [],
rowKey: '',
num: 0, num: 0,
list: [], list: [],
}, },
reducers: { reducers: {
queryMetaSuccess(state, { payload: columns }) { queryMetaSuccess(state, { payload: { rowKey, columns } }) {
return { return {
...state, ...state,
rowKey,
columns, columns,
} }
}, },
...@@ -90,31 +95,14 @@ const modelCreator = () => { ...@@ -90,31 +95,14 @@ const modelCreator = () => {
*fetchData({ payload: { coordinate, pst, psz, params, filters} }, { put, call }) { *fetchData({ payload: { coordinate, pst, psz, params, filters} }, { put, call }) {
const options = { pst, psz, params, filters }; const options = { pst, psz, params, filters };
const api = datasourceApi(coordinate); const api = datasourceApi(coordinate);
const meta = api.meta(); const meta = yield call(api.meta);
yield put({ type: 'queryMetaSuccess', payload: makeColumns(meta) }); const rowKey = `${getRowIndex(meta)}`;
yield put({ type: 'queryMetaSuccess', payload: { rowKey, columns: makeColumns(meta) } });
const num = yield call(api.count, options); const num = yield call(api.count, options);
yield put({ type: 'queryCountSuccess', payload: num }); yield put({ type: 'queryCountSuccess', payload: num });
const dsb = yield call(api.query, options); const dsb = yield call(api.query, options);
yield put({ type: 'queryTasksSuccess', payload: getArrayData(dsb, meta) }); yield put({ type: 'queryTasksSuccess', payload: getArrayData(dsb, meta) });
}, },
*fetchTasks({ payload: { pst, psz, filters } }, { put, call }) {
const num = Number.parseInt(yield call(countTasks, filters), 10);
yield put({ type: 'queryCountSuccess', payload: num });
const tasks = yield call(fetchTasks, { pst, psz, filters });
yield put({
type: 'queryTasksSuccess',
payload: tasks.map((task) => {
return {
key: `${task.pId}-${task.nId}`,
pName: task.pName,
nName: task.nName,
state: task.state,
date: moment(task.date, config.defaultDateTimeFormat),
deadline: moment(task.deadline, config.defaultDateTimeFormat),
};
}),
});
},
}, },
subscriptions: {}, subscriptions: {},
}, },
......
...@@ -12,7 +12,7 @@ const createMenus = () => { ...@@ -12,7 +12,7 @@ const createMenus = () => {
return null; return null;
} }
const [cur, ...rest] = path; const [cur, ...rest] = path;
const find = _menus.filter(menu => menu.name === cur).pop(); const find = _menus.filter(menu => menu.name === `${cur}`).pop();
if (find) { if (find) {
if (rest.length === 0) { if (rest.length === 0) {
return find; return find;
...@@ -24,7 +24,7 @@ const createMenus = () => { ...@@ -24,7 +24,7 @@ const createMenus = () => {
for (const id of path) { for (const id of path) {
const m = getModule(id); const m = getModule(id);
const menu = { const menu = {
name: m.id, name: `${m.id}`,
text: m.name, text: m.name,
children: [], children: [],
}; };
......
...@@ -36,7 +36,7 @@ const authenticated = (nextState, replace) => { ...@@ -36,7 +36,7 @@ const authenticated = (nextState, replace) => {
const createRoute = async (app, module) => { const createRoute = async (app, module) => {
const route = { const route = {
path: module.id, path: `${module.id}`,
name: module.name, name: module.name,
}; };
if (!module.group) { if (!module.group) {
......
...@@ -4,7 +4,6 @@ import { Menu, Breadcrumb, Icon } from 'antd'; ...@@ -4,7 +4,6 @@ import { Menu, Breadcrumb, Icon } from 'antd';
import { connect } from 'dva'; import { connect } from 'dva';
import { Link } from 'dva/router'; import { Link } from 'dva/router';
import { fullPath } from '../../utils/helper'; import { fullPath } from '../../utils/helper';
import { getMenuItems } from '../../utils/navigate';
import styles from './header.less'; import styles from './header.less';
const MenuItem = Menu.Item; const MenuItem = Menu.Item;
...@@ -76,7 +75,7 @@ class HeaderPane extends React.Component { ...@@ -76,7 +75,7 @@ class HeaderPane extends React.Component {
<SubMenu title={domainTitle} key="domain"> <SubMenu title={domainTitle} key="domain">
{ {
domainList.map(dm => ( domainList.map(dm => (
<MenuItem key={dm.id}> <MenuItem key={`${dm.id}`}>
{ dm.name } { dm.name }
</MenuItem> </MenuItem>
)) ))
...@@ -93,7 +92,7 @@ HeaderPane.propTypes = { ...@@ -93,7 +92,7 @@ HeaderPane.propTypes = {
user: PropTypes.string, user: PropTypes.string,
domain: PropTypes.string, domain: PropTypes.string,
domainList: PropTypes.arrayOf(PropTypes.shape({ domainList: PropTypes.arrayOf(PropTypes.shape({
id: PropTypes.string, id: PropTypes.number,
name: PropTypes.string, name: PropTypes.string,
})), })),
}; };
......
import { mapKeys, toPairs, isUndefined, isString, curry } from 'lodash'; import { mapKeys, toPairs, isUndefined, isString, partial } from 'lodash';
import request, { normParams } from '../utils/request'; import request, { normParams } from '../utils/request';
import { split } from '../utils/filter'; import { split } from '../utils/filter';
...@@ -14,15 +14,15 @@ export const datasourceApi = (coordinate) => { ...@@ -14,15 +14,15 @@ export const datasourceApi = (coordinate) => {
} : (coordinate || {}); } : (coordinate || {});
if (containerType === 'global') { if (containerType === 'global') {
return { return {
query: curry(calcGlobalDatasource)(datasourceName), query: partial(calcGlobalDatasource, datasourceName),
count: curry(countGlobalDatasource)(datasourceName), count: partial(countGlobalDatasource, datasourceName),
meta: curry(getGlobalDatasourceMeta)(datasourceName), meta: partial(getGlobalDatasourceMeta, datasourceName),
}; };
} else if (containerType === 'module') { } else if (containerType === 'module') {
return { return {
query: curry(calcModuleDatasource)(containerName, datasourceName), query: partial(calcModuleDatasource, containerName, datasourceName),
count: curry(countModuleDatasource)(containerName, datasourceName), count: partial(countModuleDatasource, containerName, datasourceName),
meta: curry(getModuleDatasourceMeta)(containerName, datasourceName), meta: partial(getModuleDatasourceMeta, containerName, datasourceName),
}; };
} else { } else {
throw new Error(`Unsupported containerType: ${containerType}`); throw new Error(`Unsupported containerType: ${containerType}`);
...@@ -34,7 +34,7 @@ const makeQueryParams = ({ pst, psz, filters = [], params = {} }) => { ...@@ -34,7 +34,7 @@ const makeQueryParams = ({ pst, psz, filters = [], params = {} }) => {
...toPairs({ pst, psz }), ...toPairs({ pst, psz }),
...parseFilters(filters), ...parseFilters(filters),
...normParams(mapKeys(params, (v, k) => `p-${k}`)), ...normParams(mapKeys(params, (v, k) => `p-${k}`)),
].filter(isUndefined); ].filter(v => v && !isUndefined((v[1])));
}; };
export async function calcGlobalDatasource(name, { pst, psz, filters = [], params = {} }) { export async function calcGlobalDatasource(name, { pst, psz, filters = [], params = {} }) {
......
export const makeCancelable = (promise, silence = true) => {
let hasCanceled = false;
const canceledError = { isCanceled: true };
const wrappedPromise = new Promise((resolve, reject) => {
promise.then(
val => (hasCanceled ? reject(canceledError) : resolve(val)),
error => (hasCanceled ? reject(canceledError) : reject(error)),
);
});
return {
run: cb => cb(wrappedPromise).catch((err) => {
if (silence && err !== canceledError) {
throw err;
}
}),
cancel() {
hasCanceled = true;
},
};
};
...@@ -6,7 +6,7 @@ import { cookie } from '../utils/config'; ...@@ -6,7 +6,7 @@ import { cookie } from '../utils/config';
import { errors } from '../utils/error'; import { errors } from '../utils/error';
// eslint-disable-next-line max-len // eslint-disable-next-line max-len
function parseObject(response, { num2str = true, bool2str = true, nul2str = false, ud2str = false, nil2str = false } = {}) { function parseObject(response, { num2str = false, bool2str = false, nul2str = false, ud2str = false, nil2str = false } = {}) {
if (response.status === 204) { // no-content if (response.status === 204) { // no-content
return null; return null;
} else { } else {
......
import React from 'react'; import React from 'react';
import { partial } from 'lodash';
import { storiesOf } from '@storybook/react'; import { storiesOf } from '@storybook/react';
import dva from 'dva'; import dva from 'dva';
import createLoading from 'dva-loading'; import createLoading from 'dva-loading';
import DsTable from '../src/components/table/dstable'; import DsTable from '../src/components/table/dstable';
import { makeCancelable } from '../src/utils/promise';
import { login } from '../src/services/login'; import { login } from '../src/services/login';
import { switchDomain } from '../src/services/domain'; import { switchDomain } from '../src/services/domain';
import { allModuleInfos, getModuleConfigure } from '../src/services/modules';
import { setCookie, setLocalStorge } from '../src/utils/helper'; import { setCookie, setLocalStorge } from '../src/utils/helper';
import { cookie, storage } from '../src/utils/config'; import { cookie, storage } from '../src/utils/config';
...@@ -19,19 +19,9 @@ const loginIt = async (userName, password, domainId) => { ...@@ -19,19 +19,9 @@ const loginIt = async (userName, password, domainId) => {
setCookie(cookie.user, userId); setCookie(cookie.user, userId);
setLocalStorge(storage.userName, userName); setLocalStorge(storage.userName, userName);
await switchDomain(domainId); await switchDomain(domainId);
const moduleInfos = await allModuleInfos();
console.log(moduleInfos);
if (moduleInfos.length > 0) {
const module = await getModuleConfigure(moduleInfos[0].name);
console.log(module);
}
}; };
loginIt('cxj', '111111', 5).catch(err => console.log(err)); const wrap = () => Comp => (props) => {
const Wrapper = () => Comp => (props) => {
const app = dva({}); const app = dva({});
app.use(createLoading({ app.use(createLoading({
effects: true, effects: true,
...@@ -41,8 +31,50 @@ const Wrapper = () => Comp => (props) => { ...@@ -41,8 +31,50 @@ const Wrapper = () => Comp => (props) => {
return app.start()(); return app.start()();
}; };
const lazy = action => (Comp) => {
class Lazy extends React.Component {
constructor(props, context) {
super(props, context);
this.state = {
loading: true,
};
}
componentDidMount() {
this.action = makeCancelable(action());
this.action.run(promise => promise.then(() => {
this.setState({
loading: false,
});
}));
}
componentWillUnmount() {
this.action.cancel();
}
render() {
if (this.state.loading) {
return <div>加载中...</div>;
} else {
const { children, ...rest } = this.props;
return (
<Comp {...rest}>
{ children }
</Comp>
);
}
}
}
return Lazy;
};
storiesOf('a', module) storiesOf('a', module)
.add('1', () => { .add('1', () => {
const Comp = Wrapper()(DsTable); const Comp = lazy(partial(loginIt, 'cxj', '111111', 5))(wrap()(DsTable));
return <Comp />; const coordinate = {
containerType: 'module',
containerName: 'query-transfer-order',
datasourceName: 'QueryLeftHousesTranfersTable',
};
return <Comp coordinate={coordinate} />;
}); });
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论