Commit f4b6db9e authored by superman's avatar superman

1.3.3

parent c52926c0
This source diff could not be displayed because it is too large. You can view the blob instead.
This source diff could not be displayed because it is too large. You can view the blob instead.
......@@ -131,6 +131,7 @@ export default class HeaderOperation extends Component {
<ul>
<li><a href="javascript:void('退出');" onClick={handleExit}>退出</a></li>
<li><Link to="/my/modifyPassword">修改密码</Link></li>
<li><Link to={'/my/' + user.id}>个人信息</Link></li>
</ul>
) : null;
......
......@@ -36,7 +36,7 @@ export default class App extends Component {
const styles = require('./App.less');
const menu = [
{
id:'business',
id: 'business',
title: '业务管理',
icon: 'mail',
items: [
......@@ -73,9 +73,9 @@ export default class App extends Component {
to: '/withdraw/audits',
cn: '提现审核',
en: 'Withdraw Money'
},{
to:'/authInfo/audits',
cn:'身份认证审核',
}, {
to: '/authInfo/audits',
cn: '身份认证审核',
en: 'Auth Audits'
}
]
......@@ -95,7 +95,7 @@ export default class App extends Component {
}
]
}, {
id:'base',
id: 'base',
title: '基础功能',
icon: 'folder',
items: [
......@@ -110,8 +110,13 @@ export default class App extends Component {
]
}
]
}, {
id:'admin',
}];
const {user, location:{pathname}} = this.props;
if (user && user.authorities && user.authorities['ROLE_ADMIN']) {
menu.push({
id: 'admin',
title: '管理员',
icon: 'folder',
items: [
......@@ -139,9 +144,43 @@ export default class App extends Component {
]
}
]
}];
})
}
const {user, location:{pathname}} = this.props;
menu.push({
id: 'setting',
title: '设置',
icon: 'setting',
items: [
{
title: '个人信息',
items: [
{
to: '/my/modifyPassword',
cn: '修改密码',
en: 'Modify Password'
}, {
to: '/my/' + (user && user.id || ''),
cn: '个人资料',
en: 'Profile setting'
}, {
onClick: (e)=> {
e.preventDefault();
this.props.dispatch({
type: 'LOGIN_REQUEST',
replace: this.props.history.replace
});
this.props.dispatch({
type: 'LOGOUT'
});
},
cn: '退出',
en: 'Exit System'
}
]
}
]
});
const logo = require('./images/logo.png');
......@@ -157,13 +196,13 @@ export default class App extends Component {
<Menu mode="inline" defaultOpenKeys={['sub1']}>
{user && user.token &&
menu.map((submenu, si)=>
<SubMenu key={'submenu'+si} title={
<span><Icon type={submenu.icon} /><span>{submenu.title}</span></span>
<SubMenu key={'submenu' + si} title={
<span><Icon type={submenu.icon}/><span>{submenu.title}</span></span>
}>
{submenu.items.map((menus, mi)=>
<MenuItemGroup key={'menu-item-group-'+si+'-'+ mi} title={menus.title}>
<MenuItemGroup key={'menu-item-group-' + si + '-' + mi} title={menus.title}>
{menus.items.map((item, ii)=>
<Menu.Item key={[si, mi,ii].join('-')}>
<Menu.Item key={[si, mi, ii].join('-')}>
<MenuItemContent {...item}/>
</Menu.Item>
)}
......@@ -193,8 +232,16 @@ class MenuItemContent extends Component {
}
render() {
const {to, cn, en} = this.props;
const {to, cn, en, onClick} = this.props;
return (
onClick ?
<a href={"javascript:void('" + cn + "');"} onClick={onClick}>
<span>
<span className="cn">{cn}</span>
<span className="en">{en}</span>
</span>
</a>
:
<Link to={to}>
<span>
<span className="cn">{cn}</span>
......
......@@ -119,6 +119,12 @@ export default class EditItem extends Component {
}
})
}
if(data.name){
if(!/^ROLE_/g.test(data.name)){
data.name = 'ROLE_' + data.name;
}
data.name = (data.name+'').toUpperCase();
}
console.log(data);
this.props.dispatch({
type: data.id ? 'UPDATE_AUTHORITY_ITEM' : 'CREATE_AUTHORITY_ITEM',
......@@ -253,6 +259,8 @@ export default class EditItem extends Component {
hasCancel={!isCreate}/>
</Col>
{
params.id !== 'ROLE_ADMIN' &&
<Col span="12">
<Tree checkable={isEdit}
defaultExpandAll={true}
......@@ -266,6 +274,7 @@ export default class EditItem extends Component {
title={key}>
{
this.state.resourcesCategoryMap[key].map(res=>
res.action &&
<Tree.TreeNode className="resource-item"
key={
res.action.length === 1 ?
......@@ -293,6 +302,7 @@ export default class EditItem extends Component {
</Tree>
</Col>
}
</Row>
</Form>
}
......
......@@ -93,7 +93,7 @@ export default class List extends Component {
dispatch
} = this.props;
const handleRemove = (id)=>{
const handleRemove = (id)=> {
dispatch({
type: 'DELETE_AUTHORITY_ITEM',
id
......@@ -131,15 +131,21 @@ export default class List extends Component {
render: (status)=>(
<span>{enableStatusToString(status)}</span>
)
},{
}, {
title: '操作',
key: 'operation',
width: 120,
className: 'tac',
render: (text, record)=>(
(record.name === 'ROLE_ADMIN' || record.name === 'ROLE_USER' || record.name === 'ROLE_DEFAULT') ?
''
:
<Popconfirm title="确定要删除这个角色吗?"
onClick={e=>{e.preventDefault();e.stopPropagation();}}
onConfirm={handleRemove.bind(this, record.name )} >
onClick={e=> {
e.preventDefault();
e.stopPropagation();
}}
onConfirm={handleRemove.bind(this, record.name)}>
<a href="javascript:void('删除')">删除</a>
</Popconfirm>
)
......@@ -171,11 +177,12 @@ export default class List extends Component {
const buttons = [{
key:'add',
link:'/admin/authorities/create',
onClick:()=>{}
},{
key:'filter',
key: 'add',
link: '/admin/authorities/create',
onClick: ()=> {
}
}, {
key: 'filter',
}];
const operation = (
......@@ -183,7 +190,6 @@ export default class List extends Component {
);
const header = (
<MainHeader breadcrumb={['角色管理', '角色列表']}
title="角色列表"
......@@ -235,10 +241,10 @@ export default class List extends Component {
return (
<Layout header={header}>
<Table className="list-table" columns={columns}
dataSource={Array.isArray(items)?items:[]}
dataSource={Array.isArray(items) ? items : []}
loading={loading}
pagination={pagination}
scroll={{ y: window.innerHeight-(this.state.filterVisible? 203 :150) }}
scroll={{y: window.innerHeight - (this.state.filterVisible ? 203 : 150)}}
onRowClick={this.handleRowClick.bind(this)}
/>
</Layout>
......
......@@ -2,10 +2,19 @@ import React, {Component, PropTypes} from 'react';
const Home = ({location}) => {
const styles = require('./Home.less');
return (
<div style={{padding: '20px 50px 20px 100px'}}>
<div className={styles.home}>
<h1 style={{marginBottom: 50}}>欢迎使用枢纽科技后台</h1>
<h3>2016-08-18 更新 1.3.3</h3>
<p>
1. 菜单栏增加"设置"; "管理员"菜单只分配给管理员角色。<br/>
2. 修复Window下, 报单审核照片下载文件扩展名缺失。<br/>
3. 创建角色时, 角色ID强制"ROLE_"开头<br/>
4. ROLE_ADMIN, ROLE_USER, ROLE_DEFAULT 三个角色不允许删除<br/>
</p>
<h3>2016-08-17 更新 1.3.2</h3>
<p>
1. 报单审核列表页 下载审核成功的照片
......
.home {
padding: 20px 50px 20px 100px;
h1 {
font-size: 24px !important;
}
h3 {
margin-top: 30px !important;
color: #666 !important;
}
p {
margin-top: 10px !important;
color: #888 !important;
}
}
......@@ -84,9 +84,6 @@ export default class List extends Component {
// }
render() {
console.log('render');
const {total, items, loading, history:{replace}, location:{pathname, query}} = this.props;
const {selectedRowKeys} = this.state;
......@@ -128,7 +125,7 @@ export default class List extends Component {
}
const iframe = document.createElement('iframe');
const ids = selectedRowKeys.join(',');
iframe.src = '/zip/' + name + '?id=' + ids;
iframe.src = '/zip/' + name + '.zip?id=' + ids;
document.body.appendChild(iframe);
setTimeout(()=> {
document.body.removeChild(iframe);
......@@ -202,7 +199,7 @@ export default class List extends Component {
<a href="javascript:void('下载');" onClick={e=>{
e.stopPropagation();
const iframe = document.createElement('iframe');
iframe.src = '/zip/' + record.id + '?id=' + record.id;
iframe.src = '/zip/' + record.id + '.zip?id=' + record.id;
document.body.appendChild(iframe);
setTimeout(()=> {
document.body.removeChild(iframe);
......
......@@ -108,10 +108,10 @@ export default class PassItem extends Component {
}
}];
if(audit && audit.status == 1){
if (audit && audit.status == 1) {
buttons.unshift({
key:'edit',
onClick:e=> {
key: 'edit',
onClick: e=> {
e.preventDefault();
this.setState({isEdit: !this.state.isEdit})
}
......@@ -253,6 +253,18 @@ export default class PassItem extends Component {
}}>
<Icon type="rollback"/>返回
</Button>
{
audit.status == 9 &&
<Button style={{marginLeft:'1em'}} type="ghost" onClick={e=>{
e.stopPropagation();
const iframe = document.createElement('iframe');
iframe.src = '/zip/' + params.id + '.zip?id=' + params.id;
document.body.appendChild(iframe);
setTimeout(()=> {
document.body.removeChild(iframe);
}, 1000);
}}>下载</Button>
}
</Form.Item>
</Col>
<Col span="12">
......
......@@ -22,7 +22,7 @@ import {
import Layout from '../../components/Layout/Layout';
import MainHeader from '../../components/MainHeader/MainHeader';
import HeaderOperation,{DetailOperations} from '../../components/HeaderOperation/HeaderOperation';
import HeaderOperation, {DetailOperations} from '../../components/HeaderOperation/HeaderOperation';
import {
......@@ -87,12 +87,11 @@ export default class EditItem extends Component {
render() {
const {item, loading, form:{getFieldProps}, location:{query}, isEdit, dispatch} = this.props;
const header = (
<MainHeader breadcrumb={['权限管理', '权限资源详情']}
title={'权限资源详情' + (isEdit ? ' - 编辑' : '')}
operation={<HeaderOperation buttons={item && DetailOperations('RESOURCE', item.id, isEdit, dispatch)} />}
operation={<HeaderOperation
buttons={item ? DetailOperations('RESOURCE', item.id, isEdit, dispatch) : []}/>}
/>
);
......@@ -107,7 +106,7 @@ export default class EditItem extends Component {
{
isEdit ?
<Select
style={{width:200}} {...getFieldProps('category', {initialValue: item.category})}>
style={{width: 200}} {...getFieldProps('category', {initialValue: item.category})}>
<Select.Option value="业务管理">业务管理</Select.Option>
<Select.Option value="基础功能">基础功能</Select.Option>
<Select.Option value="系统管理">系统管理</Select.Option>
......@@ -143,14 +142,14 @@ export default class EditItem extends Component {
<Form.Item label="Actions" {...smallFormItemLayout}>
{
resourceActions(item.actionMask).map(({label, value})=>
<span key={value} style={{marginRight:'1em'}}>{label}</span>
<span key={value} style={{marginRight: '1em'}}>{label}</span>
)
}
</Form.Item>
<Form.Item label="创建时间" {...smallFormItemLayout}>
{item.dateCreated && formatDateTime(item.dateCreated)}
</Form.Item>
<Form.Item {...footerFormSubmitLayout} style={{marginTop:30}}>
<Form.Item {...footerFormSubmitLayout} style={{marginTop: 30}}>
{
isEdit ?
<Button type="primary" onClick={this.handleSubmit.bind(this)}
......@@ -158,17 +157,17 @@ export default class EditItem extends Component {
<Icon type="save"/>保存
</Button>
:
<Button type="primary" onClick={e=>{
<Button type="primary" onClick={e=> {
e.preventDefault();
this.props.dispatch({
type:'UPDATE_RESOURCE'
type: 'UPDATE_RESOURCE'
});
}}>
<Icon type="edit"/>编辑
</Button>
}
<Button onClick={e=>{
<Button onClick={e=> {
e.preventDefault();
isEdit ?
this.props.dispatch({
......@@ -176,7 +175,7 @@ export default class EditItem extends Component {
}) :
this.props.history.goBack();
}}
style={{marginLeft:'1em'}}>
style={{marginLeft: '1em'}}>
<Icon type="rollback"/>
{isEdit ? '取消' : '返回'}
</Button>
......
......@@ -39,19 +39,23 @@ import {
item: state.user.item,
isEdit: state.user.isEdit,
authorities: state.authority.items,
isAdmin: /^\/admin\//.test(location.pathname)
}))
@Form.create()
export default class EditItem extends Component {
constructor() {
super(...arguments);
this.state = {
authoritiesCheckedValues: []
authoritiesCheckedValues: [],
}
}
componentDidMount() {
console.log(this.props.isAdmin);
this.fetchItem(this.props.params.id);
if (this.props.isAdmin) {
this.fetchAuthorityList();
}
};
componentWillReceiveProps(nextProps) {
......@@ -79,8 +83,11 @@ export default class EditItem extends Component {
handleSubmit(e) {
e.preventDefault();
const data = this.props.form.getFieldsValue();
data.id = this.props.params.id;
const {form, params, dispatch, isAdmin} = this.props;
const data = form.getFieldsValue();
data.id = params.id;
if (isAdmin) {
if (isNaN(data.status)) {
Object.keys(USER_STATUS).forEach(key=> {
if (USER_STATUS[key] === data.status) {
......@@ -90,19 +97,24 @@ export default class EditItem extends Component {
})
}
data.authorities = this.state.authoritiesCheckedValues.join();
}
console.log(data);
this.props.dispatch({
dispatch({
type: 'UPDATE_USER_ITEM',
item: data
});
}
render() {
const {item, loading, form:{getFieldProps}, location:{query}, isEdit, authorities, dispatch, history} = this.props;
const {isAdmin, item, loading, form:{getFieldProps}, location:{query}, isEdit, authorities, dispatch, history} = this.props;
const breadcrumb = isAdmin ? ['用户管理', '用户详情'] : ['我的','个人信息'];
const title = isAdmin ? '用户详情' : '个人信息';
const header = (
<MainHeader breadcrumb={['用户管理', '用户详情']}
title={'用户详情' + (isEdit ? ' - 编辑' : '')}
<MainHeader breadcrumb={breadcrumb}
title={title + (isEdit ? ' - 编辑' : '')}
operation={<HeaderOperation history={history}
buttons={item && DetailOperations('USER', item.id, isEdit, dispatch)}/>}
/>
......@@ -134,6 +146,9 @@ export default class EditItem extends Component {
<Form.Item label="用户名" {...smallFormItemLayout}>
{ item.username }
</Form.Item>
{
isAdmin ?
<div>
<Form.Item label="状态" {...smallFormItemLayout}>
{
isEdit ?
......@@ -159,6 +174,9 @@ export default class EditItem extends Component {
(userAuthorities.length ? userAuthorities.join(',') : NULL)
}
</Form.Item>
</div>
:
<div>
<Form.Item label="昵称" {...smallFormItemLayout}>
{
isEdit ?
......@@ -183,6 +201,8 @@ export default class EditItem extends Component {
item.mobile || NULL
}
</Form.Item>
</div>
}
<Form.Item label="注册时间" {...smallFormItemLayout}>
{item.dateCreated && formatDateTime(item.dateCreated)}
</Form.Item>
......@@ -225,32 +245,3 @@ export default class EditItem extends Component {
);
}
}
// <Button type="ghost" onClick={e=>{e.preventDefault(); this.setState({isEdit: !this.state.isEdit})}}>
// <Icon type="edit"/>
// </Button>
// <Form.Item {...footerFormSubmitLayout} style={{marginTop:30}}>
// {
// isEdit ?
// <Button type="primary" onClick={this.handleSubmit.bind(this, -1)}
// loading={loading}>
// <Icon type="save"/>修改
// </Button>
// :
// item.status ?
// <Button type="primary" onClick={this.handleSubmit.bind(this, 0)}
// loading={loading}>
// <Icon type="save"/>禁用
// </Button>
// :
// <Button type="primary" onClick={this.handleSubmit.bind(this, 1)}
// loading={loading}>
// <Icon type="save"/>激活
// </Button>
// }
// <Button onClick={e=>{e.preventDefault(); this.props.history.goBack();}}
// style={{marginLeft:'1em'}}>
// <Icon type="rollback"/>返回
// </Button>
// </Form.Item>
......@@ -15,7 +15,7 @@ export default class Register extends Component {
componentWillReceiveProps(nextProps) {
if (nextProps.created) {
// this.props.history.replace('/login');
this.props.history.replace('/login');
}
}
......
......@@ -36,7 +36,8 @@
border-color: @primary-color;
}
&:focus {
box-shadow: 0 0 0 2px rgba(76, 150, 137, 0.2);
box-shadow: none;
//box-shadow: 0 0 0 2px rgba(76, 150, 137, 0.2);
}
}
.ant-btn-group {
......@@ -141,8 +142,6 @@
}
}
}
.tac {
......
......@@ -72,6 +72,7 @@ export default (store)=> {
</Route>
<Route path="my">
<Route path="modifyPassword" component={Containers.ModifyPassword}/>
<Route path=":id" component={Containers.UsersItem}/>
</Route>
</Route>
<Route path="/login" component={Containers.Login}/>
......
import {takeLatest} from 'redux-saga';
import {take, call, put, fork, cancel, race} from 'redux-saga/effects';
import {fetch, create, fetchList, fetchItem, updateItem, modifyPassword} from '../services/user';
import {
fetch, create, modifyPassword,
fetchList, fetchItem, updateItem
} from '../services/user';
import {message} from 'antd';
import {watchIndex, watchShow, watchCreate, watchEdit, watch} from './RESTful';
import {watchIndex, watchShow, watchEdit, watch} from './RESTful';
function* authorize(username, password, replace) {
try {
const user = yield call(fetch, username, password);
if (user && user.username && user.token) {
user.authorities = user.authorities ? user.authorities.split(',').reduce((s,a)=>{s[a]=a; return s},{}) : {};
sessionStorage.setItem('user', JSON.stringify({
time: Date.now(),
data: user
......@@ -46,7 +50,8 @@ export default function*() {
yield fork(watchShow(ID, fetchItem));
yield fork(watchEdit(ID, updateItem));
yield fork(watch('CREATE_USER', create, '创建用户'));
yield fork(watch('CREATE_USER', create, '注册'));
yield fork(watch('MODIFY_USER_PASSWORD', modifyPassword, '修改密码'));
}
......@@ -14,28 +14,37 @@ export async function create(data) {
body: serialize(data)
});
}
export async function modifyPassword(data) {
return xFetch('/api/users/' + data.username, {
method: 'PATCH',
body: serialize(data)
});
}
export async function fetchList(query) {
return xFetch('/api/admin/users' + '?' + serialize({s: 30, ...query}));
}
export async function fetchItem(id) {
return xFetch('/api/admin/users/' + id);
let url = /^\/admin\//.test(location.pathname) ? '/api/admin/users/' + id : '/api/users/' + id;
return xFetch(url);
}
export async function updateItem(data) {
return xFetch('/api/admin/users/' + data.id, {
let url;
if(/^\/admin\//.test(location.pathname)){
url = '/api/admin/users/' + data.id;
}else{
url = '/api/users/' + data.id;
}
return xFetch(url, {
method: 'PUT',
body: serialize(data)
})
}
export async function modifyPassword(data) {
return xFetch('/api/users/' + data.username, {
method: 'PATCH',
body: serialize(data)
});
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment