Commit b43d84b3 authored by wangxuelai's avatar wangxuelai

'学员解绑微信'

parent 4bb0869d
......@@ -72,6 +72,7 @@ export default {
studentsChoiceClass: `${dakaapi}member/erp/student/distribution`,
studentClassRecords: `${dakaapi}member/erp/student/calls`,
studentsLog: `${dakaapi}member/erp/student/logs`,
studentsUnBindWx: `${dakaapi}member/erp/student/wechat/remove`,
},
teachers: `${dakaapi}member/erp/teachers`,
courses: {
......
......@@ -10,7 +10,7 @@ import * as studentsAjax from '../services/students';
import * as classMgtAjax from '../services/classmgt';
import * as courseAjax from '../services/course';
import * as teachersAjax from '../services/teachers';
import * as commonAjax from '../services/common';
export default {
namespace: 'studentsinfo',
state: {
......@@ -57,6 +57,12 @@ export default {
changeOperatorShow: false,
teacherList: [],
datetime: '',
bindWxShow: false,
checkoutVerifyCode: false,
erpCountdown: 60,
erpCounting: false,
erptimer: null,
gettingErpVerifyCoding: false,
},
subscriptions: {
setup({ dispatch, history }) { // eslint-disable-line
......@@ -505,6 +511,134 @@ export default {
},
});
},
* sendErpVerifyCode({ payload }, { call, put, select }) {
const {
erpCountdown, erpCounting, gettingErpVerifyCoding, erptimer,
} = yield select(state => state.usersetting);
const { mobile, sms_type } = payload;
let newCountdowm = erpCountdown;
let newCounting = erpCounting;
if (gettingErpVerifyCoding) {
return;
}
yield put({
type: 'updateState',
payload: {
gettingErpVerifyCoding: true,
erpCounting: false,
},
});
const verifycodehide = message.loading('正在获取验证码....', 0);
const data = yield call(commonAjax.getErpVerifyCode, { mobile, sms_type });
if (data.code == 200) {
setTimeout(verifycodehide);
message.success('验证码获取成功', 1);
yield put({
type: 'updateState',
payload: {
gettingErpVerifyCoding: false,
},
});
newCounting = true;
yield put({
type: 'updateState',
payload: {
erpCounting: newCounting,
},
});
const setTimer = setInterval(() => {
newCountdowm--;
if (newCountdowm <= 0) {
newCountdowm = 60;
newCounting = false;
clearInterval(setTimer);
}
payload.dispatch({
type: 'studentsinfo/updateState',
payload: {
erpCountdown: newCountdowm,
erpCounting: newCounting,
erptimer: setTimer,
},
});
}, 1000);
} else {
setTimeout(verifycodehide);
yield put({
type: 'updateState',
payload: {
gettingErpVerifyCoding: false,
erpCounting: false,
erpCountdown: 60,
},
});
yield put({
type: 'webapp/errorrequestresolve',
payload: {
data,
},
});
}
},
* clearCountInterval({ payload }, { call, put, select }) {
const { erptimer } = yield select(state => state.studentsinfo);
clearInterval(erptimer);
yield put({
type: 'updateState',
payload: {
erptimer: null,
gettingErpVerifyCoding: false,
erpCounting: false,
erpCountdown: 60,
},
});
},
* unbindWxPost({ payload }, { call, put, select }) {
const { studentsdetail, checkoutVerifyCode } = yield select(state => state.studentsinfo);
const { verify_code, callBack, student_id } = payload;
if (checkoutVerifyCode) {
return;
}
yield put({
type: 'updateState',
payload: {
checkoutVerifyCode: true,
},
});
const unbindWxData = yield call(studentsAjax.studentsUnBindWx, {
student_id,
code: verify_code,
});
yield put({
type: 'updateState',
payload: {
checkoutVerifyCode: false,
},
});
if (unbindWxData.code == 200) {
message.success('解绑成功', 1);
studentsdetail.consumer_id = 0;
yield put({
type: 'updateState',
payload: {
bindWxShow: false,
studentsdetail: {
...studentsdetail,
},
},
});
yield put({
type: 'clearCountInterval',
});
} else {
yield put({
type: 'webapp/errorrequestresolve',
payload: {
data: unbindWxData,
},
});
}
},
* pageInit({ payload }, { call, put, select }) {
yield put({
type: 'updateState',
......@@ -552,6 +686,11 @@ export default {
changeOperatorShow: false,
teacherList: [],
datetime: '',
bindWxShow: false,
gettingErpVerifyCoding: false,
erpCountdown: 60,
erpCounting: false,
erptimer: null,
},
});
},
......
import React from 'react';
import { connect } from 'dva';
import { Row, Col, Modal, Form, Input, Button, message } from 'antd';
import pageStyles from './BindWx.less';
import Cropper from '../../components/Cropper';
import { pageIn, imagify } from '../../utils/index';
const { Search } = Input;
const FormItem = Form.Item;
class UserSettingForm extends React.Component {
constructor(props) {
super(props);
this.state = {
};
}
componentDidMount() {
}
componentWillUnmount() {
const { dispatch } = this.props;
}
sureBindWx = () => {
const { form, bindWxPost } = this.props;
form.validateFields((err, values) => {
if (!err) {
bindWxPost(values, () => {
form.resetFields();
});
}
});
}
onCancel = () => {
const { form, onCancel } = this.props;
form.resetFields();
onCancel(false);
}
render() {
const {
visible,
userInfo,
erpCounting,
erpCountdown,
sendVerifyCode,
onCancel,
previewQrcodeShow,
previewQrcode,
closeQrcodeShow,
checkoutVerifyCode,
} = this.props;
const { getFieldDecorator } = this.props.form;
return (
<div>
<Modal
visible={visible}
title="绑定微信"
okText={checkoutVerifyCode ? '提交中...' : '提交'}
cancelText="关闭"
zIndex={110}
onOk={this.sureBindWx}
onCancel={this.onCancel}
maskClosable={false}
confirmLoading={checkoutVerifyCode}
width="540px"
>
<div style={{ width: 300, margin: '0 auto 20px', fontSize: '14px' }}>身份验证: 验证码将发送到超级管理员绑定的手机号({userInfo.mobile}),请注意查收</div>
<div style={{ width: 300, margin: '0 auto' }}>
<Form className="modalform" labelAlign="left">
<Form.Item>
<Row gutter={8}>
<Col span={15}>
{getFieldDecorator('verify_code', {
rules: [
{ required: true, message: '请输入四位数字验证码' },
{ pattern: /^[0-9]{4}$/, message: '验证码是4位数字验证码' },
],
})(<Input type="text" maxLength={4} placeholder="请输入验证码" />)}
</Col>
<Col span={9} style={{ color: '#1890FF', cursor: 'pointer', fontSize: '14px' }}>
<div className={`${pageStyles.verycodebtn} ${erpCounting ? pageStyles.verycodebtndisable : ''}`} onClick={sendVerifyCode}>{erpCounting ? `${erpCountdown}秒后重新获取` : '发送验证码'}</div>
</Col>
</Row>
</Form.Item>
</Form>
</div>
</Modal>
</div>
);
}
}
UserSettingForm.propTypes = {
};
const UserSetting = Form.create()(UserSettingForm);
function mapStateToProps(state) {
const {
cropperboxShow,
uploadImgUrl,
avatorUploader,
} = state.uploader;
const {
counting,
countdown,
gettingVerifyCoding,
resetPsdDiaShow,
resetPsdSubmitting,
bindWxShow,
} = state.usersetting;
return {
cropperboxShow,
resetPsdDiaShow,
uploadImgUrl,
avatorUploader,
gettingVerifyCoding,
counting,
countdown,
resetPsdSubmitting,
bindWxShow,
};
}
export default connect(mapStateToProps)(UserSetting);
@import '../../less/variables.less';
.container {
min-height: 100vh;
background-color: #F0F2F5;
}
.header {
background-color: #fff;
color: #000000;
font-size: 14px;
padding-left: 32px;
line-height: 64px;
}
.content {
padding: 23px 25px 33px;
}
.settingbox {
background-color: #fff;
border-radius: 2px;
min-height: 800px;
}
.titlebox {
line-height: 55px;
border-bottom: 1px solid #E9E9E9;
padding-left: 32px;
padding-right: 23px;
line-height: 54px;
color: #000;
font-weight: 600;
font-size: 16px;
margin-bottom: 50px;
display: flex;
justify-content: space-between;
align-items: center;
}
.settingcontent {
padding: 0 32px 20px;
}
.avatarbox {
text-align: center;
margin-bottom: 37px;
}
.avatar {
display: block;
width: 86px;
height: 86px;
border-radius: 50%;
margin: 0 auto 16px;
}
.uploadbtn {
display: inline-block;
cursor: pointer;
margin: 0 auto;
color: #1890FF;
font-size: 16px;
line-height: 1;
position: relative;
cursor: pointer;
}
.infoline {
text-align: center;
display: flex;
align-items: center;
justify-content: center;
margin-bottom: 20px;
}
.infooperate {
width: 60px;
text-align: right;
color: #108EE9;
font-size: 14px;
cursor: pointer;
}
.infodetail {
text-align: left;
width: 237px;
font-size: 14px;
color: #000;
}
.fileuploadinput {
position: absolute;
width: 100%;
height: 100%;
left: 0;
top: 0;
z-index: 1;
opacity: 0;
}
@media (max-width: 768px){
.content {
padding: 23px 8px 33px;
}
.userinfo {
padding: 32px 8px 32px;
}
.titlebox {
padding-left: 8px;
padding-right: 8px;
}
.schoollist {
padding: 0 8px 20px;
}
}
\ No newline at end of file
......@@ -8,7 +8,9 @@ import StudentEdit from './StudentEdit';
import ChangeCourse from './ChangeCourse';
import OperatorChange from '../../components/operatorChange';
import Cropper from '../../components/Cropper';
import BindWx from './BindWx';
import Renew from './Renew';
// import { studentsDetail } from '../../services/students';
const { confirm } = Modal;
const { Option } = Select;
const { TextArea } = Input;
......@@ -394,6 +396,57 @@ class StudentMgt extends React.Component {
},
});
}
unbindWx = () => {
const { dispatch } = this.props;
dispatch({
type: 'studentsinfo/updateState',
payload: {
bindWxShow: true,
},
});
}
BindWxDiaVisible = () => {
const { dispatch } = this.props;
dispatch({
type: 'studentsinfo/clearCountInterval',
});
dispatch({
type: 'studentsinfo/updateState',
payload: {
bindWxShow: false,
},
});
}
sendBindWxVerifyCode = () => {
const {
dispatch,
erpCounting,
gettingErpVerifyCoding,
studentsdetail,
} = this.props;
if (gettingErpVerifyCoding || erpCounting) {
return;
}
dispatch({
type: 'studentsinfo/sendErpVerifyCode',
payload: {
sms_type: 4,
mobile: studentsdetail.mobile,
dispatch,
},
});
}
unbindWxPost = (values, callBack) => {
const { dispatch, studentsdetail } = this.props;
dispatch({
type: 'studentsinfo/unbindWxPost',
payload: {
verify_code: values.verify_code,
callBack,
student_id: studentsdetail.id,
},
});
}
render() {
const {
studentsdetail,
......@@ -426,6 +479,10 @@ class StudentMgt extends React.Component {
uploadImgUrl,
avatorUploader,
studentAvator,
bindWxShow,
checkoutVerifyCode,
erpCountdown,
erpCounting,
} = this.props;
const { getFieldDecorator } = this.props.form;
const { logCourseId } = this.state;
......@@ -680,7 +737,7 @@ class StudentMgt extends React.Component {
<Col xs={{ span: 12 }} sm={{ span: 19 }} lg={{ span: 19 }} xl={{ span: 16 }} xxl={{ span: 12 }}>
<Descriptions>
<Descriptions.Item label="姓名" className={pageStyle.item}>{studentsdetail.name}</Descriptions.Item>
<Descriptions.Item label="微信绑定" className={pageStyle.item}>{studentsdetail.consumer_id == 0 ? '未绑定' : '已绑定'}</Descriptions.Item>
<Descriptions.Item label="微信绑定" className={pageStyle.item}>{studentsdetail.consumer_id == 0 ? '未绑定' : <div><span>已绑定</span><a href="javascript:;" onClick={this.unbindWx} style={{ paddingLeft: '10px' }}>解除绑定</a></div>}</Descriptions.Item>
<Descriptions.Item label="备用电话" className={pageStyle.item}>{studentsdetail.reserve_mobile}</Descriptions.Item>
</Descriptions>
<Descriptions>
......@@ -866,6 +923,16 @@ class StudentMgt extends React.Component {
changeToTargetCourse={this.changeToTargetCourse}
classList={courseRelateClassList}
/>
<BindWx
visible={bindWxShow}
userInfo={studentsdetail}
erpCounting={erpCounting}
erpCountdown={erpCountdown}
sendVerifyCode={this.sendBindWxVerifyCode}
onCancel={() => this.BindWxDiaVisible(false)}
bindWxPost={this.unbindWxPost}
checkoutVerifyCode={checkoutVerifyCode}
/>
</div>
);
}
......@@ -903,6 +970,10 @@ function mapStateToProps(state) {
teacherList,
datetime,
studentAvator,
bindWxShow,
checkoutVerifyCode,
erpCountdown,
erpCounting,
} = state.studentsinfo;
const {
courseList,
......@@ -947,6 +1018,10 @@ function mapStateToProps(state) {
uploadImgUrl,
avatorUploader,
studentAvator,
bindWxShow,
checkoutVerifyCode,
erpCountdown,
erpCounting,
};
}
export default connect(mapStateToProps)(ForgotPassword);
......
......@@ -166,13 +166,6 @@ class UserSettingForm extends React.Component {
mobile: userInfo.mobile,
},
});
// dispatch({
// type: 'usersetting/createQrcode',
// payload: {
// mobile: userInfo.mobile,
// callBack,
// },
// });
}
closeQrcodeShow = () => {
const { dispatch } = this.props;
......
......@@ -65,3 +65,11 @@ export function studentsChoiceClass(params) {
data,
});
}
export function studentsUnBindWx(params) {
const data = qs.stringify(params);
return request({
url: `${api.students.studentsUnBindWx}`,
method: 'POST',
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