Commit 90871162 by FE

bargain bind phone modify

parent a0ea8a63
import React, { Component } from 'react';
import ReactDOM from 'react-dom';
import classnames from 'classnames';
import './index.scss';
const Root = document.querySelector('body');
const events = ['touchmove', 'mousewheel'];
class Mask extends Component {
constructor(props) {
super(props);
if(!this.el) {
this.el = document.createElement('div');
}
}
componentDidMount() {
events.forEach(item => {
this.el.addEventListener(item, this.preventEvent, {
passive: false
})
})
Root.appendChild(this.el);
}
componentWillUnmount() {
Root.removeChild(this.el);
}
preventEvent = e => {
e.preventDefault();
}
render() {
const { visible, handleToHide, className } = this.props;
if(visible) {
return ReactDOM.createPortal(
(
<div className="mask">
<div className={classnames("mask-content", className)}>
{this.props.children}
</div>
<div className="mask-footer">
<i className="mask-button__close" onClick={handleToHide}></i>
</div>
</div>
),
this.el
);
}else {
return null;
}
}
}
export default Mask;
\ No newline at end of file
.mask {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
color:#fff;
background-color: rgba(0, 0, 0, .5);
z-index: 999;
}
.mask-content {
min-width: 200px;
min-height: 100px;
padding: 10px 0;
border-radius: 5px;
box-sizing: border-box;
background-color: #fff;
}
.mask-footer {
margin-top: 33px;
}
.mask-button__close {
display: inline-block;
width: 33px;
height: 33px;
background-size: cover;
background-image: url('https://julyedu-cdn.oss-cn-beijing.aliyuncs.com/newyear20/H5/close-btn.png');
}
\ No newline at end of file
......@@ -372,12 +372,7 @@
}
.artifact-box, .use-artifact-box {
padding: 20px 0;
background-color: $bg_fff;
border-radius: 3px;
text-align: center;
margin: 200px auto 20px auto;
position: relative;
.top-img {
position: absolute;
......
......@@ -23,7 +23,6 @@ class BargainInfo extends Component {
}
handleChange = e => {
let {name, value} = e.target
this.setState({
......
import React, { Component } from 'react';
import { Toast } from 'antd-mobile';
import { http } from '@/utils';
import './confirm.scss';
class BargainConfirmBind extends Component {
farmatKey = (key) => {
let data = null;
switch (key) {
case 1:
data = {
key: 'email',
type: 'email'
};
break;
case 2:
data = {
key: 'wechat_nickname',
type: 'wechat'
};
break;
case 3:
data = {
key: 'qq_nickname',
type: 'qq'
};
break;
case 4:
data = {
key: 'sina_nickname',
type: 'sina'
};
break;
default:
data = null;
break;
}
return data;
}
confirmBindPhone = () => {
const { data, handleToBargain } = this.props;
// is_valid 是否验证 1:验证(默认),0不验证
http.post(
`${API['passport-api']}/m/personal/bindPhone`,
{
...data,
type: 1,
is_valid: 0
}
).then(res => {
const { errno, msg } = res.data;
if(errno === 200) {
handleToBargain();
}else {
Toast.info(msg);
}
});
}
render() {
const { bindInfo, handleToHide } = this.props;
return (
<div className="bargain-bind-confirm">
<h4 className="bargain-bind-confirm__title">绑定确认</h4>
<p className="bargain-bind-confirm__desc">该手机号已绑定到以下账号,继续绑定将解除以下绑定状态</p>
<ul className="bargain-bind-confirm__list">
{
bindInfo && [1,2,3,4].map(item => {
const data = this.farmatKey(item);
if(bindInfo[data.key]) {
return (
<li className="bargain-bind-confirm__account" key={item}>
<i className="bargain-bind-confirm__icon" data-plat={data.type}></i>
<p className="bargain-bind-confirm__name">{bindInfo[data.key]}</p>
</li>
);
}
return null;
})
}
</ul>
<div className="bargain-bind-confirm__footer">
<button
className="bargain-bind-confirm__button"
data-type="cancle"
onClick={handleToHide}
>取消</button>
<button
className="bargain-bind-confirm__button"
data-type="confirm"
onClick={this.confirmBindPhone}
>继续绑定</button>
</div>
</div>
)
}
}
export default BargainConfirmBind;
\ No newline at end of file
.bargain-bind-confirm {
width: 290px;
padding-top: 10px;
padding-bottom: 8px;
}
.bargain-bind-confirm__title {
margin: 0 0 12px;
font-size: 15px;
color: #333;
text-align: center;
line-height: 1;
}
.bargain-bind-confirm__desc {
margin: 0;
padding: 0 20px;
font-size: 12px;
color: #666;
}
.bargain-bind-confirm__list {
padding: 0 0 10px;
}
.bargain-bind-confirm__account {
display: flex;
align-items: center;
height: 30px;
margin: 0 52px;
padding: 0 4px;
text-align: left;
&:nth-child(n+2) {
border-top: 1px solid #E5E5E5;
}
}
.bargain-bind-confirm__icon {
display: inline-block;
width: 22px;
height: 22px;
background-size: 100% auto;
background-repeat: no-repeat;
background-position: center;
&[data-plat="email"] {
background-image: url('https://julyedu-cdn.oss-cn-beijing.aliyuncs.com/newyear20/H5/icon-mail.png');
}
&[data-plat="sina"] {
background-image: url('https://julyedu-cdn.oss-cn-beijing.aliyuncs.com/newyear20/H5/icon-sina.png');
}
&[data-plat="qq"] {
background-image: url('https://julyedu-cdn.oss-cn-beijing.aliyuncs.com/newyear20/H5/icon-qq.png');
}
&[data-plat="wechat"] {
background-image: url('https://julyedu-cdn.oss-cn-beijing.aliyuncs.com/newyear20/H5/icon-wechat.png');
}
}
.bargain-bind-confirm__name {
margin: 0;
padding-left: 7px;
font-size: 12px;
color: #999;
}
.bargain-bind-confirm__footer {
display: flex;
align-items: center;
justify-content: space-between;
padding: 0 28px;
}
.bargain-bind-confirm__button {
width: 105px;
height: 30px;
box-sizing: border-box;
border-radius: 15px;
font-size: 14px;
cursor: pointer;
outline: none;
&[data-type="cancle"] {
border: 1px solid #0099FF;
color: #0099FF;
background-color: transparent;
}
&[data-type="confirm"] {
border-style: none;
color: #fff;
background-color: #0099FF;
}
}
\ No newline at end of file
import React, { Component } from 'react';
import classnames from 'classnames';
import { Link } from 'react-router-dom';
import { Formik, Form, Field } from 'formik';
import { Toast } from 'antd-mobile';
import { http, getParam } from '@/utils';
import './index.scss';
class BargainBindPhone extends Component {
constructor(props) {
super(props);
this.state = {
mobile: '',
code: '',
num: '86',
seconds: 60,
isTimer: false, // 是否开始倒计时
};
}
// 获取短信验证码
handleToSendCode = ({ mobile }) => {
const { country: { num = 86 } } = this.props;
let { isTimer, seconds } = this.state;
if(!isTimer) {
if(!/^\d+$/.test(mobile)){
Toast.info('请输入正确的手机号');
return;
}
// 获取验证码
http.post(
`${API['passport-api']}/m/personal/bindPhoneSendCode`,
{
area_code: `00${num}`,
phone_num: mobile
}
).then(res => {
const { errno, msg } = res.data;
if(errno === 200) {
Toast.info('验证码发送成功', 2, null, false);
// 倒计时
this.timer = window.setInterval(() => {
if (seconds <= 0) {
window.clearInterval(this.timer);
this.setState({
isTimer: false,
seconds: 60
});
}else {
this.setState({
isTimer: true,
seconds: --seconds
});
}
}, 1000);
}else {
Toast.info(msg);
}
});
}
}
// 绑定手机号
handleToBindPhone = ({code, mobile}) => {
const { country: { num = 86}, handleToBargain, confirmBindPhone } = this.props;
if (!mobile) {
Toast.info('请填手机号码');
return;
}
if (!code) {
Toast.info('请填写验证码');
return;
}
const params = {
area_code: `00${num}`,
phone_num: mobile,
code: code,
};
// is_valid 是否验证 1:验证(默认),0不验证
http.post(
`${API['passport-api']}/m/personal/bindPhone`,
{
...params,
type: 1,
is_valid: 1
}
).then(res => {
const { errno, data, msg } = res.data;
if(errno === 200) {
if(data.tip_info) {
confirmBindPhone(params, data.tip_info);
}else {
handleToBargain();
}
}else {
Toast.info(msg);
}
});
}
render() {
const { country: { num = '86' } } = this.props;
const { isTimer, seconds } = this.state;
return (
<Formik
initialValues={{
mobile: '',
code: ''
}}
validate={({mobile, code}) => {
const errors = {};
if(!/^\d+$/.test(mobile)) {
errors.mobile = '请填写正确格式的手机号';
}
if (!/[0-9]{6}/.test(code)) {
errors.code = '请输入验证码';
}
return errors;
}}
onSubmit={(values, { setStatus, setSubmitting }) => {
this.handleToBindPhone(values);
}}
render={({values: {mobile, code}, errors}) => (
<Form className="bargain-bind-phone">
<h2 className="bargain-bind-phone__title">绑定手机,先砍一刀</h2>
<div className="bargain-bind-phone__item">
<Link
className="bargain-bind-phone__button--num"
to={`/country?id=${getParam('id')}&from=bargain`}
>
+{num}
<i className="iconfont iconiconfront-69"></i>
</Link>
<Field
name="mobile"
render={({field}) => (
<input
{...field}
className="bargain-bind-phone__ipt"
type="tel"
placeholder='手机号'
maxLength={11}
/>
)}
/>
</div>
<div className="bargain-bind-phone__item">
<Field
name="code"
render={({field}) => (
<input
{...field}
type="tel"
placeholder='验证码'
maxLength={6}
/>
)}
/>
{errors.mobile}
<button
type="button"
className={classnames(
'bargain-bind-phone__button--send',
{
'active': mobile && errors.mobile === undefined
}
)}
disabled={!(mobile && errors.mobile === undefined)}
onClick={() => this.handleToSendCode({mobile})}
>
{isTimer? `重新发送${seconds}s` : '发送验证码'}
</button>
</div>
<button
type="submit"
className="bargain-bind-phone__button--bargain"
disabled={!(mobile && code && JSON.stringify(errors) === '{}')}
>先砍一刀</button>
</Form>
)}
/>
)
}
}
export default BargainBindPhone;
\ No newline at end of file
.bargain-bind-phone {
padding: 10px 20px;
}
.bargain-bind-phone__title {
margin: 0 0 12px;
font-size: 15px;
color: #333;
font-weight: normal;
text-align: center;
line-height: 1;
}
.bargain-bind-phone__item {
display: flex;
align-items: center;
width: 100%;
height: 30px;
margin-top: 15px;
border: 1px solid #ddd;
box-sizing: border-box;
input {
width: 100%;
padding-left: 10px;
border-style: none;
outline: 0;
-webkit-appearance: none;
&::-webkit-input-placeholder {
color: $color_999;
}
&.bargain-bind-phone__ipt {
border-left: 1px solid #ddd;
}
}
}
.bargain-bind-phone__button--num {
display: inline-flex;
align-items: center;
padding: 0 5px;
color: $color_999;
}
.bargain-bind-phone__button--send {
width: 136px;
border-style: none;
font-size: 13px;
color: $active;
text-align: right;
background-color: transparent;
cursor: pointer;
outline: none;
&:disabled {
color: $color_999;
}
}
.bargain-bind-phone__button--bargain {
display: block;
width: 100%;
height: 30px;
margin-top: 20px;
border-style: none;
font-size: 15px;
color: #FF4000;
line-height: 30px;
text-align: center;
background-color: #FADD29;
outline: none;
-webkit-appearance: none;
&:disabled {
color: $white;
background-color: $bg_999;
}
}
\ No newline at end of file
......@@ -6,7 +6,9 @@ import { getCourses } from "@/components/detail/actions"
import { connect } from "react-redux"
import './index.scss'
import Overlay from '../overlay'
import BindPhone from './../bindPhone/index';
import BargainConfirmBind from './../bindPhone/confirm';
import Mask from '@/common/Mask/index';
class BtnStatus extends Component {
constructor(props) {
......@@ -17,9 +19,12 @@ class BtnStatus extends Component {
group_status: 3,
in_cart: false,
countdown: 0,
barInfo: {}
barInfo: {},
bindPhone: false,
bindConfrm: false,
bindInfo: {}, // 冲突信息
formInfo: {},
}
}
componentDidMount() {
......@@ -77,6 +82,7 @@ class BtnStatus extends Component {
// }
// })
// };
// 返现课程的立即购买
signUpNow = () => {
if(this.props.user.hasError) {
......@@ -93,6 +99,7 @@ class BtnStatus extends Component {
})
}
};
// 普通课程的立即报名 要模拟结算过程
simpleCourse = () => {
if(this.props.user.hasError) {
......@@ -108,11 +115,13 @@ class BtnStatus extends Component {
})
}
};
// 格式化开课时间
formatDate = (date) => {
let ary = date.split('-');
return `${ary[1]}${ary[2]}日开课`;
};
// 直接购买
tobuy = () => {
const {user} = this.props;
......@@ -134,6 +143,7 @@ class BtnStatus extends Component {
}
}
};
// 一键开团
keyToGroup = () => {
if(this.props.user.hasError) {
......@@ -143,6 +153,7 @@ class BtnStatus extends Component {
}
this.props.history.push(`/order?id=${getParam('id')}`, {group: 1})
};
// 砍完价去支付
bargainToOrder = () => {
if(this.props.user.hasError) {
......@@ -184,6 +195,7 @@ class BtnStatus extends Component {
}
})
}
close = () => {
this.setState({
isShowOverlay: false,
......@@ -206,7 +218,14 @@ class BtnStatus extends Component {
http.post(`${API.home}/m/bargain/toBargain`, data).then((res) => {
const {data, code, msg} = res.data;
if (code === 200) {
history.push(`/bargain-middle-page?id=${course_id}&bargaincode=${data.bargain_code}&is_originator=1`)
// user_status 用户状态 1-关注公众号,2-绑定手机号 3-再砍一刀 (是发起人没有这个字段)
if(data.user_status === 2) {
this.setState({
bindPhone: true
})
}else {
history.push(`/bargain-middle-page?id=${course_id}&bargaincode=${data.bargain_code}&is_originator=1`)
}
} else {
Toast.info(msg, 2)
}
......@@ -224,7 +243,6 @@ class BtnStatus extends Component {
}
}
//获取砍价信息
getBargainInfo = () => {
const {user} = this.props
......@@ -278,13 +296,58 @@ class BtnStatus extends Component {
}
}
// 隐藏弹窗
handleToHide = (key) => {
console.log(key);
this.setState({
[key]: false
});
}
// 绑定手机号 -- 确认
confirmBindPhone = (params, bindInfo) => {
this.setState({
bindPhone: false,
bindConfrm: true,
formInfo: params,
bindInfo
});
}
render() {
// data 课程信息;barInfo 砍价信息
const { user = {}, toCart } = this.props;
const { countdown ,barInfo, courseInfo: info = {}} = this.state;
const { user = {}, toCart, country } = this.props;
const {
countdown,
barInfo,
courseInfo: info = {},
bindPhone,
bindConfrm,
bindInfo,
formInfo,
} = this.state;
const uid = user.data && user.data.uid;
return (
<div>
{/* 绑定手机号 */}
<Mask visible={bindPhone} handleToHide={() => this.handleToHide('bindPhone')}>
<BindPhone
country={country}
handleToBargain={this.toKanjia}
confirmBindPhone={this.confirmBindPhone}
/>
</Mask>
{/* 绑定手机号--确认 */}
<Mask visible={bindConfrm} handleToHide={() => this.handleToHide('bindConfrm')}>
<BargainConfirmBind
data={formInfo}
bindInfo={bindInfo}
handleToHide={() => this.handleToHide('bindConfrm')}
handleToBargain={this.toKanjia}
/>
</Mask>
{/*正常购买*/}
{
info.is_baoming === 0 && info.group_status !== 3 &&
......@@ -320,8 +383,6 @@ class BtnStatus extends Component {
</div>
}
{/*已购买*/}
{
info.is_baoming === 1 &&
......
......@@ -485,7 +485,6 @@ class Detail extends Component {
singleType: 1
})
this.props.history.push(`/detail?id=${getParam('id')}`);
}
render() {
......@@ -735,6 +734,7 @@ class Detail extends Component {
{
course_info &&
<BtnStatus
country={this.props.country}
countdown={countdown}
data={course_info}
user={this.props.user}
......
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