Commit f4b6db9e authored by superman's avatar superman

1.3.3

parent c52926c0
This diff is collapsed.
This diff is collapsed.
......@@ -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,14 +232,22 @@ class MenuItemContent extends Component {
}
render() {
const {to, cn, en} = this.props;
const {to, cn, en, onClick} = this.props;
return (
<Link to={to}>
<span>
<span className="cn">{cn}</span>
<span className="en">{en}</span>
</span>
</Link>
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>
<span className="en">{en}</span>
</span>
</Link>
);
}
}
......
......@@ -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,46 +259,50 @@ export default class EditItem extends Component {
hasCancel={!isCreate}/>
</Col>
<Col span="12">
<Tree checkable={isEdit}
defaultExpandAll={true}
checkedKeys={this.state.checkedKeys}
onCheck={(checkedKeys)=> {
this.setState({checkedKeys});
}}>
{
Object.keys(this.state.resourcesCategoryMap).map((key, index)=>
<Tree.TreeNode className="resource-category" key={'c-' + key}
title={key}>
{
this.state.resourcesCategoryMap[key].map(res=>
<Tree.TreeNode className="resource-item"
key={
res.action.length === 1 ?
('a-' + res.controllerName + '-' + res.action[0].value) :
('r-' + res.id)
}
title={
res.description + (
res.action.length === 1 ? ' - ' + res.action[0].label : ''
)
}>
{
res.action.length > 1 && res.action.map(action=>
<Tree.TreeNode className="resource-action"
key={'a-' + res.controllerName + '-' + action.value}
title={action.label}/>
)
}
</Tree.TreeNode>
)
}
</Tree.TreeNode>
)
}
</Tree>
{
params.id !== 'ROLE_ADMIN' &&
<Col span="12">
<Tree checkable={isEdit}
defaultExpandAll={true}
checkedKeys={this.state.checkedKeys}
onCheck={(checkedKeys)=> {
this.setState({checkedKeys});
}}>
{
Object.keys(this.state.resourcesCategoryMap).map((key, index)=>
<Tree.TreeNode className="resource-category" key={'c-' + key}
title={key}>
{
this.state.resourcesCategoryMap[key].map(res=>
res.action &&
<Tree.TreeNode className="resource-item"
key={
res.action.length === 1 ?
('a-' + res.controllerName + '-' + res.action[0].value) :
('r-' + res.id)
}
title={
res.description + (
res.action.length === 1 ? ' - ' + res.action[0].label : ''
)
}>
{
res.action.length > 1 && res.action.map(action=>
<Tree.TreeNode className="resource-action"
key={'a-' + res.controllerName + '-' + action.value}
title={action.label}/>
)
}
</Tree.TreeNode>
)
}
</Tree.TreeNode>
)
}
</Tree>
</Col>
</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,17 +131,23 @@ export default class List extends Component {
render: (status)=>(
<span>{enableStatusToString(status)}</span>
)
},{
}, {
title: '操作',
key: 'operation',
width: 120,
className: 'tac',
render: (text, record)=>(
<Popconfirm title="确定要删除这个角色吗?"
onClick={e=>{e.preventDefault();e.stopPropagation();}}
onConfirm={handleRemove.bind(this, record.name )} >
<a href="javascript:void('删除')">删除</a>
</Popconfirm>
(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)}>
<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="角色列表"
......@@ -199,7 +205,7 @@ export default class List extends Component {
{
cates &&
<Cascader options={cates} placeholder="请选产品类目" {...filterFormItemStyle}
{...getFieldProps('categoryId')}
{...getFieldProps('categoryId')}
/>
}
</Form.Item>
......@@ -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,25 +157,25 @@ 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=>{
e.preventDefault();
isEdit ?
this.props.dispatch({
type: 'CANCEL_UPDATE_RESOURCE'
}) :
this.props.history.goBack();
}}
style={{marginLeft:'1em'}}>
<Button onClick={e=> {
e.preventDefault();
isEdit ?
this.props.dispatch({
type: 'CANCEL_UPDATE_RESOURCE'
}) :
this.props.history.goBack();
}}
style={{marginLeft: '1em'}}>
<Icon type="rollback"/>
{isEdit ? '取消' : '返回'}
</Button>
......
This diff is collapsed.
......@@ -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