添加《实名认证》模块的一级认证页面。尚未完工。
This commit is contained in:
@@ -154,9 +154,9 @@ export default {
|
|||||||
'lgpwd.originPrompt': 'Please input your original login password',
|
'lgpwd.originPrompt': 'Please input your original login password',
|
||||||
'lgpwd.success': 'Login password is changed successfully',
|
'lgpwd.success': 'Login password is changed successfully',
|
||||||
|
|
||||||
'profile.account': 'Account Settings',
|
'profile.account': 'My Account',
|
||||||
'profile.system': 'System Settings',
|
'profile.system': 'System Settings',
|
||||||
'profile.identity': 'KYC',
|
'profile.identity': 'KYC Authentication',
|
||||||
'profile.share': 'Promotion',
|
'profile.share': 'Promotion',
|
||||||
'profile.msg': 'Message Center',
|
'profile.msg': 'Message Center',
|
||||||
'profile.about': 'About VIC',
|
'profile.about': 'About VIC',
|
||||||
@@ -170,6 +170,18 @@ export default {
|
|||||||
'account.factor': '2FA',
|
'account.factor': '2FA',
|
||||||
'account.logout': 'Logout',
|
'account.logout': 'Logout',
|
||||||
'account.confirm': 'Are you sure to logout?',
|
'account.confirm': 'Are you sure to logout?',
|
||||||
|
'account.modifyNickname': 'Change nickname',
|
||||||
|
|
||||||
|
'identity.title': 'KYC 1st Level',
|
||||||
|
'identity.realname': 'Real Name',
|
||||||
|
'identity.nationality': 'Nationality',
|
||||||
|
'identity.idtype': 'ID Type',
|
||||||
|
'identity.idcode': 'ID Code',
|
||||||
|
'identity.idphoto': 'ID Photo',
|
||||||
|
'identity.idtypes': {idcard:'id card', passport:'passport'},
|
||||||
|
'identity.chooseIdtype': 'Type of id cards',
|
||||||
|
'identity.real1btn': 'Submit',
|
||||||
|
'identity.real2btn': 'Go to 2nd level of KYC',
|
||||||
|
|
||||||
'system.title': 'Settings',
|
'system.title': 'Settings',
|
||||||
'system.language': 'Language',
|
'system.language': 'Language',
|
||||||
|
|||||||
@@ -170,6 +170,18 @@ export default {
|
|||||||
'account.factor': '双因子验证(2FA)',
|
'account.factor': '双因子验证(2FA)',
|
||||||
'account.logout': '退出登录',
|
'account.logout': '退出登录',
|
||||||
'account.confirm': '是否确认退出登录?',
|
'account.confirm': '是否确认退出登录?',
|
||||||
|
'account.modifyNickname': '修改昵称',
|
||||||
|
|
||||||
|
'identity.title': '一级实名认证',
|
||||||
|
'identity.realname': '实名',
|
||||||
|
'identity.nationality': '国籍',
|
||||||
|
'identity.idtype': '证件类型',
|
||||||
|
'identity.idcode': '证件编号',
|
||||||
|
'identity.idphoto': '证件照片',
|
||||||
|
'identity.idtypes': {idcard:'身份证', passport:'护照'},
|
||||||
|
'identity.chooseIdtype': '选择证件类型',
|
||||||
|
'identity.real1btn': '提交',
|
||||||
|
'identity.real2btn': '进入二级实名认证',
|
||||||
|
|
||||||
'system.title': '我的设置',
|
'system.title': '我的设置',
|
||||||
'system.language': '语言偏好',
|
'system.language': '语言偏好',
|
||||||
|
|||||||
@@ -133,8 +133,7 @@ const AboutPage: React.FC = () => {
|
|||||||
<br/>
|
<br/>
|
||||||
<div className="section">
|
<div className="section">
|
||||||
<span className="title">{formatMessage({ id: 'about.contact' })}</span>
|
<span className="title">{formatMessage({ id: 'about.contact' })}</span>
|
||||||
<span className="desc">邮箱: {config.linkEmail}</span>
|
<span className="desc">{config.linkHomeweb}</span>
|
||||||
<span className="desc">微信号: {config.linkSupport}</span>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<br/>
|
<br/>
|
||||||
|
|||||||
@@ -34,7 +34,7 @@ const AccountPage: React.FC<DispatchProp & UserModelState & AccountModelState> =
|
|||||||
|
|
||||||
const editNameModal = (
|
const editNameModal = (
|
||||||
<Modal
|
<Modal
|
||||||
title={formatMessage({ id: 'common.modify' })}
|
title={formatMessage({ id: 'account.modifyNickname' })}
|
||||||
visible={nameEditable}
|
visible={nameEditable}
|
||||||
onCancel={() => dispatch({ type: 'account/onUpdateState', nameEditable: false })}
|
onCancel={() => dispatch({ type: 'account/onUpdateState', nameEditable: false })}
|
||||||
onOk={() => dispatch({ type: 'account/changeName' })}
|
onOk={() => dispatch({ type: 'account/changeName' })}
|
||||||
|
|||||||
@@ -43,6 +43,12 @@ const ProfilePage: React.FC<UserModelState & DispatchProp> = ({
|
|||||||
title="profile.account"
|
title="profile.account"
|
||||||
onClick={() => dispatch(routerRedux.push('/account'))}
|
onClick={() => dispatch(routerRedux.push('/account'))}
|
||||||
/>
|
/>
|
||||||
|
<SettingItem
|
||||||
|
className="group"
|
||||||
|
logo={logoIdentity}
|
||||||
|
title="profile.identity"
|
||||||
|
onClick={() => dispatch(routerRedux.push('/identity'))}
|
||||||
|
/>
|
||||||
<SettingItem
|
<SettingItem
|
||||||
className="group"
|
className="group"
|
||||||
logo={logoSystem}
|
logo={logoSystem}
|
||||||
|
|||||||
109
src/pages/identity/index.tsx
Normal file
109
src/pages/identity/index.tsx
Normal file
@@ -0,0 +1,109 @@
|
|||||||
|
/**
|
||||||
|
* Title: 地产详情
|
||||||
|
* Routes:
|
||||||
|
* - ./src/pages/routes
|
||||||
|
*/
|
||||||
|
import React, { useState } from 'react';
|
||||||
|
import { connect, DispatchProp, routerRedux } from 'dva';
|
||||||
|
import { formatMessage } from 'umi-plugin-locale';
|
||||||
|
import { Button, Modal, Input } from 'antd';
|
||||||
|
import Header from '@/components/Header';
|
||||||
|
import ChoiceModal from '@/components/ChoiceModal';
|
||||||
|
import AccountItem from '@/components/AccountItem';
|
||||||
|
import { UserModelState } from '@/models/user';
|
||||||
|
import { dispatch } from '@/utils/utils';
|
||||||
|
|
||||||
|
import styles from './style.less';
|
||||||
|
import { IdentityModelState } from './model';
|
||||||
|
|
||||||
|
const idtypes = [
|
||||||
|
{key:'idcard', value:'身份证'},
|
||||||
|
{key:'passport', value:'护照'}]
|
||||||
|
|
||||||
|
const IdentityPage: React.FC<DispatchProp & UserModelState & IdentityModelState> = ({
|
||||||
|
dispatch,
|
||||||
|
user,
|
||||||
|
nameEditable,
|
||||||
|
nameInput,
|
||||||
|
nameSubmitting,
|
||||||
|
real1Submitting
|
||||||
|
}) => {
|
||||||
|
|
||||||
|
const [idtypesVisible, setIdtypesVisible] = useState(false);
|
||||||
|
|
||||||
|
const onItemSelected = (key: string) => {
|
||||||
|
setIdtypesVisible(false);
|
||||||
|
// dispatch({ type: 'user/changeIdtype', payload: key });
|
||||||
|
};
|
||||||
|
|
||||||
|
const idtypeModal = (
|
||||||
|
<ChoiceModal
|
||||||
|
closable={false}
|
||||||
|
data={idtypes}
|
||||||
|
selectedKey='idcard'
|
||||||
|
onItemSelected={onItemSelected}
|
||||||
|
visible={idtypesVisible}
|
||||||
|
onCancel={() => setIdtypesVisible(false)}
|
||||||
|
title={formatMessage({ id: 'identity.chooseIdtype' })}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className={styles.container}>
|
||||||
|
<Header
|
||||||
|
className={styles.header}
|
||||||
|
title={formatMessage({ id: 'identity.title' })}
|
||||||
|
/>
|
||||||
|
{user && <div className={styles.content}>
|
||||||
|
<AccountItem
|
||||||
|
className="group"
|
||||||
|
title="identity.realname"
|
||||||
|
message={user.realname}
|
||||||
|
showGo={false}
|
||||||
|
onClick={() => dispatch({
|
||||||
|
type: 'identity/onUpdateState',
|
||||||
|
nameEditable: true,
|
||||||
|
nameInput: user.realname,
|
||||||
|
})}
|
||||||
|
/>
|
||||||
|
<AccountItem
|
||||||
|
className="group"
|
||||||
|
title="identity.nationality"
|
||||||
|
message={user.nationality}
|
||||||
|
// preview={fromLangToText(lang)}
|
||||||
|
// onClick={() => setNationsVisible(true)}
|
||||||
|
/>
|
||||||
|
<AccountItem
|
||||||
|
className="group"
|
||||||
|
title="identity.idtype"
|
||||||
|
message={user.idtype}
|
||||||
|
// preview={fromLangToText(lang)}
|
||||||
|
onClick={() => setIdtypesVisible(true)}
|
||||||
|
/>
|
||||||
|
<AccountItem
|
||||||
|
className="group"
|
||||||
|
title="identity.idcode"
|
||||||
|
message={user.idcode}
|
||||||
|
// onClick={() => dispatch(routerRedux.push('/chphone'))}
|
||||||
|
/>
|
||||||
|
<AccountItem
|
||||||
|
className="group"
|
||||||
|
title="identity.idphoto"
|
||||||
|
// onClick={() => dispatch(routerRedux.push('/lgpwd'))}
|
||||||
|
/>
|
||||||
|
// 此处应当加一个label,显示后台驳回理由
|
||||||
|
<Button
|
||||||
|
className={styles.input}
|
||||||
|
type="primary"
|
||||||
|
size="large"
|
||||||
|
loading={real1Submitting}
|
||||||
|
onClick={() => dispatch({ type: 'identity/real1submit' })}
|
||||||
|
>{formatMessage({ id: 'identity.real1btn' })}</Button>
|
||||||
|
</div>}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default connect(
|
||||||
|
({ user, account }: any) => ({ ...user, ...account }),
|
||||||
|
)(IdentityPage);
|
||||||
52
src/pages/identity/model.ts
Normal file
52
src/pages/identity/model.ts
Normal file
@@ -0,0 +1,52 @@
|
|||||||
|
import { Model } from 'dva';
|
||||||
|
import { changeName } from './service';
|
||||||
|
import { message } from 'antd';
|
||||||
|
|
||||||
|
export interface IdentityModelState {
|
||||||
|
nameEditable: boolean;
|
||||||
|
nameInput: string;
|
||||||
|
nameSubmitting: boolean;
|
||||||
|
real1Submitting: boolean;
|
||||||
|
}
|
||||||
|
|
||||||
|
const model: Model = {
|
||||||
|
namespace: 'identity',
|
||||||
|
|
||||||
|
state: {
|
||||||
|
nameEditable: false,
|
||||||
|
nameInput: '',
|
||||||
|
nameSubmitting: false,
|
||||||
|
real1Submitting: false,
|
||||||
|
} as IdentityModelState,
|
||||||
|
|
||||||
|
effects: {
|
||||||
|
*changeName(_, { put, all, call, select }) {
|
||||||
|
const { nameInput } = yield select((state: any) => state.account);
|
||||||
|
if (!nameInput) return;
|
||||||
|
|
||||||
|
yield put({ type: 'onUpdateState', nameSubmitting: true });
|
||||||
|
try {
|
||||||
|
yield call(changeName, nameInput);
|
||||||
|
yield all([
|
||||||
|
put({ type: 'onUpdateState', nameInput: '', nameEditable: false }),
|
||||||
|
put({ type: 'user/updateUser', payload: { nickname: nameInput } }),
|
||||||
|
]);
|
||||||
|
} catch (e) {
|
||||||
|
message.error(e.message);
|
||||||
|
} finally {
|
||||||
|
yield put({ type: 'onUpdateState', nameSubmitting: false });
|
||||||
|
}
|
||||||
|
},
|
||||||
|
},
|
||||||
|
|
||||||
|
reducers: {
|
||||||
|
onUpdateState(state, payload) {
|
||||||
|
return {
|
||||||
|
...state,
|
||||||
|
...payload,
|
||||||
|
};
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
export default model;
|
||||||
9
src/pages/identity/service.ts
Normal file
9
src/pages/identity/service.ts
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
import http from '@/utils/http';
|
||||||
|
|
||||||
|
export async function changeName(nickname: string) {
|
||||||
|
const { ok, msg } = await http.post('/user/chnickname', { nickname });
|
||||||
|
if (ok) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
throw Error(msg);
|
||||||
|
}
|
||||||
29
src/pages/identity/style.less
Normal file
29
src/pages/identity/style.less
Normal file
@@ -0,0 +1,29 @@
|
|||||||
|
@import '../../global.less';
|
||||||
|
|
||||||
|
.container {
|
||||||
|
height: 100%;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
}
|
||||||
|
|
||||||
|
.header {
|
||||||
|
flex-shrink: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.content {
|
||||||
|
flex-grow: 1;
|
||||||
|
overflow: auto;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: stretch;
|
||||||
|
|
||||||
|
:global {
|
||||||
|
.group {
|
||||||
|
margin: 8px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.logout {
|
||||||
|
margin: 16px 10px;
|
||||||
|
}
|
||||||
@@ -13,6 +13,10 @@ export interface User {
|
|||||||
token: string;
|
token: string;
|
||||||
inviteCode: string;
|
inviteCode: string;
|
||||||
inviter: string;
|
inviter: string;
|
||||||
|
realname: string;
|
||||||
|
idcode: string;
|
||||||
|
idtype: string;
|
||||||
|
nationality: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export enum SendCodeType {
|
export enum SendCodeType {
|
||||||
|
|||||||
Reference in New Issue
Block a user