Commit 89f900c1 authored by superman's avatar superman

增加身份认证审核

parent 1ec72cd6
This diff is collapsed.
This diff is collapsed.
import React, {Component, PropTypes} from 'react';
import {Button, Icon, Popconfirm, Menu, Row, Col, Popover} from 'antd';
import {Button, Icon, Popconfirm, Menu, Row, Col, Popover, Tooltip} from 'antd';
import {connect} from 'react-redux';
import {Link} from 'react-router';
......@@ -78,6 +78,9 @@ export default class HeaderOperation extends Component {
{
buttons.map(button=> {
const props = {...defaultButtons[button.key], ...button};
const title = props.title;
delete props.title;
if (props.link) {
const icon = props.icon;
......@@ -85,15 +88,19 @@ export default class HeaderOperation extends Component {
delete props.icon;
delete props.link;
return (
<Button type="ghost" {...props} >
<Link to={link}>
<Icon type={icon}/>
</Link>
</Button>
<Tooltip title={title} key={props.key+'tooltip'}>
<Button type="ghost" {...props} >
<Link to={link}>
<Icon type={icon}/>
</Link>
</Button>
</Tooltip>
);
}
const btn = (
<Button type="ghost" {...props} />
<Tooltip title={title} key={props.key+'tooltip'}>
<Button type="ghost" {...props} />
</Tooltip>
);
if (props.onConfirm) {
return (
......
......@@ -73,6 +73,10 @@ export default class App extends Component {
to: '/withdraw/audits',
cn: '提现审核',
en: 'Withdraw Money'
},{
to:'/authInfo/audits',
cn:'身份认证审核',
en: 'Auth Audits'
}
]
}, {
......
import React, {Component, PropTypes} from 'react';
import {connect} from 'react-redux';
import {
Row,
Col,
Form,
Input,
Button,
Checkbox,
Select,
message,
Tabs,
Cascader,
Radio,
Upload,
Icon,
Modal,
DatePicker,
Table,
Spin
} from 'antd';
import Layout from '../../components/Layout/Layout';
import MainHeader from '../../components/MainHeader/MainHeader';
import HeaderOperation, {DetailOperations} from '../../components/HeaderOperation/HeaderOperation';
import {
formatDateTime,
formItemLayout,
smallFormItemLayout,
footerFormSubmitLayout,
remittanceAuditStatusToString,
leftRightFormItemLayout,
NULL
} from '../../utils';
@connect(state=>({
loading: state.authInfo.loading,
audit: state.authInfo.audit,
}))
@Form.create()
export default class PassItem extends Component {
constructor() {
super(...arguments);
this.state = {
priviewVisible: false,
priviewImage: '',
isEdit: false
}
}
componentDidMount() {
this.fetchItem(this.props.params.id);
};
fetchItem(id) {
this.props.dispatch({
type: 'FETCH_AUTHINFO_ITEM',
id
});
};
handleSubmit(status, e) {
e.preventDefault();
const data = this.props.form.getFieldsValue();
data.id = this.props.params.id;
data.status = status;
console.log(data);
if (status == 9) {
delete data.memo;
}
this.props.dispatch({
type: 'PASS_AUTHINFO_ITEM',
data
});
}
render() {
const {audit, loading, form:{getFieldProps}, location:{query}, params, dispatch} = this.props;
let title = (audit && audit.realName ? audit.realName + ' - ' : '');
const isEdit = audit && audit.status == 1 && this.state.isEdit;
if (audit) {
switch (audit.status) {
case 1:
title += '身份认证审核详情' + (isEdit? ' - 审核中': '');
break;
case 5:
title += '审核失败';
break;
case 9:
title += '审核成功';
}
} else {
title += '身份认证审核详情';
}
const buttons = [{
key: 'rollback',
onClick: e=> {
e.preventDefault();
isEdit ?
this.setState({isEdit: !this.state.isEdit}) :
this.props.history.goBack();
}
}];
if(audit && audit.status == 1){
buttons.unshift({
key:'edit',
onClick:e=> {
e.preventDefault();
this.setState({isEdit: !this.state.isEdit})
}
});
}
const operation = (
<HeaderOperation history={this.props.history} buttons={buttons}/>
);
const header = (<MainHeader breadcrumb={['审核管理', '身份认证审核', '审核详情']} title={title} operation={operation}/>);
const imgProps = (src)=>({
src: src + '!t',
style: {maxWidth: 200, maxHeight: 160},
onClick: e => {
e.preventDefault();
this.setState({
priviewVisible: true,
priviewImage: src
});
}
});
return (
<Layout header={header}>
<Spin spinning={loading}>
{
audit &&
<Form className="main-form" horizontal>
<Row style={{padding: '0 20px'}}>
<Col span="12">
<Form.Item label="用户ID" {...leftRightFormItemLayout}>
{audit.userId || NULL}
</Form.Item>
<Form.Item label="用户名" {...leftRightFormItemLayout}>
{audit.realName || NULL}
</Form.Item>
<Form.Item label="昵称" {...leftRightFormItemLayout}>
{audit.nick || NULL}
</Form.Item>
<Form.Item label="手机号" {...leftRightFormItemLayout}>
{audit.mobile || NULL}
</Form.Item>
{
audit.status == 5 ?
<Form.Item label="拒绝理由" {...smallFormItemLayout}>
{ audit.memo || NULL }
</Form.Item>
:
(
audit.status == 1 && isEdit &&
<Form.Item label="拒绝理由" {...smallFormItemLayout}>
<Input placeholder="拒绝理由" type="textarea"
autosize
{...getFieldProps('memo', {
initialValue: ''
})} />
</Form.Item>
)
}
<Form.Item wrapperCol={{span: 16, offset: 6}} style={{marginTop: 30}}>
{
audit.status == 1 && (
isEdit ?
<span>
<Button size="large" type="primary"
onClick={this.handleSubmit.bind(this, 9)}>
<Icon type="check-circle-o"/>通过
</Button>
<Button size="large" type="ghost"
onClick={this.handleSubmit.bind(this, 5)}
style={{margin: 'auto 1em'}}>
<Icon type="cross-circle-o"/>拒绝
</Button>
</span>
:
<Button type="primary"
style={{marginRight: '1em'}}
onClick={ e=> {
e.preventDefault();
this.setState({isEdit: !this.state.isEdit})
}}>
<Icon type="edit"/>审核
</Button>
)
}
<Button onClick={e=> {
e.preventDefault();
isEdit ?
this.setState({isEdit: !this.state.isEdit}) :
this.props.history.goBack();
}}>
<Icon type="rollback"/>返回
</Button>
</Form.Item>
</Col>
<Col span="12">
<Form.Item label="身份认证照片">
{
audit.authPic ?
<img {...imgProps(audit.authPic)}/>
:
<p style={{color: '#f00'}}>
<Icon type="cross-circle-o" style={{marginRight: '.5em'}}/>
身份认证照片未上传,请拒绝!
</p>
}
</Form.Item>
</Col>
</Row>
<Modal className="img-priview-dialog" footer={null}
visible={this.state.priviewVisible}
onCancel={()=>this.setState({priviewVisible: false})}>
<img src={this.state.priviewImage}/>
</Modal>
</Form>
}
</Spin>
</Layout>
);
}
}
import React, {Component, PropTypes} from 'react';
import {connect} from 'react-redux';
import {Table, Icon} from 'antd';
import {Link} from 'react-router';
import {serialize, formatDateTime, remittanceAuditStatusToString} from '../../utils';
import Layout from '../../components/Layout/Layout';
import MainHeader from '../../components/MainHeader/MainHeader';
import HeaderOperation from '../../components/HeaderOperation/HeaderOperation';
const columns = [
{
title: 'ID',
dataIndex: 'id',
key: 'id',
width: 70
}, {
title: '用户ID',
dataIndex: 'userId',
key: 'userId',
width: 100
}, {
title: '申请时间',
dataIndex: 'dateCreated',
key: 'dateCreated',
width: 150,
className: 'tac',
render: (dateCreated, record)=>(
<span>
{dateCreated && formatDateTime(dateCreated)}
</span>
)
}, {
title: '状态',
dataIndex: 'status',
key: 'status',
width: 120,
className: 'tac',
render: (status, record)=>(<span data-status={status}>{remittanceAuditStatusToString(status)}</span>)
}, {
title: '操作',
key: 'operation',
width: 60,
className: 'tac',
render: (text, record)=>(
<span>
{
record.status == 1 &&
<Link to={'/authInfo/audits/' + record.id} onClick={e=>e.stopPropagation()}>审核</Link>
}
</span>
)
}
];
@connect(state=>({
items: state.authInfo.audits,
loading: state.authInfo.loading,
total: state.authInfo.total,
}))
export default class List extends Component {
constructor(props, context) {
super(props, context);
this.state = {
filterVisible: false
}
}
componentDidMount() {
this.fetchList(this.props.location.query);
};
fetchList(query) {
this.props.dispatch({
type: 'FETCH_AUTHINFO_LIST',
query
});
}
handleRowClick({id}) {
this.props.history.push('/authInfo/audits/' + id);
}
render() {
const {total, items, loading, history:{replace}, location:{pathname, query}} = this.props;
const pagination = {
total: total,
pageSize: parseInt(query.s, 10) || 30,
current: parseInt(query.p, 10) || 1,
showSizeChanger: true,
showTotal: total => `共 ${total} 条`,
pageSizeOptions: ['10', '30', '50', '100'],
onShowSizeChange: (current, pageSize)=> {
console.log('Current: ', current, '; PageSize: ', pageSize);
query.p = current;
query.s = pageSize;
replace(pathname + '?' + serialize(query));
this.fetchList(query);
},
onChange: (current) => {
console.log('Current: ', current);
query.p = current;
replace(pathname + '?' + serialize(query));
this.fetchList(query);
}
};
const operation = (
<HeaderOperation history={this.props.history} buttons={[{
key: 'filter',
}]}/>
);
const header = (<MainHeader breadcrumb={['审核管理', '身份认证审核']}
title="身份认证审核列表"
operation={operation}
/>);
return (
<Layout header={header}>
<Table className="list-table" columns={columns}
dataSource={Array.isArray(items) ? items : []}
loading={loading}
pagination={pagination}
scroll={{y: window.innerHeight - (this.state.filterVisible ? 203 : 150)}}
onRowClick={this.handleRowClick.bind(this)}
/>
</Layout>
);
}
}
......@@ -6,6 +6,10 @@ const Home = ({location}) => {
<div style={{padding: '20px 50px 20px 100px'}}>
<h1 style={{marginBottom: 50}}>欢迎使用枢纽科技后台</h1>
<h3>2016-08-15 更新 1.3.1</h3>
<p>
1. 增加身份认证审核
</p>
<h3>2016-08-12 更新 1.3.0</h3>
<p>
1. 权限系统<br/>
......
......@@ -30,3 +30,5 @@ export AuthorityItem from './Authority/EditItem';
export ModifyPassword from './Users/ModifyPassword';
export Register from './Users/Register';
export AuthInfoList from './AuthInfo/List';
export AuthInfoItem from './AuthInfo/Item';
import {handleActions} from 'redux-actions';
import {combineReducer} from 'redux';
const authInfo = handleActions({
['FETCH_AUTHINFO_LIST'](state) {
return {...state, loading: true,};
},
['FETCH_AUTHINFO_LIST_SUCCESS'](state, action) {
return {...state, loading: false, audits: action.items, total: action.total};
},
['FETCH_AUTHINFO_LIST_FAILED'](state, action) {
return {...state, err: action.err, loading: false, audits: [], total: 0};
},
['FETCH_AUTHINFO_ITEM'](state) {
return {...state, loading: true,};
},
['FETCH_AUTHINFO_ITEM_SUCCESS'](state, action) {
return {...state, loading: false, audit: action.item};
},
['FETCH_AUTHINFO_ITEM_FAILED'](state, action) {
return {...state, err: action.err, loading: false, audit: null};
},
['PASS_AUTHINFO_ITEM'](state){
return {...state, loading: true};
},
['PASS_AUTHINFO_ITEM_SUCCESS'](state, action){
return {...state, loading: false, audit: {...state.audit, ...action.data}};
},
['PASS_AUTHINFO_ITEM_FAILED'](state, action){
return {...state, loading: false, err: action.err};
}
}, {
audits: [],
loading: false,
});
export default authInfo;
......@@ -43,6 +43,12 @@ export default (store)=> {
<Route path=":id" component={Containers.PassWithDrawItem}/>
</Route>
</Route>
<Route path="authInfo">
<Route path="audits">
<IndexRoute component={Containers.AuthInfoList}/>
<Route path=":id" component={Containers.AuthInfoItem}/>
</Route>
</Route>
<Route path="customMessages">
<IndexRoute component={Containers.CustomMessageList}/>
<Route path="create" component={Containers.CustomMessageAddItem}/>
......@@ -65,11 +71,11 @@ export default (store)=> {
</Route>
</Route>
<Route path="my">
<Route path="modifyPassword" component={Containers.ModifyPassword} />
<Route path="modifyPassword" component={Containers.ModifyPassword}/>
</Route>
</Route>
<Route path="/login" component={Containers.Login}/>
<Route path="/register" component={Containers.Register} />
<Route path="/register" component={Containers.Register}/>
<Route path="*" component={Containers.NotFound}/>
</Route>
);
......
import {takeLatest} from 'redux-saga';
import {take, call, put, fork, cancel, select} from 'redux-saga/effects';
import {fetchList, fetchItem, pass} from '../services/authInfo';
import {message} from 'antd';
import {watchIndex, watchShow, watchCreate, watchEdit, watch} from './RESTful';
export default function*() {
const ID = 'AUTHINFO';
yield fork(watchIndex(ID, fetchList));
yield fork(watchShow(ID, fetchItem));
yield fork(watch('PASS_AUTHINFO_ITEM', pass, '审核'));
}
......@@ -4,31 +4,6 @@ import {fetchList, fetchItem, pass} from '../services/remittance';
import {message} from 'antd';
import {watchIndex, watchShow, watchCreate, watchEdit, watch} from './RESTful';
// function* passItem(item){
// try {
// yield call(pass, item);
//
// yield put({
// type: 'PASS_REMITTANCE_ITEM_SUCCESS',
// item
// });
// } catch (err) {
// console.log(err);
// message.error(err);
// yield put({
// type: 'PASS_REMITTANCE_ITEM_FAILED',
// err
// });
// }
// }
// function* watchPassItem() {
// while (true) {
// const {data} = yield take('PASS_REMITTANCE_ITEM');
// yield fork(passItem, data);
// }
// }
export default function*() {
const ID = 'REMITTANCE';
// yield fork(watchPassItem);
......
import xFetch from './xFetch';
import {serialize} from '../utils';
export async function fetchList(query) {
return xFetch('/api/authInfo/audits' + '?' + serialize({s: 30, ...query}));
}
export async function fetchItem(id) {
return xFetch('/api/authInfo/audits/' + id);
}
export async function pass(data) {
return xFetch('/api/authInfo/audits/' + data.id, {
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