Browse Source

登录页logo/分发对象box显示已选中项、样式优化/个人信息页面设计/model originData reset应用

zhuth 7 years ago
parent
commit
dbfb535b89

BIN
public/images/uas.png


+ 7 - 1
src/components/chart/distributeBox.jsx

@@ -272,7 +272,13 @@ class DistributeBox extends React.Component {
                             />
                         </Card>
                         <FilterBox key={Math.random()} type='chart' code={chartCode} columns={columnData} filterData={currentPolicy ? currentPolicy.filters : []} visibleFilterBox={visiblePolicyRuleBox} hideFilterBox={this.hidePolicyRuleBox} createFilters={this.createFilters} />
-                        <AccessObjectBox key={Math.random()} visibleBox={visibleAccessObjectBox} hideBox={this.hideAccessObjectBox} okHandler={this.setAccessObject} group={group} geren={geren} />
+                        {visibleAccessObjectBox && <AccessObjectBox
+                            visibleBox={visibleAccessObjectBox}
+                            hideBox={this.hideAccessObjectBox}
+                            okHandler={this.setAccessObject}
+                            defaultSelectedGroups={group}
+                            defaultSelectedUsers={geren}
+                        />}
                     </Content>
                 </Layout>
             </Modal>

+ 1 - 1
src/components/chart/list.jsx

@@ -76,7 +76,7 @@ class ChartList extends React.Component {
         let filterLabel = chart.filterLabel.replace(new RegExp('(\\\\)', 'g'), '\\$1').replace(reg, '\\$1'); // 添加转义符号
         const operationMenu = (
             <Menu className='menu-operation'>
-                <Menu.Item>
+                <Menu.Item disabled>
                     <Icon type="link" />分享
                 </Menu.Item>
                 {selectedRecord && currentUser.code === selectedRecord.creatorCode && <Menu.Item onClick={() => {

+ 96 - 13
src/components/common/accessObjectBox/accessObjectBox.jsx

@@ -11,17 +11,43 @@ class AccessObjectBox extends React.Component {
     constructor(props) {
         super(props);
         this.state = {
-            selectedGroups: props.group || [],
-            selectedUsers: props.geren || []
+            selectedGroups: props.defaultSelectedGroups && props.defaultSelectedGroups.length >= 0 ? props.defaultSelectedGroups : [],
+            selectedUsers: props.defaultSelectedUsers && props.defaultSelectedUsers.length >= 0 ? props.defaultSelectedUsers : [],
+            columnWidth: 100,
+            boxHeight: 0,
+            tableHeaderHeight: 60,
         }
     }
 
     componentDidMount() {
         const { dispatch } = this.props;
-        dispatch({ type: 'userGroup/fetchList' });
-        dispatch({ type: 'user/fetchList' });
+        new Promise(() => {
+            dispatch({ type: 'userGroup/fetchList' });
+            dispatch({ type: 'user/fetchList' }).then(() => {
+                window.setTimeout(() => {
+                    var e = document.createEvent("Event");
+                    e.initEvent("resize", true, true);
+                    window.dispatchEvent(e);
+                }, 20);
+            });
+        })
+        window.addEventListener('resize', this.onWindowResize);
     }
 
+    componentWillUnmount() {
+        window.removeEventListener('resize', this.onWindowResize);
+    }
+
+    onWindowResize = () => {
+        const boxEl = document.getElementsByClassName('accessobject-box')[0].getElementsByClassName('ant-modal-content')[0];
+        const tableHeaderEl = boxEl.getElementsByTagName('thead')[0];
+
+        this.setState({
+            boxHeight: boxEl.offsetHeight,
+            tableHeaderHeight: tableHeaderEl.offsetHeight + 2, // 表头高度(含边框)
+        });
+    }
+    
     getAccessObject = () => {
         const { okHandler, hideBox } = this.props;
         const { selectedGroups, selectedUsers } = this.state;
@@ -30,18 +56,23 @@ class AccessObjectBox extends React.Component {
     }
 
     render() {
-        const { visibleBox, hideBox, userGroup, user } = this.props;
-        const { selectedGroups, selectedUsers } = this.state;
+        const { visibleBox, hideBox, userGroup, user, defaultSelectedGroups: _defaultSelectedGroups, defaultSelectedUsers: _defaultSelectedUsers } = this.props;
+        const { selectedGroups, selectedUsers, columnWidth, boxHeight } = this.state;
+
+        const defaultSelectedGroups = _defaultSelectedGroups && _defaultSelectedGroups.length >= 0 ? _defaultSelectedGroups : [];
+        const defaultSelectedUsers = _defaultSelectedUsers && _defaultSelectedUsers.length >= 0 ? _defaultSelectedUsers : [];
 
         const reg = new RegExp('([+ \\- & | ! ( ) { } \\[ \\] ^ \" ~ * ? : ( ) \/])', 'g'); // 需要转义的字符
         let filterLabel = (this.state.filterLabel || '').replace(new RegExp('(\\\\)', 'g'), '\\$1').replace(reg, '\\$1'); // 添加转义符号
 
+        const tableBodyHeight = boxHeight - 50 - 45 - 37 - 53 - 2;
+
         const userGroupColumns = [{
             key: 'check',
             title: '选择',
             render: (v, r, i) => <Checkbox
                 dataKey={r.key}
-                checked={!!selectedGroups.find(g => g.code === r.code)}
+                checked={!!defaultSelectedGroups.find(g => g.code === r.code) || !!selectedGroups.find(g => g.code === r.code)}
                 onChange={(e) => {
                     const target = e.target;
                     const checked = target.checked;
@@ -83,7 +114,7 @@ class AccessObjectBox extends React.Component {
             title: '选择',
             render: (v, r, i) => <Checkbox
                 dataKey={r.key}
-                checked={!!selectedUsers.find(g => g.code === r.code)}
+                checked={!!defaultSelectedUsers.find(g => g.code === r.code) || !!selectedUsers.find(g => g.code === r.code)}
                 onChange={(e) => {
                     const target = e.target;
                     const checked = target.checked;
@@ -124,8 +155,8 @@ class AccessObjectBox extends React.Component {
         return (
             <Modal
                 className='accessobject-box'
-                height='80%'
                 width='60%'
+                height='80%'
                 title={
                     <Row>
                         <Col span={14}>选择用户组或用户</Col>
@@ -152,9 +183,9 @@ class AccessObjectBox extends React.Component {
                 >
                     <TabPane tab="用户组" key="userGroup" >
                         <Table
-                            className='usergroup-table'
+                            className='object-table usergroup-table'
                             columns={userGroupColumns.map(c => ({
-                                ...c, width: 100
+                                ...c, width: columnWidth
                             }))}
                             dataSource={userGroup.list.filter(l => {
                                 let reg = new RegExp('(' + filterLabel + '){1}', 'ig');
@@ -164,12 +195,40 @@ class AccessObjectBox extends React.Component {
                                 key: i
                             }))}
                             size='small'
+                            pagination={false}
+                            scroll={{
+                                x: userColumns.length * columnWidth,
+                                y: tableBodyHeight
+                            }}
+                            onRow={(record) => {
+                                return {
+                                    onClick: () => {
+                                        console.log(record);
+                                        const idx = selectedGroups.findIndex(i => i.code === record.code);
+                                        if(idx === -1) {
+                                            selectedGroups.push({
+                                                code: record.code,
+                                                name: record.name,
+                                                isGroup: true
+                                            });
+                                        }else {
+                                            selectedGroups.splice(idx, 1);
+                                        }
+                                        this.setState({
+                                            selectedGroups: selectedGroups
+                                        })
+                                    }
+                                };
+                            }}
                         />
                     </TabPane>
                     <TabPane tab="用户" key="user" >
                         <Table
-                            className='user-table'
-                            columns={userColumns}
+                            className='object-table user-table'
+                            columns={userColumns.map(c => ({
+                                ...c,
+                                width: columnWidth
+                            }))}
                             dataSource={user.list.filter(l => {
                                 let reg = new RegExp('(' + filterLabel + '){1}', 'ig');
                                 return (l.fullName || '').search(reg) !== -1;
@@ -178,6 +237,30 @@ class AccessObjectBox extends React.Component {
                                 key: i
                             }))}
                             size='small'
+                            pagination={false}
+                            scroll={{
+                                x: userColumns.length * columnWidth,
+                                y: tableBodyHeight
+                            }}
+                            onRow={(record) => {
+                                return {
+                                    onClick: () => {
+                                        const idx = selectedUsers.findIndex(i => i.code === record.code);
+                                        if(idx === -1) {
+                                            selectedUsers.push({
+                                                code: record.code,
+                                                name: record.fullName,
+                                                isGroup: false
+                                            });
+                                        }else {
+                                            selectedUsers.splice(idx, 1);
+                                        }
+                                        this.setState({
+                                            selectedUsers: selectedUsers
+                                        })
+                                    }
+                                };
+                            }}
                         />
                     </TabPane>
                 </Tabs>

+ 20 - 5
src/components/common/accessObjectBox/accessObjectBox.less

@@ -1,18 +1,33 @@
 .accessobject-box {
+    top: 10%;
+    &>.ant-modal-content {
+        max-height: 100%;
+        height: 100%;
+        padding-top: 50px;
+        overflow: hidden;
+        &>.ant-modal-header {
+            margin-top: -50px;
+            height: 50px;
+            line-height: 50px;
+            padding: 12px 24px;
+        }
+    }
     .ant-modal-body {
         padding: 0;
-        max-height: 50vh;
-        overflow-y: auto;
-        .accessobject-tabs {
-            .accessobject-tabs {
+        &>.accessobject-tabs {
+            margin: 0;
+            &>.ant-tabs-bar {
                 margin: 0;
             }
         }
-        .choosechart-table {
+        .object-table {
             .ant-table-header {
                 overflow-y: hidden;
                 margin-right: 6px;
             }
+            .ant-table-body {
+                height: 999px; // 最终高度等于max-height
+            }
         }
     }
 }

+ 1 - 1
src/components/common/dataPreview/dataPreview.jsx

@@ -46,7 +46,7 @@ class DataPreview extends React.Component {
         const { loading, columns, dataSource, pageSize, total } = dataList;
         const { screenWidth, screenHeight, boxW, boxH, columnWidth, tableHeaderHeight } = this.state;
         const tableBodyWidth = screenWidth * boxW - 10 - 10 - 18;
-        const tableBodyHeight = screenHeight * boxH - 40 - 40 - tableHeaderHeight;
+        const tableBodyHeight = screenHeight * boxH - 40 - 40 - tableHeaderHeight - 2;
 
         return <Modal
             className='datapreview'

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

@@ -21,6 +21,8 @@ function authenticate(token, expireTime, user, autoLogin, cb ) {
     autoLogin ? window.localStorage.setItem("password", user.password) : window.localStorage.removeItem('password');
     window.localStorage.setItem("username", user.name);
     window.localStorage.setItem("userrole", user.role);
+    window.localStorage.setItem("department", user.department);
+    window.localStorage.setItem("job", user.job);
 
     setTimeout(cb, 100); // fake async
 }
@@ -81,7 +83,9 @@ class LoginComponent extends React.Component {
                     account: user.userName,
                     password: user.passWord,
                     name: user.name,
-                    role: user.role
+                    role: user.role || 'default',
+                    department: user.department,
+                    job: user.post,
                 };
                 dispatch({ type: 'main/setCurrentUser', user: currentUser });
                 authenticate(token, expireTime, currentUser, autoLogin, () => {
@@ -115,7 +119,10 @@ class LoginComponent extends React.Component {
             <div className='container'>
                 <div className='content'>
                     <div className='main'>
-                        <h3>登录</h3>
+                        <div className='login-header'>
+                            <img className='logo' src='../../../../public/images/uas.png' alt='UAS' style={{ height: '30px', marginTop: '3px'}}></img>
+                            <span className='text' >BI 商业智能报表</span>
+                        </div>
                         <Login
                             className='login'
                             onSubmit={this.onSubmit}

+ 14 - 0
src/components/common/login/login.less

@@ -10,6 +10,20 @@
         .main {
             width: 368px;
             margin: 0 auto;
+            .login-header {
+                height: 60px;
+                margin-bottom: 40px;
+                display: flex;
+                justify-content: center;
+                align-items: center;
+                .logo {
+                    margin-top: 3px;
+                }
+                .text {
+                    font-size: 24px;
+                    font-weight: bold;
+                }
+            }
         }
     }
 }

+ 3 - 1
src/components/common/navigator.jsx

@@ -18,7 +18,9 @@ class Navigator extends React.Component {
 
         const userMenu = currentUser.code ? (
             <Menu>
-                <Menu.Item key="0">
+                <Menu.Item key="0" onClick={() => {
+                    dispatch({ type: 'main/redirect', path: '/userinfo' });
+                }}>
                     <Icon type="info-circle-o" /><span>账号信息</span>
                 </Menu.Item>
                 {currentUser.role === 'admin' && <Menu.Item key="1" onClick={() => {

+ 1 - 1
src/components/common/navigator.less

@@ -3,7 +3,7 @@
     justify-content: space-between;
     background: white;
     height: 100%;
-    padding: 0 20px;
+    padding: 0 24px;
     .navigator-menu {
         border-bottom: none;
         .nav-page {

+ 38 - 7
src/components/dashboard/list.jsx

@@ -21,7 +21,9 @@ class DashboardList extends React.Component {
             visibleDistributeBox: false,
             visibleTransferBox: false,
             visibleGroupMenu: false, // 显示分组菜单
-            visibleDeleteBox: false
+            visibleDeleteBox: false,
+            defaultSelectedGroups: [],
+            defaultSelectedUsers: [],
         }
     }
 
@@ -45,7 +47,7 @@ class DashboardList extends React.Component {
         const pWidth = parent.offsetWidth; // 父级容器宽度
         const pPadding = 10 + 10; // 父级容器左右padding
         const cWidth = 512; // 每个卡片宽度
-        const cMargin = 5 + 5; // 每个卡片左右margin
+        const cMargin = 8 + 8; // 每个卡片左右margin
         const pTrueWidth = pWidth - pPadding; // 父容器实际可用宽度
         const cTrueWidth = cWidth + cMargin; // 卡片实际占用宽度
         const count = Math.floor(pTrueWidth/cTrueWidth); // 每行最大卡片数量
@@ -54,6 +56,33 @@ class DashboardList extends React.Component {
         cardBodyWidth > 0 ? cardBody.style.width = cardBodyWidth + 'px' : void(0);
     }
 
+    getShareList = () => {
+        new Promise((resolve, reject) => {
+            const { dispatch } = this.props;
+            const { selectedRecord } = this.state;
+            dispatch({ type: 'dashboard/shareList', code: selectedRecord.code })
+            .then(
+                (resolve) => {
+                    const resData = resolve.data.data;
+                    const { groupNames: defaultSelectedGroups, userNames: defaultSelectedUsers } = resData;
+                    this.setState({
+                        visibleDistributeBox: true,
+                        defaultSelectedGroups: defaultSelectedGroups.map(g => ({
+                            code: g.id + '',
+                            name: g.name
+                        })),
+                        defaultSelectedUsers: defaultSelectedUsers.map(u => ({
+                            code: u.id + '',
+                            name: u.name
+                        })), 
+                    });
+                }
+            ).catch(reject => {
+                console.log(reject);
+            });
+        });
+    }
+
     generateCard() {
         const { main, dashboard, dispatch } = this.props;
         const { selectedRecord } = this.state;
@@ -66,15 +95,14 @@ class DashboardList extends React.Component {
         const operationMenu = (
             <Menu className='menu-operation'>
                 <Menu.Item
+                    disabled
                     onClick={(e) => {
                     }}
                 >
                     <Icon type="delete" />分享
                 </Menu.Item>
                 { selectedRecord && currentUser.code === selectedRecord.creatorCode && <Menu.Divider />}
-                { selectedRecord && currentUser.code === selectedRecord.creatorCode && <Menu.Item onClick={() => {
-                    this.setState({visibleDistributeBox: true})
-                }}> 
+                { selectedRecord && currentUser.code === selectedRecord.creatorCode && <Menu.Item onClick={this.getShareList}> 
                     <Icon type='share-alt'/>分发
                 </Menu.Item>}
                 { selectedRecord && currentUser.code === selectedRecord.creatorCode && <Menu.Item
@@ -181,7 +209,7 @@ class DashboardList extends React.Component {
 
     render() {
         const { dispatch, dashboard } = this.props;
-        const { visibleDistributeBox, visibleTransferBox, visibleDeleteBox, selectedRecord } = this.state
+        const { visibleDistributeBox, visibleTransferBox, visibleDeleteBox, selectedRecord, defaultSelectedGroups, defaultSelectedUsers } = this.state
         return (
             <Layout className='dashboard-list'>
                 <Content>
@@ -221,7 +249,10 @@ class DashboardList extends React.Component {
                             visibleDistributeBox: false
                         })
                     }}
-                    okHandler={this.distribute} />}
+                    okHandler={this.distribute}
+                    defaultSelectedGroups={defaultSelectedGroups}
+                    defaultSelectedUsers={defaultSelectedUsers}
+                />}
                 {visibleTransferBox && <TransferBox
                     visibleBox={visibleTransferBox}
                     title='选择移交对象'

+ 1 - 1
src/components/dashboard/list.less

@@ -34,7 +34,7 @@
         .dashboard-card {
             width: 512px;
             text-align: center;
-            margin: 5px;
+            margin: 8px;
             padding: 0;
             &>.ant-card {
                 border: 2px solid #CCCCCC;

+ 0 - 19
src/components/dashboard/transferBox.jsx

@@ -1,19 +0,0 @@
-import React from 'react'
-import { Modal } from 'antd'
-
-
-class TransferBox extends React.Component {
-    render() {
-        const { visibleTransferBox, onCancel } = this.props
-        return (
-            <Modal 
-                visible={visibleTransferBox}
-                onCancel={onCancel}
-            >
-                <span>Test</span>
-            </Modal>
-        )
-    }
-}
-
-export default TransferBox

+ 2 - 1
src/components/dataSource/list.jsx

@@ -489,7 +489,8 @@ class DataSource extends React.Component {
                             }}
                             okHandler={() =>{
                                 dispatch({ type: 'dataSource/remoteDelete', code: selectedRecord.code })
-                        }} />}
+                            }} 
+                        />}
                         {visibleDataPreviewBox && <DataPreview
                             visibleBox={visibleDataPreviewBox}
                             hideBox={() => {

+ 34 - 5
src/components/dataSourceDetail/accessConfig.jsx

@@ -3,6 +3,7 @@ import { connect } from 'dva'
 import { Layout, Card, Row, Col, Table, Input, Checkbox, Button, Icon, Tag } from 'antd'
 import FilterBox from '../common/filterBox/filterBox'
 import AccessObjectBox from '../common/accessObjectBox/accessObjectBox'
+import DeleteBox from '../common/deleteBox/deleteBox'
 import moment from 'moment'
 import './accessConfig.less'
 const { Content } = Layout
@@ -19,7 +20,8 @@ class DataSourceAccessConfig extends React.Component{
             visibleAccessObjectBox: false,
             visiblePolicyRuleBox: false, // 显示过滤规则编辑窗口
             currentPolicy: {}, // 选中的策略
-            visibleFilterBox: false
+            visibleFilterBox: false,
+            visibleDeleteBox: false,
         }
     }
 
@@ -111,7 +113,7 @@ class DataSourceAccessConfig extends React.Component{
     
     render() {
         const { dataSourcePolicy, dataSourceDetail,  dispatch } = this.props;
-        const { visibleAccessObjectBox, visiblePolicyRuleBox, currentPolicy } = this.state;
+        const { visibleAccessObjectBox, visiblePolicyRuleBox, visibleDeleteBox, currentPolicy } = this.state;
         
         const polices = dataSourcePolicy.list;
         const group = currentPolicy ? (currentPolicy.targets ? currentPolicy.targets.filter(t => t.isGroup) : []) : [];
@@ -231,7 +233,9 @@ class DataSourceAccessConfig extends React.Component{
         }, {
             title: '操作',
             render: (v,r) => <div><span style={{ cursor: 'pointer' }} onClick={() => {
-                dispatch({ type: 'dataSourcePolicy/remoteDelete', code: r.code });
+                this.setState({
+                    visibleDeleteBox: true
+                });
             }}>删除</span></div>,
             width: 120
         }];
@@ -282,8 +286,33 @@ class DataSourceAccessConfig extends React.Component{
                             }}
                         />
                     </Card>
-                    <FilterBox key={Math.random()} type='dataSource' code={dataSourceDetail.code} columns={columnData} filterData={currentPolicy.filters} visibleFilterBox={visiblePolicyRuleBox} hideFilterBox={this.hidePolicyRuleBox} createFilters={this.createFilters} />
-                    <AccessObjectBox key={Math.random()} visibleBox={visibleAccessObjectBox} hideBox={this.hideAccessObjectBox} okHandler={this.setAccessObject} group={group} geren={geren} />
+                    {visiblePolicyRuleBox && <FilterBox
+                        type='dataSource'
+                        code={dataSourceDetail.code}
+                        columns={columnData}
+                        filterData={currentPolicy.filters}
+                        visibleFilterBox={visiblePolicyRuleBox}
+                        hideFilterBox={this.hidePolicyRuleBox}
+                        createFilters={this.createFilters}
+                    />}
+                    {visibleAccessObjectBox && <AccessObjectBox
+                        visibleBox={visibleAccessObjectBox}
+                        hideBox={this.hideAccessObjectBox}
+                        okHandler={this.setAccessObject}
+                        defaultSelectedGroups={group}
+                        defaultSelectedUsers={geren}
+                    />}
+                    {visibleDeleteBox && <DeleteBox
+                        visibleBox={visibleDeleteBox}
+                        hideBox={() => {
+                            this.setState({ visibleDeleteBox: false })
+                        }}
+                        text={<div><span>确定要删除策略【{currentPolicy.name}】吗?</span><br/><span style={{ color: 'red' }}>(此操作可能导致策略开放对象使用该数据源创建的图表失效!)</span></div>}
+                        okHandler={() =>{
+                            dispatch({ type: 'dataSourcePolicy/remoteDelete', code: currentPolicy.code });
+                            // dispatch({ type: 'dataSource/remoteDelete', code: selectedRecord.code })
+                        }}
+                    />}
                 </Content>
             </Layout>
         );

+ 27 - 0
src/components/user/layout.jsx

@@ -0,0 +1,27 @@
+/**
+ * 用户信息管理
+ */
+import { Tabs } from 'antd'
+import UserInfo from './userInfo'
+import Password from './password'
+import './layout.less'
+const { TabPane } = Tabs
+
+const Layout = () => {
+    return (
+        <Tabs
+            className='userinfo-tabs'
+            tabPosition='left'
+            defaultActiveKey='userinfo'
+        >
+            <TabPane tab='个人信息' key='userinfo'>
+                <UserInfo />
+            </TabPane>
+            <TabPane tab='修改密码' key='modifypassword'>
+                <Password />
+            </TabPane>
+        </Tabs>
+    )
+}
+
+export default Layout;

+ 13 - 0
src/components/user/layout.less

@@ -0,0 +1,13 @@
+.userinfo-tabs {
+    height: 100%;
+    .ant-tabs-bar {
+        margin: 0;
+    }
+    .ant-tabs-content {
+        height: 100%;
+        border: none !important;
+        .ant-tabs-tabpane {
+            height: 100%;
+        }
+    }
+}

+ 48 - 0
src/components/user/password.jsx

@@ -0,0 +1,48 @@
+/**
+ * 用户信息管理
+ */
+import { Form, Input, Button } from 'antd'
+const { Item: FormItem } = Form
+
+const UserInfo = () => {
+    const formItemLayout = {
+        labelCol: {
+            xs: { span: 24 },
+            sm: { span: 5 },
+        },
+        wrapperCol: {
+            xs: { span: 24 },
+            sm: { span: 12 },
+        },
+    };
+    return (
+        <Form>
+            <FormItem
+                {...formItemLayout}
+                label="原密码"
+            >
+                <Input id="oldPassword" type='password' />
+            </FormItem>
+            <FormItem
+                {...formItemLayout}
+                label="新密码"
+            >
+                <Input id="newPassword" type='password' />
+            </FormItem>
+            <FormItem
+                {...formItemLayout}
+                label="确认新密码"
+            >
+                <Input id="confirmPassword" type='password' />
+            </FormItem>
+            <FormItem wrapperCol={{
+            xs: { span: 24 },
+            sm: { span: 14, offset: 10 },
+          }}>
+                <Button type="primary" htmlType="submit">确认修改</Button>
+            </FormItem>
+        </Form>
+    )
+}
+
+export default UserInfo;

+ 57 - 3
src/components/user/userInfo.jsx

@@ -1,5 +1,59 @@
-const UserInfo = () => {
-    return <div cl></div>
+/**
+ * 用户信息管理
+ */
+import { Form, Avatar, Input, Select } from 'antd'
+import { connect } from 'dva'
+const { Item: FormItem } = Form
+
+const UserInfo = ({ main }) => {
+    const { name, department, job, role } = main.currentUser;
+    const formItemLayout = {
+        labelCol: {
+            xs: { span: 24 },
+            sm: { span: 5 },
+        },
+        wrapperCol: {
+            xs: { span: 24 },
+            sm: { span: 12 },
+        },
+    };
+    return (
+        <Form>
+            <FormItem
+                {...formItemLayout}
+                label="头像"
+            >
+                <Avatar size={64} icon="user" />
+            </FormItem>
+            <FormItem
+                {...formItemLayout}
+                label="用户名"
+            >
+                <Input id="userName" defaultValue={name} />
+            </FormItem>
+            <FormItem
+                {...formItemLayout}
+                label="部门"
+            >
+                <Input id="department" defaultValue={department} />
+            </FormItem>
+            <FormItem
+                {...formItemLayout}
+                label="岗位"
+            >
+                <Input id="job" defaultValue={job} />
+            </FormItem>
+            <FormItem
+                {...formItemLayout}
+                label="角色"
+            >
+                <Select defaultValue={role}>
+                    <Select.Option value='admin'>管理员</Select.Option>
+                    <Select.Option value='default'>普通用户</Select.Option>
+                </Select>
+            </FormItem>
+        </Form>
+    )
 }
 
-export default UserInfo;
+export default connect(({ present: { main } }) => ({ main }))(UserInfo);

+ 17 - 11
src/models/chart.js

@@ -6,14 +6,16 @@ import CHART_TYPE from './chartType.json'
 export default {
     namespace: 'chart',
     state: {
-        list: [],
-        filterLabel: '',
-        groupList: [],
-        currentGroup: [{
-            code: 'all',
-            label: '全部分组'
-        }],
-        groupDirty: false
+        originData: {
+            list: [],
+            filterLabel: '',
+            groupList: [],
+            currentGroup: [{
+                code: 'all',
+                label: '全部分组'
+            }],
+            groupDirty: false
+        },
     },
     reducers: {
         add(state, action) {
@@ -107,7 +109,11 @@ export default {
                 }
             }
             return Object.assign({}, state, {list: list});
-        }
+        },
+        reset(state, action) {
+            let newState = Object.assign({}, state, state.originData);
+            return Object.assign({}, newState);
+        },
     },
     effects: {
         *fetchList(action, { select, call, put }) {
@@ -740,7 +746,7 @@ export default {
     },
     subscriptions: {
         setup({ dispatch, history }) {
-            return history.listen(({ pathname, query }) => {}
-        )}
+            dispatch({ type: 'reset' });
+        }
     }
 }

+ 4 - 25
src/models/chartDesigner.js

@@ -39,6 +39,7 @@ export default {
             creatorCode: null,
             creatorName: null,
             header: { label: '无标题' },
+            columns: [],
             baseConfig: { dataSource: { code: '' }, viewType: '' },
             aggregateTableConfig: { targetColumn: {}, statistics: [], groupBy: [] },
             dataViewConfig: { viewColumns: [], sortColumn: {key: ''}, sortType: 'asc' },
@@ -47,34 +48,13 @@ export default {
             pieConfig: { xAxis: { column: {}, granularity: {} }, yAxis: { column: {}, gauge: {} } },
             scatterConfig: { xAxis: { column: {}, granularity: {} }, yAxis: { column: {}, gauge: {} }, groupBy: {key:''} },
             styleConfig: { visibleIndex: true },
+            otherConfig:{},
+            description: '',
             filters: [],
             chartOption: {},
             dirty: false,
             fetchConfig: {}
         },
-        columns: [],
-        allPermission: [
-			{ value: 'owner', name: '创建人' },
-			{ value: 'anyone', name: '所有人' }
-        ],
-        header: { label: '无标题' },
-        baseConfig: {
-            dataSource: { code: '' },
-            viewType: ''
-        },
-        aggregateTableConfig: { targetColumn: {}, statistics: [], groupBy: [] },
-        dataViewConfig: { viewColumns: [], sortColumn: {key: ''}, sortType: 'asc' },
-        barConfig: { xAxis: { column: {}, granularity: {} }, yAxis: { column: {}, gauge: {} }, groupBy: {key:''} },
-        lineConfig: { xAxis: { column: {}, granularity: {} }, yAxis: { column: {}, gauge: {} }, groupBy: {key:''} },
-        pieConfig: { xAxis: { column: {}, granularity: {} }, yAxis: { column: {}, gauge: {} } },
-        scatterConfig: { xAxis: { column: {}, granularity: {} }, yAxis: { column: {}, gauge: {} }, groupBy: {key:''} },
-        styleConfig: { visibleIndex: true },
-        otherConfig:{ },
-        description: '',
-        filters: [],
-        chartOption: {},
-        dirty: false,
-        fetchConfig: {}
     },
     reducers: {
         /**
@@ -761,8 +741,7 @@ export default {
     },
     subscriptions: {
         setup({ dispatch, history }) {
-          return history.listen(({ pathname, query }) => {
-          });
+            dispatch({ type: 'reset' });  
         },
     },
 };

+ 4 - 10
src/models/chartPolicy.js

@@ -109,13 +109,13 @@ export default {
                         enabled: d.strategies.isOpen+'' === '1',
                         name: d.strategies.name,
                         targets: d.userGroupName.map(g => ({
-                            code: g.ID+'',
+                            code: g.id+'',
                             isGroup: true,
-                            name: g.NAME
+                            name: g.name
                         })).concat(d.userName.map(u => ({
-                            code: u.ID+'',
+                            code: u.id+'',
                             isGroup: false,
-                            name: u.NAME
+                            name: u.name
                         }))),
                         filters: d.strategies.ruleStr ? JSON.parse(d.strategies.ruleStr).map(f => getModelFilter(f)) : [],
                     })) : [];
@@ -267,11 +267,5 @@ export default {
                 message.error('获得图表列数据失败: ' + e);
             }
         }
-    },
-    subscriptions: {
-        setup({ dispatch, history }) {
-            return history.listen(({ pathname, query }) => {
-            })
-        }
     }
 };

+ 33 - 14
src/models/dashboard.js

@@ -5,15 +5,20 @@ import URLS from '../constants/url'
 export default {
     namespace: 'dashboard',
     state: {
-        list: [],
-        filterLabel: '',
-        groupList: [],
-        currentGroup: [{
-            code: 'all',
-            label: '全部分组'
-        }],
-        groupDirty: false,
-        
+        originData: {
+            list: [],
+            newOne: {
+                defaultSelectedGroups: [],
+                defaultSelectedUsers: []
+            },
+            filterLabel: '',
+            groupList: [],
+            currentGroup: [{
+                code: 'all',
+                label: '全部分组'
+            }],
+            groupDirty: false,
+        }
     },
     reducers: {
         list(state, action) {
@@ -23,7 +28,11 @@ export default {
         setFilterLabel(state, action) {
             let { label } = action;
             return Object.assign({}, state, {filterLabel: label});
-        }
+        },
+        reset(state, action) {
+            let newState = Object.assign({}, state, state.originData);
+            return Object.assign({}, newState);
+        },
     },
     effects: {
         *fetchList(action, {select, call, put}) {
@@ -264,15 +273,25 @@ export default {
                 });
                 console.log('看板分发', body, res);
                 if(!res.err && res.data.code > 0) {
-                    message.success('分发成功');
+                    message.success('设置分发对象成功');
                 }else {
-                    message.error('分发失败: ' + (res.err || res.data.msg));
+                    message.error('设置分发对象失败: ' + (res.err || res.data.msg));
                 }
             }catch(e) {
                 console.log(body, e);
                 message.error('分发失败: ' + e);
             }
         },
+        *shareList(action, { put, call, select }) {
+            const { code } = action;
+            const body = code;
+            const res = yield call(service.fetch, {
+                url: URLS.DASHBOARD_SHARE_LIST,
+                body
+            });
+            console.log('请求看板分发列表', body, res);
+            return res;
+        },
         *transfer(action, { put, call, select }) {
             const { userCode, dashboardCode } = action;
             const body = {
@@ -308,7 +327,7 @@ export default {
     },
     subscriptions: {
         setup({ dispatch, history}) {
-            return history.listen(({pathname}) => {}
-        )}
+            dispatch({ type: 'reset' });
+        }
     }
 }

+ 1 - 4
src/models/dashboardDesigner.js

@@ -454,9 +454,6 @@ export default {
                 message.error('生成缩略图失败: ' + e);
             }
         }
-    },
-    subscription: {
-
-    },
+    }
 };
 

+ 12 - 7
src/models/dataConnect.js

@@ -5,10 +5,12 @@ import URLS from '../constants/url'
 export default {
     namespace: 'dataConnect',
     state: {
-        list: [],
-        newOne: {},
-        filterLabel: '',
-        validInfo: {}
+        originData: {
+            list: [],
+            newOne: {},
+            filterLabel: '',
+            validInfo: {}
+        }
     },
     reducers: {
         list(state, action) {
@@ -96,7 +98,11 @@ export default {
             let newOne = state.newOne;
             newOne.invalid = value;
             return Object.assign({}, state, {newOne});
-        }
+        },
+        reset(state, action) {
+            let newState = Object.assign({}, state, state.originData);
+            return Object.assign({}, newState);
+        },
     },
     effects: {
         *fetchList(action, { select, call, put, takeEvery, takeLatest }) {
@@ -350,8 +356,7 @@ export default {
     },
     subscriptions: {
         setup({ dispatch, history }) {
-            return history.listen(({ pathname, query }) => {
-            })
+            dispatch({ type: 'reset' });
         }
     }
 };

+ 0 - 6
src/models/dataList.js

@@ -37,10 +37,4 @@ export default {
     },
     effects: {
     },
-    subscriptions: {
-        setup({ dispatch, history }) {
-            return history.listen(({ pathname, query }) => {
-            })
-        }
-    }
 };

+ 17 - 12
src/models/dataSource.js

@@ -6,15 +6,17 @@ import moment from 'moment'
 export default {
     namespace: 'dataSource',
     state: {
-        list: [],
-        filterLabel: '',
-        invalidSQL: false,
-        groupList: [],
-        currentGroup: [{
-            code: 'all',
-            label: '全部分组'
-        }],
-        groupDirty: false
+        originData: {
+            list: [],
+            filterLabel: '',
+            invalidSQL: false,
+            groupList: [],
+            currentGroup: [{
+                code: 'all',
+                label: '全部分组'
+            }],
+            groupDirty: false
+        }
     },
     reducers: {
         list(state, action) {
@@ -110,7 +112,11 @@ export default {
                 }
             }
             return Object.assign({}, state, {list: list});
-        }
+        },
+        reset(state, action) {
+            let newState = Object.assign({}, state, state.originData);
+            return Object.assign({}, newState);
+        },
     },
     effects: {
         *fetchList(action, { select, call, put, takeEvery, takeLatest }) {
@@ -789,8 +795,7 @@ export default {
     },
     subscriptions: {
         setup({ dispatch, history }) {
-            return history.listen(({ pathname, query }) => {
-            })
+            dispatch({ type: 'reset' });
         }
     }
 };

+ 4 - 10
src/models/dataSourcePolicy.js

@@ -99,13 +99,13 @@ export default {
                         enabled: d.strategies.isOpen+'' === '1',
                         name: d.strategies.name,
                         targets: d.userGroupName.map(g => ({
-                            code: g.ID+'',
+                            code: g.id+'',
                             isGroup: true,
-                            name: g.NAME
+                            name: g.name
                         })).concat(d.userName.map(u => ({
-                            code: u.ID+'',
+                            code: u.id+'',
                             isGroup: false,
-                            name: u.NAME
+                            name: u.name
                         }))),
                         filters: d.strategies.ruleStr ? JSON.parse(d.strategies.ruleStr).map(f => getModelFilter(f)) : [],
                     })) : [];
@@ -233,11 +233,5 @@ export default {
                 message.error('设置对象失败: ' + e);
             }
         }
-    },
-    subscriptions: {
-        setup({ dispatch, history }) {
-            return history.listen(({ pathname, query }) => {
-            })
-        }
     }
 };

+ 16 - 15
src/models/main.js

@@ -10,6 +10,8 @@ const account = window.localStorage.getItem('account');
 const password = window.localStorage.getItem('password');
 const name = window.localStorage.getItem('username');
 const role = window.localStorage.getItem('userrole');
+const department = window.localStorage.getItem('department');
+const job = window.localStorage.getItem('job');
 
 export default {
     namespace: 'main',
@@ -21,6 +23,8 @@ export default {
             password,
             name,
             role,
+            department,
+            job,
         },
         currentPage: ''
     },
@@ -30,13 +34,7 @@ export default {
         },
         setCurrentUser(state, action) {
             const { user } = action;
-            return { ...state, currentUser: {
-                code: user.code,
-                account: user.account,
-                password: user.password,
-                name: user.name,
-                role: user.role
-            } };
+            return { ...state, currentUser: user };
         },
         setAuthenticated(state, action) {
             const { authenticated } = action;
@@ -67,17 +65,20 @@ export default {
                 window.localStorage.removeItem("username");
                 window.localStorage.removeItem("userrole");
                 window.localStorage.removeItem("usercode");
+                window.localStorage.removeItem("department");
+                window.localStorage.removeItem("job");
                 window.localStorage.removeItem("loginTime");
                 window.localStorage.removeItem("token");
                 window.localStorage.removeItem("expireTime");
-                yield put({ type: 'dataConnect/list', list: [] });
-                yield put({ type: 'dataSource/list', list: [] });
-                yield put({ type: 'chart/list', list: [] });
-                yield put({ type: 'dashboard/list', list: [] });
-                yield put({ type: 'user/list', list: [] });
-                yield put({ type: 'userGroup/list', list: [] });
-                yield put({ type: 'recent/listRecentChart', recentChart: [] });
-                yield put({ type: 'recent/listRecentDashboard', recentDashboard: [] });
+
+                yield put({ type: 'dataConnect/reset' });
+                yield put({ type: 'dataSource/reset' });
+                yield put({ type: 'chart/reset' });
+                yield put({ type: 'dashboard/reset' });
+                yield put({ type: 'user/reset' });
+                yield put({ type: 'userGroup/reset', list: [] });
+                yield put({ type: 'recent/reset' });
+                // yield put({ type: 'recent/listRecentDashboard', recentDashboard: [] });
             }catch(e) {
                 console.log(e);
                 message.error('注销失败: ' + e);

+ 14 - 3
src/models/recent.js

@@ -9,8 +9,10 @@ import moment from 'moment'
 export default {
     namespace: 'recent',
     state: {
-        recentChart: [],
-        recentDashboard: []
+        originData: {
+            recentChart: [],
+            recentDashboard: []
+        }
     },
     reducers: {
         listRecentChart(state, action) {
@@ -20,7 +22,11 @@ export default {
         listRecentDashboard(state, action) {
             const { recentDashboard } = action;
             return { ...state, recentDashboard };
-        }
+        },
+        reset(state, action) {
+            let newState = Object.assign({}, state, state.originData);
+            return Object.assign({}, newState);
+        },
     },
     effects: {
         *fetchRecentChart(action, { select, call, put }) {
@@ -106,5 +112,10 @@ export default {
                 message.error('添加访问记录错误: ' + e);
             }
         }
+    },
+    subscriptions: {
+        setup({ dispatch, history }) {
+            dispatch({ type: 'reset' });
+        }
     }
 };

+ 10 - 5
src/models/user.js

@@ -5,8 +5,10 @@ import URLS from '../constants/url'
 export default {
     namespace: 'user',
     state: {
-        list: [],
-        filterLabel: ''
+        originData: {
+            list: [],
+            filterLabel: ''
+        }
     },
     reducers: {
         list(state, action) {
@@ -16,7 +18,11 @@ export default {
         setFilterLabel(state, action) {
             const { label } = action;
             return { ...state, filterLabel: label}
-        }
+        },
+        reset(state, action) {
+            let newState = Object.assign({}, state, state.originData);
+            return Object.assign({}, newState);
+        },
     },
     effects: {
         *fetchList(action, { put, call, select }) {
@@ -67,8 +73,7 @@ export default {
     },
     subscriptions: {
         setup({ dispatch, history }) {
-            return history.listen(({ pathname, query }) => {
-            })
+            dispatch({ type: 'reset' });
         }
     }
 };

+ 11 - 6
src/models/userGroup.js

@@ -5,10 +5,12 @@ import URLS from '../constants/url'
 export default {
     namespace: 'userGroup',
     state: {
-        list: [],
-        selectedGroup: null,
-        filterLabel: '',
-        newOne: {}
+        originData: {
+            list: [],
+            selectedGroup: null,
+            filterLabel: '',
+            newOne: {}
+        }
     },
     reducers: {
         list(state, action) {
@@ -85,6 +87,10 @@ export default {
             const { group } = action;
             return { ...state, selectedGroup: group };
         },
+        reset(state, action) {
+            let newState = Object.assign({}, state, state.originData);
+            return Object.assign({}, newState);
+        },
     },
     effects: {
         *fetchList(action, { put, call, select }) {
@@ -279,8 +285,7 @@ export default {
     },
     subscriptions: {
         setup({ dispatch, history }) {
-            return history.listen(({ pathname, query }) => {
-            })
+            dispatch({ type: 'reset' });
         }
     }
 };

+ 5 - 3
src/routes/mainLayout.js

@@ -8,9 +8,10 @@ import Loading from '../components/common/loading/loading'
 import DataSource from '../components/dataSource/list'
 import Dashboard from '../components/dashboard/list'
 import Chart from '../components/chart/list'
-import './mainLayout.less';
-import Demo from '../demo';
-import Admin from '../components/admin/admin';
+import './mainLayout.less'
+import Demo from '../demo'
+import Admin from '../components/admin/admin'
+import UserInfo from '../components/user/layout'
 const { Header, Content } = Layout
 
 const MainLayout = ({ isAuthenticated }) => {
@@ -28,6 +29,7 @@ const MainLayout = ({ isAuthenticated }) => {
                     <Route sensitive path='/dashboard' component={Dashboard} />
                     <Route sensitive path='/chart' component={Chart} />
                     <Route sensitive path='/admin' component={Admin} />
+                    <Route sensitive path='/userinfo' component={UserInfo} />
                     <Route path='/' component={isAuthenticated ? HomePage : () => <Redirect
                         to={{
                             pathname: "/login",