Commit a05b6b7e by wangshuo

Merge branch '00' into dev

parents a78c5271 96625758
...@@ -7,11 +7,12 @@ import { http, getParam } from '@/utils'; ...@@ -7,11 +7,12 @@ import { http, getParam } from '@/utils';
import './index.scss'; import './index.scss';
class BindPhone extends Component { class BindPhone extends Component {
captchaInstance = null;
constructor(props) { constructor(props) {
super(props), super(props),
this.state = { this.state = {
validate: '', validate: '',
captchaInstance: null,
seconds: 60, seconds: 60,
isFirst: true, isFirst: true,
timer: null, timer: null,
...@@ -24,12 +25,27 @@ class BindPhone extends Component { ...@@ -24,12 +25,27 @@ class BindPhone extends Component {
} }
} }
getCaptchaInstance = instance => { componentDidMount() {
this.initCountryInfo();
}
initCountryInfo = () => {
const { country } = this.props;
this.setState({ this.setState({
captchaInstance: instance country
}); });
} }
toFetchCountryNum = () => {
const { history, hideBindPhone } = this.props;
hideBindPhone();
history.push('/country');
}
getCaptchaInstance = instance => {
this.captchaInstance = instance;
}
onVerify = (err, data) => { onVerify = (err, data) => {
if (err) { if (err) {
console.log(err); console.log(err);
...@@ -40,12 +56,13 @@ class BindPhone extends Component { ...@@ -40,12 +56,13 @@ class BindPhone extends Component {
} }
} }
// 获取手机号验证码
handleToSend = ({tel, code}) => { handleToSend = ({tel, code}) => {
let { validate, seconds, isFirst, isTimer, captchaInstance, country: {num = '86'} } = this.state; let { validate, seconds, isFirst, isTimer, country: {num = '86'} } = this.state;
if(validate) { if(validate) {
if (!isFirst) { if (!isFirst) {
Toast.info('请重新进行滑块验证', 2, null, false); Toast.info('请重新进行滑块验证', 2, null, false);
captchaInstance.refresh(); this.captchaInstance.refresh();
this.setState({ this.setState({
isFirst: true isFirst: true
}); });
...@@ -55,7 +72,6 @@ class BindPhone extends Component { ...@@ -55,7 +72,6 @@ class BindPhone extends Component {
if (!tel) { if (!tel) {
Toast.info('手机号码不能为空', 2, null, false); Toast.info('手机号码不能为空', 2, null, false);
}else if(!/^\d+$/.test(tel)) { }else if(!/^\d+$/.test(tel)) {
// }else if (!validateTel(tel)) {
Toast.info('请输入正确格式的手机号码', 2, null, false); Toast.info('请输入正确格式的手机号码', 2, null, false);
}else { }else {
...@@ -102,32 +118,29 @@ class BindPhone extends Component { ...@@ -102,32 +118,29 @@ class BindPhone extends Component {
} }
// 绑定手机 // 绑定手机
toContinueBind = (isValid = 1) => { toBindPhone = () => {
const { accountInfo: { tel, code}, country: {num = '86'} } = this.state; const { accountInfo: { tel, code }, country: {num = '86'} } = this.state;
// is_valid 是否验证 1:验证(默认),0不验证 const { handleToConfirmPhone, successBindPhone } = this.props;
http.post( const params = {
`${API['passport-api']}/m/personal/bindPhone`,
{
area_code: `00${num}`, area_code: `00${num}`,
phone_num: tel, mobile: tel,
code: code, code: code,
type: 1, act_type: 'treasure', // 宝箱
is_valid: isValid };
http.post(
`${API.home}/sys/v2/user/bindMobile`,
{
...params,
type: 1, // 1:绑定,2:修改绑定
is_valid: 1, // is_valid 是否验证 1:验证(默认),0不验证
} }
).then(res => { ).then(res => {
const { errno, data, msg } = res.data; const { errno, data, msg } = res.data;
if(errno === 200 ) { if(errno === 200 ) {
if(isValid) {
if(data.tip_info) { if(data.tip_info) {
this.setState({ handleToConfirmPhone(params, data.tip_info);
type: 10,
bindInfo: data.tip_info
})
}else {
this.receviceAfterBind();
}
}else { }else {
this.receviceAfterBind(); successBindPhone();
} }
}else { }else {
Toast.info(msg, 2, null, false); Toast.info(msg, 2, null, false);
...@@ -137,7 +150,7 @@ class BindPhone extends Component { ...@@ -137,7 +150,7 @@ class BindPhone extends Component {
render() { render() {
const { desc, skip = 'year' } = this.props; const { desc, skip = 'year' } = this.props;
const { country, validate, isTimer } = this.state; const { country, validate, isTimer, seconds } = this.state;
return ( return (
<Formik <Formik
initialValues={{ initialValues={{
...@@ -163,7 +176,7 @@ class BindPhone extends Component { ...@@ -163,7 +176,7 @@ class BindPhone extends Component {
...values ...values
} }
}); });
this.toContinueBind(); this.toBindPhone();
}} }}
render={({values: {tel, code}, errors}) => ( render={({values: {tel, code}, errors}) => (
<Form className="popup-form" data-skip={skip}> <Form className="popup-form" data-skip={skip}>
...@@ -172,9 +185,7 @@ class BindPhone extends Component { ...@@ -172,9 +185,7 @@ class BindPhone extends Component {
<div className="poup-form__desc">{desc}</div> <div className="poup-form__desc">{desc}</div>
} }
<div className="popup-form__item"> <div className="popup-form__item">
<a <a className="popup-form__button--num" onClick={this.toFetchCountryNum}>
className="popup-form__button--num"
to={`/country?id=${getParam('id')}&share_code`}>
+{country.num} +{country.num}
<i className="iconfont iconiconfront-69"/> <i className="iconfont iconiconfront-69"/>
</a> </a>
......
.closable-popup-mask { .closable-popup-mask {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
position: fixed; position: fixed;
top: 0; top: 0;
left: 0; left: 0;
...@@ -12,26 +8,39 @@ ...@@ -12,26 +8,39 @@
z-index: 999; z-index: 999;
.popup-container { .popup-container {
position: absolute;
top: 165px;
left: 50%;
transform: translateX(-50%);
width: 300px;
padding: 20px 10px; padding: 20px 10px;
border-radius: 10px; border-radius: 10px;
background-color: #fff; background: #fff;
.title { .title {
font-size: 16px; font-size: 16px;
color: #525C65; color: #525C65;
text-align: center; text-align: center;
} }
}
.close { .close {
position: absolute;
bottom: -74px;
left: 50%;
transform: translateX(-50%);
font-size: 36px; font-size: 36px;
color: #fff; color: #fff;
} }
.close-icon { .close-icon {
position: absolute;
bottom: -66px;
left: 50%;
width: 33px; width: 33px;
height: 33px; height: 33px;
transform: translateX(-50%);
font-size: 36px; font-size: 36px;
color: #fff; color: #fff;
} }
}
} }
...@@ -2,6 +2,25 @@ import React, { Component } from 'react'; ...@@ -2,6 +2,25 @@ import React, { Component } from 'react';
import './index.scss'; import './index.scss';
class ConfirmPhone extends Component { class ConfirmPhone extends Component {
continueBindPhone = () => {
const { data, successBindPhone } = this.props;
http.post(
`${API.home}/sys/v2/user/bindMobile`,
{
...data,
type: 1, // 1:绑定,2:修改绑定
is_valid: 0, // is_valid 是否验证 1:验证(默认),0不验证
}
).then(res => {
const { errno, msg } = res.data;
if(errno === 200 ) {
successBindPhone();
}else {
Toast.info(msg, 2, null, false);
}
});
}
render() { render() {
const { bindInfo = { }, desc, skip = 'year' } = this.props; const { bindInfo = { }, desc, skip = 'year' } = this.props;
return ( return (
...@@ -55,7 +74,7 @@ class ConfirmPhone extends Component { ...@@ -55,7 +74,7 @@ class ConfirmPhone extends Component {
onClick={() => this.handleToClose(false)}>取消</button> onClick={() => this.handleToClose(false)}>取消</button>
<button <button
className="popup-bind__button popup-bind__button--confirm" className="popup-bind__button popup-bind__button--confirm"
onClick={() => this.toContinueBind(0)}>继续绑定</button> onClick={this.continueBindPhone}>继续绑定</button>
</div> </div>
</div> </div>
) )
......
...@@ -2,6 +2,8 @@ import React, { Component } from 'react' ...@@ -2,6 +2,8 @@ import React, { Component } from 'react'
import { http } from "@/utils" import { http } from "@/utils"
import './prizes.scss' import './prizes.scss'
import { Popup } from "@common/index" import { Popup } from "@common/index"
import { Toast } from "antd-mobile"
import Loadable from '@loadable/component' import Loadable from '@loadable/component'
...@@ -13,6 +15,7 @@ class Prizes extends Component { ...@@ -13,6 +15,7 @@ class Prizes extends Component {
prizeList prizeList
bg bg
innerBox innerBox
closeIcon = 'https://julyedu-cdn.oss-cn-beijing.aliyuncs.com/newyear20/H5/close-btn.png'
state = { state = {
prizes: [], prizes: [],
......
...@@ -153,7 +153,7 @@ ...@@ -153,7 +153,7 @@
.progress-bar { .progress-bar {
position: relative; position: relative;
flex: 0 1 50px; flex: 0 1 45px;
height: 2px; height: 2px;
background: #fff; background: #fff;
...@@ -170,3 +170,11 @@ ...@@ -170,3 +170,11 @@
} }
} }
} }
.common_container {
.container_content {
.prizes-box {
margin: 0 -20px;
}
}
}
...@@ -2,44 +2,73 @@ import React, { Component } from 'react'; ...@@ -2,44 +2,73 @@ import React, { Component } from 'react';
import './index.scss'; import './index.scss';
class SplitSuccess extends Component { class SplitSuccess extends Component {
computedBg = (val) => {
return val? {
backgroundImage: `url(${val})`
} : {};
}
continueSplitTreasure = () => {
const { ids, successSplitTreasure, handleToBindPhone, handleToBindAddress } = this.props;
const params = ids[0];
http.post(`${API.home}/sys/split_treasure`, params).then(res => {
const { code, data } = res.data;
if(code === 200) {
successSplitTreasure();
}else if(code === 12000) {
// 请先绑定手机号再拆宝箱
handleToBindPhone();
}else if(code === 12001) {
// 请先填写收货地址再拆宝箱
handleToBindAddress();
}
})
}
render() { render() {
const { handleToInvite } = this.props; const {
ids,
data: {
member = [],
prize_img,
prize_name,
},
handleToInvite,
children,
} = this.props;
return ( return (
<div data-skip="split"> <div data-skip="split">
<div className="split-success__image"> <div className="split-success__image">
<img src="" alt=""/> <img src={prize_img} alt=""/>
</div> </div>
<p className="split-success__prize">AI100题纸质书</p> <p className="split-success__prize">{prize_name}</p>
<a href="" className="split-success__link">
<span>查看/修改收货信息</span> {children}
</a>
<div className="split-success__member"> <div className="split-success__member">
<div className="member-item"> {
<span className="member-item__avatar"> member.map((item, index) => (
<i className="member-item__captain">队长</i> <div className="member-item" key={index}>
</span> <span className="member-item__avatar" style={this.computedBg(item.avatar)}>
<span className="member-item__prize">AI100题纸质书</span> {
</div> item.is_captain && <i className="member-item__captain">队长</i>
<div className="member-item"> }
<span className="member-item__avatar">
<i className="member-item__captain">队长</i>
</span>
<span className="member-item__prize">AI100题纸质书</span>
</div>
<div className="member-item">
<span className="member-item__avatar">
<i className="member-item__captain">队长</i>
</span>
<span className="member-item__prize">AI100题纸质书</span>
</div>
<div className="member-item">
<span className="member-item__avatar">
<i className="member-item__captain">队长</i>
</span> </span>
<span className="member-item__prize">AI100题纸质书</span> {
item.prize
? <span className="member-item__prize">{item.prize}</span>
: <span className="member-item__prize">尚未拆开宝箱</span>
}
</div> </div>
))
}
</div> </div>
<button className="split-success__jump" onClick={handleToInvite}>继续组队开宝箱</button> {
ids.length > 0
? <button className="split-success__jump" onClick={this.continueSplitTreasure}>继续开宝箱</button>
: <button className="split-success__jump" onClick={handleToInvite}>继续组队开宝箱</button>
}
</div> </div>
); );
} }
......
...@@ -23,7 +23,7 @@ ...@@ -23,7 +23,7 @@
line-height: 1; line-height: 1;
} }
.split-success__link { .team-result {
display: inline-block; display: inline-block;
margin: 8px 0 0; margin: 8px 0 0;
font-size: 12px; font-size: 12px;
......
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
padding-left: 2px; padding-left: 2px;
display: flex; display: flex;
align-items: center; align-items: center;
transition: height .3s ease-in-out; transition: height .1s ease-out;
.sys-bullet-screen-swiper-container{ .sys-bullet-screen-swiper-container{
height: 100%; height: 100%;
......
import React, { Component } from 'react' import React, { Component } from 'react'
import BoxContainer from '../box-container/container' import BoxContainer from '../box-container/container'
import { Toast } from "antd-mobile" import { Toast, WhiteSpace } from "antd-mobile"
import { Popup } from "@common/index" import { Popup } from "@common/index"
import { connect } from "react-redux" import { connect } from "react-redux"
import Prizes from "@components/activity/newyear-2019/common/prizes" import Prizes from "@components/activity/newyear-2019/common/prizes"
import BulletScreen from "@components/activity/newyear-2019/common/user-bullet-screen" import BulletScreen from "@components/activity/newyear-2019/common/user-bullet-screen"
import './landing.scss' import './landing.scss'
import { browser, getParam, http } from "@/utils" import { browser, getParam, http, wxShare } from "@/utils"
import { Link } from "react-router-dom"
import QRCode from "qrcode"
import YearCourse from '../preheat/YearCourse'
class Landing extends Component { class Landing extends Component {
closeIcon = 'https://julyedu-cdn.oss-cn-beijing.aliyuncs.com/newyear20/H5/close-btn.png' closeIcon = 'https://julyedu-cdn.oss-cn-beijing.aliyuncs.com/newyear20/H5/close-btn.png'
createTeamSuccessPopupInstance = null createTeamSuccessPopup = null
joinSuccessPopup = null
swiper = null swiper = null
state = { state = {
teamData: { teamData: {
member: [ member: []
{
head_img: 'https://julyedu-img-public.oss-cn-beijing.aliyuncs.com/Public/Image/default/robot.png',
is_captain: 1
},
{
head_img: 'http://img2.imgtn.bdimg.com/it/u=2138045196,3587715336&fm=26&gp=0.jpg',
is_captain: 0
},
]
}, },
origin: getParam('origin'), origin: getParam('origin'),
treasure_code: getParam('treasure_code'), treasure_code: getParam('treasure_code'),
...@@ -55,7 +50,7 @@ class Landing extends Component { ...@@ -55,7 +50,7 @@ class Landing extends Component {
}) })
let searchParams = new URLSearchParams(window.location.search) let searchParams = new URLSearchParams(window.location.search)
if (searchParams.get('origin') === '1') { if (searchParams.get('origin') === '1' && !browser.isWeixin) {
searchParams.set('origin', '2') searchParams.set('origin', '2')
window.history.replaceState(null, '', `landing?${searchParams.toString()}`) window.history.replaceState(null, '', `landing?${searchParams.toString()}`)
} }
...@@ -116,8 +111,9 @@ class Landing extends Component { ...@@ -116,8 +111,9 @@ class Landing extends Component {
}) })
} }
joinSuccess = ({status, team_num, lack_member, is_team}) => { joinSuccess = ({id, status, my_team: {team_num, lack_member, is_team}}) => {
Popup({ const {history} = this.props
this.joinSuccessPopup = Popup({
title: <div className={'join-success'}> title: <div className={'join-success'}>
<img src="https://julyedu-cdn.oss-cn-beijing.aliyuncs.com/newyear20/H5/check-icon.png" alt=""/> <img src="https://julyedu-cdn.oss-cn-beijing.aliyuncs.com/newyear20/H5/check-icon.png" alt=""/>
<div>成功加入队伍</div> <div>成功加入队伍</div>
...@@ -136,7 +132,12 @@ class Landing extends Component { ...@@ -136,7 +132,12 @@ class Landing extends Component {
{ {
status === 2 status === 2
? <img style={{width: '150px', marginTop: '23px'}} ? <img style={{width: '150px', marginTop: '23px'}}
src="https://julyedu-cdn.oss-cn-beijing.aliyuncs.com/newyear20/PC/treasure-box.png" alt=""/> src="https://julyedu-cdn.oss-cn-beijing.aliyuncs.com/newyear20/PC/treasure-box.png"
alt=""
onClick={() => {
history.push(`/year/yearTreasure?id=${id}`)
}}
/>
: is_team : is_team
? <button type='button' ? <button type='button'
onClick={this.inviteMembers.bind(this, this.state.teamData['my_team']['treasure_code'])}>继续组队</button> onClick={this.inviteMembers.bind(this, this.state.teamData['my_team']['treasure_code'])}>继续组队</button>
...@@ -151,15 +152,24 @@ class Landing extends Component { ...@@ -151,15 +152,24 @@ class Landing extends Component {
} }
inviteMembers = (treasure_code) => { inviteMembers = (treasure_code) => {
const {history, match} = this.props const {history, match, user, location} = this.props
if (browser.isWeixin) {
wxShare({
title: `@${user.data.username} 邀您一起组队拿豪礼!`,
desc: `加我我的队伍,机械键盘,纸质书籍等超多奖品等你拿!`,
link: encodeURIComponent(`${window.location.origin}/${location.pathname}?treasure_code=${treasure_code}&origin=2`),
imgUrl: 'https://julyedu-cdn.oss-cn-beijing.aliyuncs.com/newIndex/community/tou5_bj.png'
})
}
sessionStorage.setItem('showShareTip', '1') sessionStorage.setItem('showShareTip', '1')
history.replace(`${match.path}?treasure_code=${treasure_code}&origin=${1}`) history.replace(`${match.path}?treasure_code=${treasure_code}&origin=${1}`)
this.createTeamSuccessPopupInstance && this.createTeamSuccessPopupInstance.remove() this.createTeamSuccessPopup && this.createTeamSuccessPopup.remove() && (this.createTeamSuccessPopup = null)
this.fetchPageData({treasure_code, origin: 1}) this.fetchPageData({treasure_code, origin: 1})
} }
createTeamSuccess = ({member, team_num, lack_member, treasure_code}) => { createTeamSuccess = (member, team_num, lack_member, treasure_code) => {
let isFollow = false let isFollow = false
this.joinSuccessPopup && this.joinSuccessPopup.remove() && (this.joinSuccessPopup = null)
http.get(`${API.home}/sys/user/isFollowWeChat`) http.get(`${API.home}/sys/user/isFollowWeChat`)
.then(res => { .then(res => {
const {errno, status} = res.data const {errno, status} = res.data
...@@ -167,7 +177,7 @@ class Landing extends Component { ...@@ -167,7 +177,7 @@ class Landing extends Component {
isFollow = true isFollow = true
} }
}) })
this.createTeamSuccessPopupInstance = Popup({ this.createTeamSuccessPopup = Popup({
title: '创建成功', title: '创建成功',
className: 'landing-create-success', className: 'landing-create-success',
content: <div> content: <div>
...@@ -204,23 +214,30 @@ class Landing extends Component { ...@@ -204,23 +214,30 @@ class Landing extends Component {
} }
remind = (type = 'create', treasure_code) => { remind = (type = 'create', treasure_code) => {
const {match, history} = this.props const {match, history, user} = this.props
http.get(`${API["base-api"]}/wx/user_temporary_qrcode/${user.data.uid}`)
.then(res => {
const {data} = res.data
return data.url
})
QRCode.toDataURL('http://m.julyedu.com')
.then(url => {
Popup({ Popup({
title: '提醒服务', title: '提醒服务',
className: 'landing-remind', className: 'landing-remind',
closeIcon: this.closeIcon, closeIcon: this.closeIcon,
content: <div> content: <div>
<div className="des">{type === 'create' ? '有好友加入队伍后第一时间通知我~' : '获得宝箱时第一时间通知我~'}</div> <div className="des">{type === 'create' ? '有好友加入队伍后第一时间通知我~' : '获得宝箱时第一时间通知我~'}</div>
<img src="https://julyedu-cdn.oss-cn-beijing.aliyuncs.com/tinypng-common/right_weixin.png" alt=""/> <img src={url} alt=""/>
<div className="des">长按识别/扫码 关注【七月在线】服务号即可预约</div> <div className="des">长按识别/扫码 关注【七月在线】服务号即可预约</div>
</div>, </div>,
close: () => new Promise(resolve => { close: () => {
history.replace(`${match.path}?treasure_code=${treasure_code}&origin=1`) history.replace(`${match.path}?treasure_code=${treasure_code}&origin=1`)
this.fetchPageData({ this.fetchPageData({
treasure_code, treasure_code,
origin: '1' origin: '1'
}) })
resolve() }
}) })
}) })
} }
...@@ -266,6 +283,7 @@ class Landing extends Component { ...@@ -266,6 +283,7 @@ class Landing extends Component {
closable: false, closable: false,
close: () => { close: () => {
sessionStorage.removeItem('showShareTip') sessionStorage.removeItem('showShareTip')
this.remind()
} }
}) })
} }
...@@ -330,7 +348,7 @@ class Landing extends Component { ...@@ -330,7 +348,7 @@ class Landing extends Component {
return ( return (
<div id={'landing'}> <div id={'landing'}>
<div id="to-square"> <div id="to-square">
前往活动会场,享更多福利! >> <Link to='/year/yearindex'>前往活动会场,享更多福利! >></Link>
</div> </div>
<BoxContainer> <BoxContainer>
<i className="snow-deco"/> <i className="snow-deco"/>
...@@ -339,10 +357,8 @@ class Landing extends Component { ...@@ -339,10 +357,8 @@ class Landing extends Component {
{ {
status === 1 && <div className="des">邀请好友加入队伍,开宝箱领取丰厚奖品~</div> status === 1 && <div className="des">邀请好友加入队伍,开宝箱领取丰厚奖品~</div>
} }
{ <div className="des">加入我的<span>{team_num}</span>号队伍,一起开宝箱领取丰厚奖品~</div>
status === 2 || status === 3 && <div className="des">加入我的<span>{team_num}</span>号队伍,一起开宝箱领取丰厚奖品~</div> <Prizes showSystemNotices={false}/>
}
<Prizes showSystemNotices={true}/>
<BulletScreen/> <BulletScreen/>
<div className="group"> <div className="group">
<ul className={'member'}> <ul className={'member'}>
...@@ -464,6 +480,8 @@ class Landing extends Component { ...@@ -464,6 +480,8 @@ class Landing extends Component {
} }
</div> </div>
</BoxContainer> </BoxContainer>
<WhiteSpace size={'xl'}/>
<YearCourse></YearCourse>
</div> </div>
) )
} }
......
...@@ -69,8 +69,6 @@ ...@@ -69,8 +69,6 @@
} }
.group { .group {
ul.member { ul.member {
display: flex; display: flex;
...@@ -168,30 +166,37 @@ ...@@ -168,30 +166,37 @@
} }
} }
.activity-end{ .activity-end {
display: flex; display: flex;
flex-flow: column; flex-flow: column;
align-items: center; align-items: center;
margin-top: 26px; margin-top: 26px;
font-size: 14px; font-size: 14px;
color: #FFE300; color: #FFE300;
div:first-child{
div:first-child {
margin-bottom: 5px; margin-bottom: 5px;
} }
div:nth-child(2){
div:nth-child(2) {
margin-bottom: 19px; margin-bottom: 19px;
} }
img{
img {
width: 120px; width: 120px;
height: 120px; height: 120px;
margin-bottom: 12px; margin-bottom: 12px;
} }
div:last-child{
div:last-child {
color: #fff; color: #fff;
font-size: 12px; font-size: 12px;
} }
} }
.am-whitespace.am-whitespace-xl {
height: 35px;
}
} }
.popup-container { .popup-container {
...@@ -342,6 +347,10 @@ ...@@ -342,6 +347,10 @@
font-size: 14px; font-size: 14px;
color: #666; color: #666;
} }
button {
}
} }
.landing-unpack-treasure-box { .landing-unpack-treasure-box {
...@@ -436,6 +445,7 @@ ...@@ -436,6 +445,7 @@
color: #111; color: #111;
&.popup-container { &.popup-container {
position: absolute;
width: 270px; width: 270px;
text-align: center; text-align: center;
top: 114px; top: 114px;
......
import React, { Component } from 'react'; import React, { Component } from 'react';
import { connect } from 'react-redux';
import { HeaderBar, Popup } from '@common'; import { HeaderBar, Popup } from '@common';
import AddressPopup from '@common/addressPopup/index'; import AddressPopup from '@common/addressPopup/index';
import BindPhone from '@common/bindPhone/index'; import BindPhone from '@common/bindPhone/index';
import ConfirmPhone from '@common/confirmPhone/index'; import ConfirmPhone from '@common/confirmPhone/index';
import TreasureTeam from './team'; import TreasureTeam from './team';
import { http } from '@/utils'; import PrizeStatus from './prize';
import SplitSuccess from './../common/splitSuccess/index';
import { http, getParam } from '@/utils';
import './index.scss'; import './index.scss';
@connect(({country, user}) => ({
country,
userInfo: user.data
}))
class MyTreasure extends Component { class MyTreasure extends Component {
popupInstance = null;
constructor(props) { constructor(props) {
super(props); super(props);
...@@ -16,43 +24,201 @@ class MyTreasure extends Component { ...@@ -16,43 +24,201 @@ class MyTreasure extends Component {
isEmpty: false, isEmpty: false,
seconds: 3, seconds: 3,
teams: [], teams: [],
bindInfo: { ids: [], // 未拆宝箱统计
email: 'a', bindInfo: {}, // 绑定手机号冲突信息
wechat_nickname: 'b',
qq_nickname: 'c',
sina_nickname: 'd',
}, // 绑定手机号冲突信息
}; };
} }
componentDidMount() { componentDidMount() {
const { isEnd, bindInfo } = this.state; const { isEnd, bindInfo } = this.state;
if(isEnd) { if (isEnd) {
this.startCountDown(); this.startCountDown();
} }
this.fetchMyTreasure(); this.fetchMyTreasure();
this.fetchActivityStatus(); this.fetchActivityStatus();
// 绑定地址--宝箱 }
Popup({
componentWillUnmount() {
if(this.phoneInstance) {
this.phoneInstance.close();
}
if(this.confrimInstance) {
this.confrimInstance.close();
}
if(this.splitInstance) {
this.splitInstance.close();
}
if(this.addressInstance) {
this.addressInstance.close();
}
}
// 页面加载时,是否需要拆宝箱
judgeIsHaveId = (data) => {
const id = getParam('id');
if(id) {
const newData = data.filter(item => item.id == id);
if(newData.length > 0) {
const params = {
team_num: newData[0]['team_num'],
owner_uid: newData[0]['captain_uid']
};
this.toSplitTreasure(params);
}
}
}
// 绑定手机号--展示
handleToBindPhone = (id) => {
const { history, country } = this.props;
this.phoneInstance = Popup({
title: '绑定手机号', title: '绑定手机号',
content: <BindPhone desc={<> content: <BindPhone
history={history}
country={country}
hideBindPhone={this.hideBindPhone.bind(this)}
handleToConfirmPhone={this.handleToConfirmPhone}
successBindPhone={() => this.successBindPhone(id)}
desc={
<>
<p className="phone-treasure__desc">恭喜您获得 奖品名称(现金)</p> <p className="phone-treasure__desc">恭喜您获得 奖品名称(现金)</p>
<p className="phone-treasure__notice">为了您的账户安全,请于20191231日前绑定手机号,过期将失效</p> <p className="phone-treasure__notice">为了您的账户安全,请于20191231日前绑定手机号,过期将失效</p>
</>} /> </>
}
/>,
close: () => new Promise(resolve => {
this.phoneInstance = null;
resolve()
})
}); });
} }
handleToBindPhone = () => { // 绑定手机号--隐藏
hideBindPhone() {
if (this.phoneInstance) {
this.phoneInstance.close();
}
} }
handleToConfirmPhone = () => { // 绑定手机号--确认
handleToConfirmPhone = (params, bindInfo) => {
this.confrimInstance = Popup({ this.confrimInstance = Popup({
title: '绑定确认', title: '绑定确认',
content: <ConfirmPhone bindInfo={bindInfo} /> content: <ConfirmPhone
data={params}
bindInfo={bindInfo}
successBindPhone={this.successBindPhone}
/>,
close: () => new Promise(resolve => {
this.confrimInstance = null;
resolve()
})
});
}
// 绑定手机号--成功
successBindPhone = (id) => {
const { teams } = this.state;
const data = teams.map(item => {
if(item.id == id) {
if(item.bind_address) {
this.handleToBindAddress();
}
return Object.assign({}, item, {
bind_phone: false,
});
}
return item;
})
this.setState({
teams: data
});
}
// 拆宝箱--拆
toSplitTreasure = (params) => {
const { ids } = this.state;
http.post(`${API.home}/sys/split_treasure`, params).then(res => {
const { code, data } = res.data;
if(code === 200) {
// 拆宝箱弹窗--成功
this.splitInstance = Popup({
title: '恭喜你获得',
skip: 'year',
content: <SplitSuccess
ids={ids}
data={data}
handleToInvite={this.handleToInvite}
successSplitTreasure={() => this.successSplitTreasure(data)}
>
<PrizeStatus
data={data}
handleToBindPhone={this.handleToBindPhone}
handleToBindAddress={this.handleToBindAddress}
toComposeCoupon={this.toComposeCoupon}
toUseCoupon={this.toUseCoupon}
toCourseList={this.toCourseList}
toFecthMoney={this.toFecthMoney}
/>
</SplitSuccess>,
close: () => new Promise(resolve => {
this.splitInstance = null;
resolve()
})
});
// 跟新队伍状态
this.successSplitTreasure(data);
if(data.bind_phone) {
setTimeout(() => {
this.handleToBindPhone();
}, 500);
}else if(data.bind_address) {
setTimeout(() => {
this.handleToBindAddress();
}, 500);
}
}else if(code === 12000) {
// 绑定手机号
this.handleToBindPhone();
}else if(code === 12001) {
// 绑定地址
this.handleToBindAddress();
}
});
}
// 拆宝箱--成功
successSplitTreasure = (params) => {
const { userInfo } = this.props;
const { teams } = this.state;
const data = teams.map(item => {
if(item.id == params.id) {
return Object.assign({}, item, {
bind_phone: params.bind_phone,
bind_address: params.bind_address,
is_open: true,
member: item.member.map(val => {
if(val.uid == userInfo.uid) {
return Object.assign({}, val, {
is_open: true,
prize_name: params.prize_name
});
}
return val;
})
});
}else {
return item;
}
});
this.initNoSplitInfo(data);
this.setState({
teams: data
}); });
} }
// 绑定地址--展示
handleToBindAddress = () => { handleToBindAddress = () => {
this.addressInstance = Popup({ this.addressInstance = Popup({
title: '收货信息', title: '收货信息',
...@@ -66,38 +232,59 @@ class MyTreasure extends Component { ...@@ -66,38 +232,59 @@ class MyTreasure extends Component {
</> </>
} }
handleToHide={() => this.addressInstance.close()} handleToHide={() => this.addressInstance.close()}
/> />,
close: () => new Promise(resolve => {
this.addressInstance = null;
resolve()
})
}); });
} }
// 获取我的宝箱信息
fetchMyTreasure = () => { fetchMyTreasure = () => {
http.get(`${API.home}/sys/treasure/my`).then(res => { http.get(`${API.home}/sys/treasure/my`).then(res => {
const { code, data } = res.data; const { code, data } = res.data;
if(code === 200) { if (code === 200) {
this.rule = data.rule; this.rule = data.rule;
if(Array.isArray(data.team) && data.team.length > 0) { if (Array.isArray(data.team) && data.team.length > 0) {
const teams = data.team.map(item => { this.initNoSplitInfo(data.team);
return Object.assign({}, item, { this.judgeIsHaveId(data.team);
members: item.member
});
});
this.setState({ this.setState({
isEmpty: false, isEmpty: false,
teams, teams: data.team,
}); });
}else{ } else {
this.setState({ this.setState({
isEmpty: true, isEmpty: true,
}); });
} }
} else if (code === 4030 || code === 4040) {
this.setState({
isEmpty: true,
});
} }
}); });
} }
// 统计未拆的宝箱信息
initNoSplitInfo = (data = []) => {
if(data.length > 0) {
this.setState({
ids: data.filter(item => !item.is_open && item.status === 2).map(val => {
return {
team_num: val.team_num,
owner_uid: val.captain_uid
}
})
});
}
}
// 获取宝箱活动状态
fetchActivityStatus = () => { fetchActivityStatus = () => {
http.get(`${API.home}/activity/stage`).then(res => { http.get(`${API.home}/activity/stage`).then(res => {
const { code, data } = res.data; const { code, data } = res.data;
if(code === 200) { if (code === 200) {
// treasure_stage,宝箱阶段,0-不在活动时间,1-活动时间内 // treasure_stage,宝箱阶段,0-不在活动时间,1-活动时间内
this.setState({ this.setState({
...@@ -110,7 +297,7 @@ class MyTreasure extends Component { ...@@ -110,7 +297,7 @@ class MyTreasure extends Component {
startCountDown = () => { startCountDown = () => {
const { history } = this.props; const { history } = this.props;
let { seconds } = this.state; let { seconds } = this.state;
if(this.timer) { if (this.timer) {
clearInterval(this.timer); clearInterval(this.timer);
} }
this.setState({ this.setState({
...@@ -120,7 +307,7 @@ class MyTreasure extends Component { ...@@ -120,7 +307,7 @@ class MyTreasure extends Component {
this.setState({ this.setState({
seconds: seconds-- seconds: seconds--
}); });
if(seconds === 0) { if (seconds === 0) {
this.setState({ this.setState({
seconds: 0 seconds: 0
}); });
...@@ -130,15 +317,54 @@ class MyTreasure extends Component { ...@@ -130,15 +317,54 @@ class MyTreasure extends Component {
}, 1000); }, 1000);
} }
updatedTreasureStatus = (id) => {
console.log(id);
}
// 邀请好友
handleToInvite = () => {
const { history } = this.props;
const { team } = this.state;
history.push(`/activity/newyear-2019/landing?treasure_code=${team.treasure_code}&origin=1`);
if(this.splitInstance) {
this.splitInstance.close();
}
}
// 奖品,代金券碎片--合成
toComposeCoupon = () => {
const { history } = this.props;
history.push('/coupons/my-patch');
}
// 奖品,指定课程代金券--使用
toUseCoupon = () => {
const { history } = this.props;
history.push(`/detail?id=${coupon['limit_course']}`);
}
// 第三:奖品,通用课程代金券--使用
toCourseList = () => {
const { history } = this.props;
history.push('/classify');
}
// 第三:奖品,现金红包--提现
toFecthMoney = () => {
const { history } = this.props;
history.push('/scholarship');
}
render() { render() {
const { isEnd, isEmpty, seconds, teams } = this.state; const { history, userInfo } = this.props;
const { isEnd, isEmpty, seconds, teams, ids } = this.state;
return ( return (
<div data-skip="treasure"> <div data-skip="treasure">
<HeaderBar title="我的宝箱" arrow={true} /> <HeaderBar title="我的宝箱" arrow={true} />
{ {
isEnd && isEnd &&
<p className="activity-end__desc"> <p className="activity-end__desc">
活动已结束<br/> 活动已结束<br />
{seconds}s后将自动返回首页 {seconds}s后将自动返回首页
</p> </p>
} }
...@@ -159,9 +385,28 @@ class MyTreasure extends Component { ...@@ -159,9 +385,28 @@ class MyTreasure extends Component {
<TreasureTeam <TreasureTeam
data={item} data={item}
key={index} key={index}
userInfo={userInfo}
history={history}
splitInstance={this.splitInstance}
toSplitTreasure={() => this.toSplitTreasure({
team_num: item.team_num,
owner_uid: item.captain_uid
})}
>
<PrizeStatus
data={{
bind_phone: item.bind_phone,
bind_address: item.bind_address,
prize_type: item.prize_type,
}}
handleToBindPhone={this.handleToBindPhone} handleToBindPhone={this.handleToBindPhone}
handleToBindAddress={this.handleToBindAddress} handleToBindAddress={this.handleToBindAddress}
toComposeCoupon={this.toComposeCoupon}
toUseCoupon={this.toUseCoupon}
toCourseList={this.toCourseList}
toFecthMoney={this.toFecthMoney}
/> />
</TreasureTeam>
)) ))
} }
</div> </div>
......
import React from 'react';
import './prize.scss';
export default (props) => {
const {
data: {
bind_phone,
bind_address,
prize_type,
},
handleToBindPhone,
handleToBindAddress,
toComposeCoupon,
toUseCoupon,
toCourseList,
toFecthMoney,
} = props;
return (
<>
{/* 第一:是否需要绑定手机号 */}
{
bind_phone &&
<a className="team-result" onClick={handleToBindPhone}>
<span>绑定手机号</span>
</a>
}
{/* 第二:是否需要填写地址 */}
{
(!bind_phone && bind_address) &&
<a className="team-result" onClick={handleToBindAddress}>
<span>查看/修改收货信息</span>
</a>
}
{/* 第三:奖品,代金券碎片 */}
{
(!bind_phone && !bind_address && prize_type === 6) &&
<a className="team-result" onClick={toComposeCoupon}>
可合成代金券在购课时使用,
<span>去合成</span>
</a>
}
{/* 第三:奖品,指定课程代金券 */}
{
(!bind_phone && !bind_address && prize_type === 3) &&
<a className="team-result" onClick={toUseCoupon}>
已发放至您的账户,
<span>去使用</span>
</a>
}
{/* 第三:奖品,通用课程代金券 */}
{
(!bind_phone && !bind_address && prize_type === 4) &&
<a className="team-result" onClick={toCourseList}>
已发放至您的账户,
<span>去使用</span>
</a>
}
{/* 第三:奖品,现金红包 */}
{
(!bind_phone && !bind_address && prize_type === 7) &&
<a className="team-result" onClick={toFecthMoney}>
已存入您的账户,
<span>去提现</span>
</a>
}
{/* 第三:奖品,线上课程 */}
{
(!bind_phone && !bind_address && prize_type === 2) &&
<a className="team-result">已发放至您的账户</a>
}
</>
)
}
\ No newline at end of file
.team-result {
display: inline-block;
margin: 8px 0 0;
font-size: 12px;
color: #666;
text-align: center;
line-height: 1;
span {
text-decoration: underline;
}
}
\ No newline at end of file
import React, { Component } from 'react'; import React, { Component } from 'react';
import classnames from 'classnames'; import classnames from 'classnames';
import { withRouter, Link } from 'react-router-dom'; import { Link } from 'react-router-dom';
import { http } from '@/utils';
import { Popup } from '@common';
import SplitSuccess from './../common/splitSuccess/index';
import './team.scss'; import './team.scss';
class TreasureTeam extends Component { class TreasureTeam extends Component {
...@@ -19,26 +16,27 @@ class TreasureTeam extends Component { ...@@ -19,26 +16,27 @@ class TreasureTeam extends Component {
this.initMemberInfo(); this.initMemberInfo();
} }
handleToInvite = () => { componentWillReceiveProps(nextProps) {
const { history } = this.props; const { data: oldData } = this.props;
history.push('/activity/newyear-2019/landing'); const { data: newData } = nextProps;
if(this.splitInstance) { if(newData.is_open != oldData.is_open) {
this.splitInstance.close(); this.initMemberInfo(newData);
} }
} }
initMemberInfo = () => { initMemberInfo = (params = {}) => {
const { data } = this.props; const { data, userInfo } = this.props;
let members = data.members; const arr = JSON.stringify(params) !== '{}'? params: data;
let len = members.length - 5; let member = arr.member;
let len = member.length - 5;
for(; len < 0; len++) { for(; len < 0; len++) {
members.push({}); member.push({});
} }
this.setState({ this.setState({
team: Object.assign({}, data, { team: Object.assign({}, arr, {
members member
}), }),
currentMember: members[0] currentMember: member.filter(item => item.uid == userInfo.uid)[0]
}); });
} }
...@@ -61,58 +59,32 @@ class TreasureTeam extends Component { ...@@ -61,58 +59,32 @@ class TreasureTeam extends Component {
// 查看队友的奖品,条件:宝箱已拆 // 查看队友的奖品,条件:宝箱已拆
toCheckPrize = (id) => { toCheckPrize = (id) => {
const { team: { is_open, members = []} } = this.state; const { team: { is_open, member = []} } = this.state;
if(is_open) { if(is_open) {
const data = members.filter(item => item.uid === id); const data = member.filter(item => item.uid === id);
this.setState({ this.setState({
currentMember: data[0] currentMember: data[0]
}); });
} }
} }
toSplitTreasure = () => {
const { handleToBindPhone, handleToBindAddress } = this.props;
const { team: {captain_uid, team_num} } = this.state;
http.post(`${API.home}/sys/split_treasure`, {
team_num: team_num,
owner_uid: captain_uid
}).then(res => {
const { code, data } = res.data;
if(code === 200) {
// 拆宝箱弹窗--成功
this.splitInstance = Popup({
title: '恭喜你获得',
skip: 'year',
content: <SplitSuccess handleToInvite={this.handleToInvite} />
});
}else if(code === 12000) {
// 绑定手机号
handleToBindPhone();
}else if(code === 12001) {
// 绑定地址
handleToBindAddress();
}
});
}
render() { render() {
const { const {
team: { team: {
id,
is_captain, is_captain,
status, status,
team_num, team_num,
lack_member, lack_member,
is_open, is_open,
members = [], treasure_code,
prize_type, member = [],
bing_phone,
bing_address,
}, },
currentMember: { currentMember
prize_name
}
} = this.state; } = this.state;
const {
toSplitTreasure,
children
} = this.props;
return ( return (
<div className="team-container" data-skip="team"> <div className="team-container" data-skip="team">
{ {
...@@ -143,11 +115,11 @@ class TreasureTeam extends Component { ...@@ -143,11 +115,11 @@ class TreasureTeam extends Component {
} }
<div className="team-member"> <div className="team-member">
{ {
members.map((item, index) => ( member.map((item, index) => (
<div <div
className={this.computedClass(item.uid)} className={this.computedClass(item.uid)}
onClick={() => this.toCheckPrize(item.uid)} onClick={() => this.toCheckPrize(item.uid)}
key={item.id} key={index}
style={this.computedBg(item.head_img)} style={this.computedBg(item.head_img)}
> >
{ {
...@@ -165,8 +137,8 @@ class TreasureTeam extends Component { ...@@ -165,8 +137,8 @@ class TreasureTeam extends Component {
<> <>
{ {
is_captain is_captain
? <Link className="team-button" to="/activity/newyear-2019/landing">继续邀请队友</Link> ? <Link className="team-button" to={`/activity/newyear-2019/landing?treasure_code=${treasure_code}&origin=1`}>继续邀请队友</Link>
: <Link className="team-button" to="/activity/newyear-2019/landing">帮好友完成组队</Link> : <Link className="team-button" to={`/activity/newyear-2019/landing?treasure_code=${treasure_code}&origin=2`}>帮好友完成组队</Link>
} }
</> </>
} }
...@@ -176,7 +148,7 @@ class TreasureTeam extends Component { ...@@ -176,7 +148,7 @@ class TreasureTeam extends Component {
(status === 2 && !is_open) && (status === 2 && !is_open) &&
<> <>
<span className="team-icon" data-direction="left"></span> <span className="team-icon" data-direction="left"></span>
<span className="team-button--split" onClick={this.toSplitTreasure}></span> <span className="team-button--split" onClick={toSplitTreasure}></span>
<span className="team-icon" data-direction="right"></span> <span className="team-icon" data-direction="right"></span>
</> </>
} }
...@@ -185,85 +157,8 @@ class TreasureTeam extends Component { ...@@ -185,85 +157,8 @@ class TreasureTeam extends Component {
{ {
(status === 2 && is_open) && (status === 2 && is_open) &&
<> <>
<p className="team-prize">{prize_name}</p> <p className="team-prize">{currentMember.prize_name}</p>
{children}
{/* 第一:是否需要绑定手机号 */}
{
bing_phone &&
<a className="treamsure-team__result" onClick="$emit('to-bind-phone', data.bing_address)">
<span>绑定手机号</span>
</a>
}
{/* 第二:是否需要填写地址 */}
{
(!bing_phone && bing_address) &&
<a className="treamsure-team__result" onClick="$emit('to-bind-address')">
<span>查看/修改收货信息</span>
</a>
}
{/* 第三:奖品,代金券碎片 */}
{
(!bing_phone && !bing_address && prize_type === 6) &&
<a
href="/my/coupon"
target="_blank"
className="treamsure-team__result"
>
可合成代金券在购课时使用,
<span>去合成</span>
</a>
}
{/* 第三:奖品,指定课程代金券 */}
{
(!bing_phone && !bing_address && prize_type === 3) &&
<a
href="/my/coupon"
target="_blank"
className="treamsure-team__result"
>
已发放至您的账户,
<span>去使用</span>
</a>
}
{/* 第三:奖品,通用课程代金券 */}
{
(!bing_phone && !bing_address && prize_type === 4) &&
<a
href="/my/coupon"
target="_blank"
className="treamsure-team__result"
>
已发放至您的账户,
<span>去使用</span>
</a>
}
{/* 第三:奖品,现金红包 */}
{
(!bing_phone && !bing_address && prize_type === 7) &&
<a
href="/my/coupon"
target="_blank"
className="treamsure-team__result"
>
已存入您的账户,
<span>去提现</span>
</a>
}
{/* 第三:奖品,线上课程 */}
{
(!bing_phone && !bing_address && prize_type === 2) &&
<a
href="/my/coupon"
target="_blank"
className="treamsure-team__result"
>已发放至您的账户</a>
}
</> </>
} }
</div> </div>
...@@ -272,4 +167,4 @@ class TreasureTeam extends Component { ...@@ -272,4 +167,4 @@ class TreasureTeam extends Component {
} }
} }
export default withRouter(TreasureTeam); export default TreasureTeam;
\ No newline at end of file \ No newline at end of file
...@@ -179,4 +179,15 @@ ...@@ -179,4 +179,15 @@
color: #303030; color: #303030;
line-height: 1; line-height: 1;
} }
.team-result {
margin: 8px 0 0;
font-size: 12px;
color: #666;
line-height: 1;
span {
text-decoration: underline;
}
}
} }
\ No newline at end of file
...@@ -2,11 +2,16 @@ import React, { Component } from 'react'; ...@@ -2,11 +2,16 @@ import React, { Component } from 'react';
import CommonContainer from './../common/commonContainer/index'; import CommonContainer from './../common/commonContainer/index';
import TreasureRank from './rank'; import TreasureRank from './rank';
import TeamInfo from './team' import TeamInfo from './team'
import Prizes from "@components/activity/newyear-2019/common/prizes"
import UserBulletScreen from "@components/activity/newyear-2019/common/user-bullet-screen"
class TreasureBox extends Component { class TreasureBox extends Component {
render() { render() {
return ( return (
<CommonContainer id="year-treasure"> <CommonContainer id="year-treasure" title={'组队开宝箱'}>
<div style={{textAlign: 'center', fontSize: '12px', color: '#FFDC1E', marginTop: '10px'}}>邀请好友组队一起开宝箱,满5人后将随机获得以下奖品~</div>
<Prizes showSystemNotices={true}/>
<UserBulletScreen/>
<TeamInfo /> <TeamInfo />
<TreasureRank /> <TreasureRank />
</CommonContainer> </CommonContainer>
......
...@@ -56,7 +56,7 @@ class TeamInfo extends Component { ...@@ -56,7 +56,7 @@ class TeamInfo extends Component {
const {removable_data, info: {removable}} = this.state; const {removable_data, info: {removable}} = this.state;
if(removable > 0) { if(removable > 0) {
let current = removable_data[0]; let current = removable_data[0];
search = `?team_num=${current.team_num}&owner_uid=${current.captain_uid}`; search = `?id=${current.id}`;
} }
} }
this.props.history.push(`/year/yearTreasure${search}`); this.props.history.push(`/year/yearTreasure${search}`);
......
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