react-app-shell
Version:
react打包脚本和example, 这里的版本请忽略
287 lines (251 loc) • 10.4 kB
JavaScript
import React, {PureComponent} from 'react';
import {withRouter} from 'react-router-dom';
import {Button} from 'antd-mobile';
import queryString from 'query-string';
import {checkUserAuth, DocumentTitle, ModalLogin, WechatConfig} from '../../components';
import {message, monitor, tools, localStore} from '../../utils';
import {orderService, authService} from '../../service';
import {appConfig, shareConfig} from '../../config';
import {AccountsType} from '../../constants';
import registrationSrc from '../../public/images/product/registration.jpg';
import sourseSrc from '../../public/images/product/course.png';
import detail_1 from '../../public/images/product/detail_1.jpg';
import detail_2 from '../../public/images/product/detail_2.jpg';
import detail_3 from '../../public/images/product/detail_3.jpg';
import detail_4 from '../../public/images/product/detail_4.jpg';
import detail_5 from '../../public/images/product/detail_5.jpg';
import detail_6 from '../../public/images/product/detail_6.jpg';
import detail_7 from '../../public/images/product/detail_7.jpg';
import detail_8_199 from '../../public/images/product/detail_8_199.jpg';
import detail_8_99 from '../../public/images/product/detail_8_99.jpg';
import detail_9 from '../../public/images/product/detail_9.jpg';
import detail_10 from '../../public/images/product/detail_10.jpg';
import detail_11 from '../../public/images/product/detail_11.jpg';
import styles from './course.less';
// 约课地址
const bookingUrl = appConfig.resources.bookingUrl;
// 分享配置
const shareOptions = shareConfig.course;
/**
* 微信朋友圈推广的课程页/商品页
*/
({
account: AccountsType.MAIN,
support: 'all'
}) // 微信授权--魔力耳朵公众号
class Course extends PureComponent {
constructor(props) {
super(props);
this.urlParams = queryString.parse(window.location.search);
// 路由参数 productId
const productId = this.props.match.params.productId;
this.state = {
productId, // 商品id
productInfo: {},
errorCourse: false, // 标记课程是否获取错误
wrapperState: true,
modalKey: '',
};
// 简单节流
this.throttleHandleBuy = tools.throttle(this.handleBuy, 1500);
}
componentDidMount() {
this.loadData();
window.addEventListener('scroll', this.watchHeadScroll, false);
}
componentWillUnmount() {
window.removeEventListener('scroll', this.watchHeadScroll, false);
}
loadData = () => {
const {productId} = this.state;
message.showLoading();
orderService.getProduct(productId)
.then(productInfo => {
this.setState({
productInfo
});
message.closeLoading();
})
.catch(error => {
this.setState({
errorCourse: true,
});
message.error(error && error.msg || '获取商品信息失败!');
});
};
/**
* 立即购买
*/
handleBuy = async () => {
const {productId} = this.state;
monitor.log('', 'course >> 点击立即购买');
// 如果微信H5环境
if (tools.isWeiXin()) {
const isLogin = await authService.checkLogin();
if (!isLogin) {
this.setState({
modalKey: 'Login',
});
return;
}
} else {
// 如果普通浏览器环境
const token = localStore.getToken();
// 未登录的需要先登录
if (!token) {
this.setState({
modalKey: 'Login',
});
return;
}
}
message.showLoading();
// 创建订单, 并跳转到订单页面
orderService.createOrder(productId)
.then(orderNo => {
message.closeLoading();
monitor.log('', `course >> 提交订单成功, 订单号: ${orderNo}`);
const url = `${appConfig.domain.mobileDomain}/pay/order_info?channel=wechat&type=WechatMP&order_no=${orderNo}&callback_url=${bookingUrl}`;
window.location.href = url;
})
.catch(({code, msg}) => {
message.closeLoading();
// 如果用户未登录或者登录失效, 需要重新登录
if (code && code === 'LOGIN_REQUIRED') {
monitor.log('', 'course >> 登录状态过期, 需要重新登录');
this.setState({
modalKey: 'Login',
});
return;
}
monitor.log('', `course >> 创建订单失败, ${msg}`);
message.error(msg || '发生错误! 购买失败');
});
};
/**
* 登录/注册成功的回调
*/
handleLoginCallback = () => {
this.setState({
modalKey: '',
});
// 登录成功之后, 提交订单
this.handleBuy();
};
/**
* 关闭modal
*/
handleHideModal = () => {
this.setState({
modalKey: '',
});
};
watchHeadScroll = () => {
let wrapper = this.refs.wrapperTables;
let scrollTop = window.pageYOffset || document.documentElement.scrollTop || document.body.scrollTop || 0;
let num = Math.floor(wrapper.offsetTop - scrollTop);
let head = document.getElementById('wrapper_header');
if (num < 1) {
if (head.classList.contains('hears-bar-wrap-fixed')) {
return false;
}
head.classList.add('hears-bar-wrap-fixed');
} else {
if (head.classList.contains('hears-bar-wrap-fixed')) {
head.classList.remove('hears-bar-wrap-fixed');
}
}
};
slideWrapper = (value) => {
this.setState({
wrapperState: value,
});
};
headBox(value) {
if (value) {
return styles['course-header-box'] + ' ' + styles['course-header-active'];
} else {
return styles['course-header-box'];
}
}
renderModal = () => {
const {modalKey} = this.state;
switch (modalKey) {
case 'Login':
return (
<ModalLogin
onOk={this.handleLoginCallback}
onCancel={this.handleHideModal}
></ModalLogin>
);
}
};
render() {
const {productInfo, errorCourse, wrapperState} = this.state;
let pictureName = [detail_1, detail_2, detail_3, detail_4, detail_5, detail_6, detail_7];
shareOptions.title = `${productInfo.price}元抢三节精品北美外教小班课!仅限60名!`;
if (productInfo.price === 19.9) {
pictureName.push(detail_8_199);
} else {
pictureName.push(detail_8_99);
}
pictureName = pictureName.concat([detail_9, detail_10, detail_11]);
const courseIntroduce = pictureName.map(function (value, index) {
return <img key={index} src={value} alt="课程介绍"/>;
});
const wrapperTransform = this.state.wrapperState ? styles['course-wrapper-box'] : styles['course-wrapper-transform'] + ' ' + styles['course-wrapper-box'];
return (
<div className={styles['course-wrapper']}>
<DocumentTitle title="魔力耳朵少儿英语"/>
<header className={styles['header']}>
<img src={sourseSrc} alt="北美精品外教课 - 魔力耳朵"/>
<div className={styles['title']}>
<h1>{productInfo.name ? productInfo.name : ''}</h1>
<div className={styles['price']}>
<i>¥</i>{productInfo.price ? productInfo.price : ''}
</div>
<p>让孩子主动开口说英语 (15天有效期) <span
className={styles['origin-price']}>原价: {productInfo.originPrice ? productInfo.originPrice : ''}元
</span></p>
</div>
</header>
<div className={styles['empty']}>
</div>
<div className={styles['course-wrapper-table']} ref="wrapperTables">
<div className={styles['wrapper-headers']}>
<div className={styles['course-wrapper-header']} id="wrapper_header">
<div
className={this.headBox(wrapperState)}
onClick={this.slideWrapper.bind(null, true)}>课程介绍
</div>
<div
className={this.headBox(!wrapperState)}
onClick={this.slideWrapper.bind(null, false)}>报名须知
</div>
</div>
</div>
<div className={styles['course-wrapper-content']}>
<div className={wrapperTransform}>
<div className={styles['course-content-left'] + ' ' + styles['image-none']}>
{courseIntroduce}
</div>
<div className={styles['course-content-right']}>
<img src={registrationSrc} alt="报名须知"/>
</div>
</div>
</div>
</div>
<footer className={styles['course-buy']}>
<div className={styles['price']}><span>新生团购价 ¥</span>{productInfo.price}</div>
<Button
disabled={errorCourse} className={styles['button-buy']}
onClick={this.throttleHandleBuy}>立即购买</Button>
</footer>
{this.renderModal()}
<WechatConfig showShare={true} shareOptions={shareOptions}></WechatConfig>
</div>
);
}
}
export default Course;