Просмотр исходного кода

用户管理界面table样式自适应调整,添加pagesize自适应逻辑

zhuth 7 лет назад
Родитель
Сommit
47940958ad

+ 28 - 2
src/components/admin/userGroupManagement.jsx

@@ -15,13 +15,30 @@ class UserGroupManagement extends React.Component {
     constructor(props) {
         super(props);
         this.state = {
+            pageSize: 10,
+            tableBodyHeight: 0,
             visibleAddMemberBox: false
         }
     }
 
     componentDidMount() {
         const { dispatch } = this.props;
-        dispatch({ type: 'userGroup/fetchList' });
+        dispatch({ type: 'userGroup/fetchList', autoSelect: true });
+        this.tableSize();
+        window.addEventListener('resize', this.tableSize);
+    }
+
+    componentWillUnmount() {
+        window.removeEventListener('resize', this.tableSize);
+    }
+
+    tableSize = () => {
+        const tableEl = document.getElementsByClassName('member-table')[0];
+        const tableScrollEl = tableEl.getElementsByClassName('ant-table-scroll')[0];
+        this.setState({
+            tableBodyHeight: tableScrollEl.offsetHeight - 38,
+            pageSize: Math.ceil((tableScrollEl.offsetHeight - 38) / 38)
+        });
     }
 
     onSort(list) {
@@ -52,6 +69,7 @@ class UserGroupManagement extends React.Component {
     render() {
         const { userGroup, dispatch } = this.props;
         const { selectedGroup } = userGroup;
+        const { tableBodyHeight, pageSize } = this.state;
 
         const reg = new RegExp('([+ \\- & | ! ( ) { } \\[ \\] ^ \" ~ * ? : ( ) \/])', 'g'); // 需要转义的字符
         let filterLabel = (userGroup.filterLabel || '').replace(new RegExp('(\\\\)', 'g'), '\\$1').replace(reg, '\\$1'); // 添加转义符号
@@ -132,9 +150,17 @@ class UserGroupManagement extends React.Component {
                     </div>
                     <Table
                         className='member-table'
+                        size='small'
+                        scroll={{
+                            x: columns ? columns.length * 200 : 0,
+                            y: tableBodyHeight,
+                        }}
+                        pagination={{
+                            pageSize: pageSize,
+                            hideOnSinglePage: true
+                        }}
                         columns={columns}
                         dataSource={selectedGroup ? (selectedGroup.member.map((d, i) => ({...d, key: i})) || []) : []}
-                        size='small'
                     />
                     <div className='addbtn-area'>
                         {selectedGroup && <Button className='add-btn' onClick={() => {

+ 12 - 0
src/components/admin/userGroupManagement.less

@@ -3,7 +3,9 @@
     background: white;
     padding: 5px;
     border: 1px solid #e8e8e8;
+    flex-direction: row;
     .ant-layout-sider {
+        height: 100%;
         background: white;
         .ant-layout-sider-children {
             height: 100%;
@@ -44,6 +46,16 @@
                     padding-bottom: 6px;
                     .ant-table {
                         height: 100%;
+                        .ant-table-content {
+                            height: 100%;
+                            .ant-table-scroll {
+                                height: 100%;
+                                .ant-table-body {
+                                    height: 100%;
+                                    overflow-x: hidden !important;
+                                }
+                            }
+                        }
                     }
                     .ant-pagination {
                         margin: 9px 0;

+ 30 - 2
src/components/admin/userManagement.jsx

@@ -9,16 +9,34 @@ class UserManagement extends React.Component {
     constructor(props) {
         super(props);
         this.state = {
+            pageSize: 10,
+            tableBodyHeight: 0,
         }
     }
 
     componentDidMount() {
         const { dispatch } = this.props;
         dispatch({ type: 'user/fetchList' });
+        this.tableSize();
+        window.addEventListener('resize', this.tableSize);
+    }
+
+    componentWillUnmount() {
+        window.removeEventListener('resize', this.tableSize);
+    }
+
+    tableSize = () => {
+        const tableEl = document.getElementsByClassName('usermanagement-table')[0];
+        const tableScrollEl = tableEl.getElementsByClassName('ant-table-scroll')[0];
+        this.setState({
+            tableBodyHeight: tableScrollEl.offsetHeight - 38,
+            pageSize: Math.ceil((tableScrollEl.offsetHeight - 38) / 38)
+        });
     }
 
     render() {
         const { user, dispatch } = this.props;
+        const { tableBodyHeight, pageSize } = this.state;
 
         const moreOperatingMenu = (
             <Menu className='operationmenu' visible={true}>
@@ -87,13 +105,23 @@ class UserManagement extends React.Component {
                         </Row>
                     }>
                         <Table
-                            className='usermanagement-table usermanagement-table'
+                            className='usermanagement-table'
                             columns={columns}
                             dataSource={user.list.filter(l => {
                                 let reg = new RegExp('(' + filterLabel + '){1}', 'ig');
                                 return (l.fullName || '').search(reg) !== -1;
-                            })}
+                            }).map((d, i) => ({
+                                ...d, key: i
+                            }))}
                             size='small'
+                            scroll={{
+                                x: columns ? columns.length * 200 : 0,
+                                y: tableBodyHeight,
+                            }}
+                            pagination={{
+                                pageSize: pageSize,
+                                hideOnSinglePage: true
+                            }}
                             onRow={(record) => {
                                 return {
                                     onClick: () => {

+ 48 - 63
src/components/admin/userManagement.less

@@ -1,74 +1,59 @@
 .usermanagement-view {
-    .usermanagement-body {
-        padding: 0;
-        .ant-card-head {
-            padding: 0 10px;
-            .usermanagement-tools {
-                .anticon-bars {
-                    cursor: pointer;
-                    line-height: 1.6;
-                    font-size: 20px;
-                    margin-right: 6px;
-                }
-                .group {
-                    line-height: 2.1;
-                    .ant-breadcrumb-link {
-                        .ant-tag {
-                            margin: 0;
+    height: 100%;
+    .ant-layout-content {
+        height: 100%;
+        .usermanagement-body {
+            padding: 0;
+            height: 100%;
+            padding-top: 65px;
+            .ant-card-head {
+                margin-top: -65px;
+                padding: 0 10px;
+                .usermanagement-tools {
+                    .anticon-bars {
+                        cursor: pointer;
+                        line-height: 1.6;
+                        font-size: 20px;
+                        margin-right: 6px;
+                    }
+                    .group {
+                        line-height: 2.1;
+                        .ant-breadcrumb-link {
+                            .ant-tag {
+                                margin: 0;
+                            }
                         }
                     }
-                }
-                .search {
-                    display: flex;
-                    > div:first-child {
-                        margin-right: 5px;
+                    .search {
+                        display: flex;
+                        > div:first-child {
+                            margin-right: 5px;
+                        }
                     }
                 }
             }
-        }
-    }
-    .ant-card-body {
-        padding: 0;
-        .usermanagement-table{
-            .ant-table {
-                .ant-table-body {
-                    margin-top: 17px;
-                    overflow-y: auto !important;
-                    table {
-                        padding: 0;
-                        .ant-table-row {
-                            td {
-                                padding: 8px;
-                                .usermanagement-name {
-                                    display: flex;
-                                    .usermanagement-type {
-                                        width: 20px;
-                                        height: 20px;
-                                        background-size: cover;
-                                        background-repeat: no-repeat;
-                                        background-image: url('https://test-feapp.oss-cn-beijing.aliyuncs.com/feapp/s70f_180613_fix_a_t/images/trdservices/44_2.png');
-                                    }
-                                    .type-oracle {
-                                        background-position: 0 -731px;
+            .ant-card-body {
+                padding: 0;
+                height: 100%;
+                .usermanagement-table {
+                    height: 100%;
+                    .ant-spin-nested-loading {
+                        height: 100%;
+                        .ant-spin-container {
+                            height: 100%;
+                            padding-bottom: 50px;
+                            .ant-table {
+                                height: 100%;
+                                .ant-table-content {
+                                    height: 100%;
+                                    .ant-table-scroll {
+                                        height: 100%;
+                                        .ant-table-body {
+                                            height: 100%;
+                                            overflow-x: hidden !important;
+                                        }
                                     }
                                 }
-                                .usermanagement-tag {
-                                    margin: 2px;
-                                    cursor: default;
-                                }
-                                .ant-dropdown-trigger {
-                                    font-size: 18px;
-                                    cursor: pointer;
-                                }
-                            }
-                            .action-col {
-                                display: flex;
-                                .operation {
-                                    cursor: pointer;
-                                }
-                                .operation:hover {
-                                    color: #40a9ff;
-                                }
                             }
                         }
                     }

+ 0 - 2
src/components/chart/list.jsx

@@ -69,7 +69,6 @@ class ChartList extends React.Component {
 
         const reg = new RegExp('([+ \\- & | ! ( ) { } \\[ \\] ^ \" ~ * ? : ( ) \/])', 'g'); // 需要转义的字符
         let filterLabel = chart.filterLabel.replace(new RegExp('(\\\\)', 'g'), '\\$1').replace(reg, '\\$1'); // 添加转义符号
-        console.log(selectedRecord, currentUser);
         const operationMenu = (
             <Menu className='menu-operation'>
                 <Menu.Item>
@@ -359,7 +358,6 @@ class ChartList extends React.Component {
         const dragCode = info.dragNode.props.eventKey;
         const dropPos = info.node.props.pos.split('-');
         const dropPosition = info.dropPosition - Number(dropPos[dropPos.length - 1]); // -1/0/1 -> 兄/子/弟
-        console.log(dragCode, dropCode, dropPosition);
         dispatch({ type: 'chart/remoteMoveGroup', dragCode, dropCode, dropPosition });
     }
 

+ 2 - 1
src/components/common/login/login.jsx

@@ -1,6 +1,6 @@
 import React from 'react'
 import Login from 'ant-design-pro/lib/Login'
-import { Alert, Checkbox, Icon, message } from 'antd'
+import { Alert, Checkbox, Icon } from 'antd'
 import { Link, Redirect } from 'dva/router'
 import { connect } from 'dva'
 import * as service from '../../../services/index'
@@ -10,6 +10,7 @@ import './login.less'
 const { UserName, Password, Submit } = Login;
 
 function authenticate(token, expireTime, user, autoLogin, cb ) {
+    window.localStorage.setItem("loginTime", new Date().getTime());
     window.localStorage.setItem("token", token);
     window.localStorage.setItem("expireTime", expireTime);
 

+ 5 - 3
src/components/common/rootLayout.jsx

@@ -20,11 +20,13 @@ class RootLayout extends React.Component {
     render() {
         const { location, isAuthenticated, children } = this.props;
         const { goLogin } = this.state;
+        const visibleLoginConfimBox = location !=='/login' && !isAuthenticated;
+
         return (<div className='root-layout'>
             { children }
-            <Modal
+            {visibleLoginConfimBox && <Modal
                 className='confirm-box'
-                visible={location !=='/login' && !isAuthenticated}
+                visible={visibleLoginConfimBox}
                 footer={null}
                 closable={false}
                 centered={true}
@@ -37,7 +39,7 @@ class RootLayout extends React.Component {
                         <Button type="primary" onClick={this.setGoLogin}>重新登录</Button>
                     </div>
                 </div>
-            </Modal>
+            </Modal>}
             {goLogin && <Redirect
                 to={{
                     pathname: "/login",

+ 3 - 0
src/components/common/rootLayout.less

@@ -15,6 +15,9 @@
                     line-height: 50px;
                     font-size: 32px;
                     color: #FF4D4F;
+                    svg {
+                        margin-top: 10px;
+                    }
                 }
             }
             .confirm-label {

+ 4 - 4
src/components/dashboardDesigner/chooseChartBox.jsx

@@ -2,7 +2,7 @@ import React from 'react'
 import '../../models/dashboardDesigner'
 import { Modal, Radio, Row, Col, Table, Input, message } from 'antd'
 import { connect } from 'dva'
-import { dateFormat } from '../../utils/baseUtils'
+import moment from 'moment'
 import 'braft-editor/dist/braft.css'
 import './chooseChartBox.less'
 const { Search } = Input
@@ -109,15 +109,15 @@ class ChooseChartBox extends React.Component {
             }
         }, {
             title: '创建人',
-            dataIndex: 'creator',
-            key: 'creator',
+            dataIndex: 'creatorName',
+            key: 'creatorName',
             width: 100
         }, {
             title: '创建时间',
             dataIndex: 'createTime',
             key: 'createTime',
             width: 120,
-            render: (text) => dateFormat(new Date(text), 'yyyy-MM-dd')
+            render: (text) => moment(text).format('YYYY-MM-DD')
         }, {
             title: '说明',
             dataIndex: 'description',

+ 1 - 9
src/components/dashboardDesigner/configForm.jsx

@@ -1,9 +1,7 @@
 import React from 'react'
 import { connect } from 'dva'
 import { Form, Input, Divider, Button, Icon, Collapse, Spin } from 'antd'
-const { TextArea } = Input;
 
-// const ConfigForm = ({ dashboardDesigner, dispatch }) => {
 class ConfigForm extends React.Component {
 
     constructor(props) {
@@ -31,15 +29,9 @@ class ConfigForm extends React.Component {
     render() {
         const { dashboardDesigner, dispatch } = this.props;
         const { activeKey, editing, selectedDataSource, selectedColumn } = this.state;
-        const { relationColumns, dataSources, description, columnFetching } = dashboardDesigner;
+        const { relationColumns, dataSources, columnFetching } = dashboardDesigner;
 
         return <Form className='config-form'>
-            <Divider>基础设置</Divider>
-            <Form.Item label='备注'>
-                <TextArea value={description} autosize={{ minRows: 2, maxRows: 6 }} onChange={(e) => {
-                    dispatch({ type: 'dashboardDesigner/setField', name: 'description', value: e.target.value });
-                }}/>
-            </Form.Item>
             <Divider>自定义过滤字段</Divider>
             <div className='filtercolumns'>
                 <Collapse key='filtercolumnscollapse' activeKey={activeKey} onChange={k => {

+ 1 - 1
src/components/dashboardDesigner/content.jsx

@@ -202,7 +202,7 @@ class DashboardDesignerContent extends React.Component {
                             dispatch({ type: 'dashboardDesigner/addRichText' });
                         }}/>
                     </Tooltip>
-                    <ChooseChartBox visibleBox={visibleChooseChartBox} hideBox={this.hideBox} />
+                    {visibleChooseChartBox && <ChooseChartBox visibleBox={visibleChooseChartBox} hideBox={this.hideBox} />}
                 </div>}
             </Header>
             <Content className='dashboard-content'>

+ 0 - 1
src/components/dashboardDesigner/layout.jsx

@@ -19,7 +19,6 @@ class DashboardDesigner extends React.Component {
     componentDidMount() {
         const { dispatch } = this.props;
         const { code } = this.props.match.params;
-        dispatch({ type: 'chart/fetchList' });
         if (code !== 'create') {
             dispatch({ type: 'dashboard/remoteDetail', code: code });
         }

+ 3 - 8
src/components/dashboardDesigner/viewLayout.jsx

@@ -1,7 +1,7 @@
 import React from "react"
 import "./viewLayout.less"
 import ReactGridLayout from 'react-grid-layout'
-import { Icon, Modal, Tooltip } from 'antd'
+import { Icon, Modal } from 'antd'
 import { connect } from 'dva'
 import ChartView from './chartView'
 
@@ -34,19 +34,14 @@ class ViewLayout extends React.PureComponent {
         const { dispatch, main, dashboardDesigner } = this.props;
         const { currentUser } = main;
         const { editMode } = dashboardDesigner;
-        const { code, name, viewType, layout, chartCode, filters } = item;
-
-        let usingFilters = filters ? ( filters.length > 0 ? ( filters.filter(f => f.using === true) ) : [] ) : [];
+        const { code, name, viewType, layout, chartCode } = item;
 
         return (
             <div className={`chartview${ isPreview ? ' chartview-preview' : (editMode ? ' chartview-edit' : '')}`} key={code} data-grid={layout}>
                 <div className='chartview-toolbar mover'>
                     <div className='chart-title'><span>{name}</span></div>
                     <div className='chart-tools'>
-                        {viewType !== 'richText' && usingFilters.length > 0 && <Tooltip title={'默认过滤条件: 【' + usingFilters.map((f, i) => f.filterLabel).join(',') + '】'}>
-                            <Icon className='visible-icon' type="info-circle" theme="outlined" />
-                        </Tooltip>}
-                        {<Icon type="reload" theme="outlined" onClick={() => {
+                        {viewType !== 'richText' && <Icon type="reload" theme="outlined" onClick={() => {
                             dispatch({ type: 'dashboardDesigner/fetchChartData', item, mandatory: true });
                         }}/>}
                         {!isPreview && viewType !== 'richText' && <Icon type="arrows-alt" onClick={() => this.showPreviewBox(item)}/>}

+ 1 - 0
src/custom.less

@@ -7,6 +7,7 @@
 //     }
 // }
 
+// 菜单项间隔去除margin
 .ant-dropdown-menu-item-divider, .ant-dropdown-menu-submenu-title-divider {
     margin: 0;
 }

+ 2 - 2
src/models/chart.js

@@ -143,11 +143,11 @@ export default {
                         return {
                             code:  d.chartId+'',
                             name: d.chartName,
-                            dataSourceCode: d.dataId,
+                            dataSourceCode: d.dataId + '',
                             dataSourceName: d.dataName,
                             access: d.authority === '1',
                             type: getViewType(d.chartType),
-                            creatorCode: d.createId+'',
+                            creatorCode: d.createId + '',
                             creatorName: d.createBy,
                             createTime: d.createDate,
                             description: d.describes || '',

+ 2 - 5
src/models/dashboardDesigner.js

@@ -309,12 +309,10 @@ export default {
             
 
             try {
-                yield put({ type: 'silentSetField', field: 'loading', value: true });
                 const res = yield call(service.fetch, {
                     url: URLS.DATASOURCE_QUERY_DATACOLUMNS,
                     body: body
                 });
-                yield put({ type: 'silentSetField', field: 'loading', value: false });
                 console.log('获得列数据', body, res);
                 if(!res.err && res.data.code > 0) {
                     let resData = res.data.data;
@@ -380,11 +378,11 @@ export default {
             }
 
             try {
-                yield put({ type: 'dashboardDesigner/silentSetField', name: 'loading', value: true });
                 yield put({ type: 'setItemFetching', code: chartCode, fetching: true });
                 const res = yield call(service.fetch, {
                     url: URLS.CHART_OPTION,
-                    body
+                    body,
+                    timeout: 30000
                 });
                 console.log('看板请求图表展示数据', body, res);
                 if(!res.err && res.data.code > 0) {
@@ -402,7 +400,6 @@ export default {
                 yield put({ type: 'setItemChartOption', code: chartCode, chartOption: {} });
                 message.error('请求图表展示数据失败: ' + e);
             }finally {
-                yield put({ type: 'dashboardDesigner/silentSetField', name: 'loading', value: false });
                 yield put({ type: 'setItemFetching', code: chartCode, fetching: false });
                 // 主动触发一次window的resize事件
                 window.setTimeout(() => {

+ 11 - 5
src/models/main.js

@@ -3,20 +3,18 @@ import { message } from 'antd'
 
 const code = window.localStorage.getItem('usercode');
 const account = window.localStorage.getItem('account');
-// const password = window.localStorage.getItem('password');
+const password = window.localStorage.getItem('password');
 const name = window.localStorage.getItem('username');
 const role = window.localStorage.getItem('userrole');
 
-// const lastPage = window.localStorage.getItem('lastpage');
-// window.localStorage.removeItem('lastpage');
-
 export default {
     namespace: 'main',
     state: {
+        authenticated: false,
         currentUser: {
             code,
             account,
-            // password,
+            password,
             name,
             role,
         },
@@ -35,6 +33,10 @@ export default {
                 name: user.name,
                 role: user.role
             } };
+        },
+        setAuthenticated(state, action) {
+            const { authenticated } = action;
+            return { ...state, authenticated };
         }
     },
     effects: {
@@ -58,6 +60,10 @@ export default {
         },
         *logout( action, { put, call, select }) {
             try {
+                window.localStorage.removeItem("username");
+                window.localStorage.removeItem("userrole");
+                window.localStorage.removeItem("usercode");
+                window.localStorage.removeItem("loginTime");
                 window.localStorage.removeItem("token");
                 window.localStorage.removeItem("expireTime");
                 yield put({ type: 'dataConnect/list', list: [] });

+ 7 - 2
src/models/userGroup.js

@@ -89,8 +89,9 @@ export default {
     effects: {
         *fetchList(action, { put, call, select }) {
             const userGroup = yield select(state => state.present.userGroup);
+            const { mandatory, autoSelect } = action;
             try {
-                if(!action.mandatory && userGroup.list.length > 0) {
+                if(!mandatory && userGroup.list.length > 0) {
                     return;
                 }
                 const res = yield call(service.fetch, {
@@ -106,6 +107,7 @@ export default {
                         member: []
                     }));
                     yield put({ type: 'list', list: list.sort((a, b) => a.createTime - b.createTime) });
+                    yield autoSelect && put({ type: 'chageSelectedGroup', group: list[0] });
                 }else {
                     console.log(res.err || res.data.msg);
                     message.error('请求用户组列表失败: ' + (res.err || res.data.msg));
@@ -129,7 +131,7 @@ export default {
                 });
                 if(!res.err && res.data.code > 0) {
                     yield put({ type: 'add', group: {
-                        code: res.data.data,
+                        code: res.data.data+'',
                         name: newOne.name,
                         description: newOne.description,
                         member: []
@@ -181,6 +183,9 @@ export default {
                 console.log('删除用户组', [group.code], res);
                 if(!res.err && res.data.code > 0) {
                     yield put({ type: 'delete', group });
+                    const userGroup = yield select(state => state.present.userGroup);
+                    const { list } = userGroup;
+                    yield put({ type: 'chageSelectedGroup', group: list[0] });
                     message.success('删除成功');
                 }else {
                     console.log([group.code], (res.err || res.data.msg));