Commit 50ab0cd1 by xuzhenghua

心愿单

parents b13cbcc2 a16a4ef8
import React, { Component } from 'react';
import { Formik, Form, Field } from 'formik';
import { withRouter, Link } from 'react-router-dom';
import Captcha from '@/common/Captcha';
import { getParam } from '@/utils';
import './index.scss';
class BindPhone extends Component {
constructor(props) {
super(props),
this.state = {
// 弹窗类型:0: 无弹出,1:非微信,2:微信
type: 0,
isCopy: false,
validate: '',
captchaInstance: null,
seconds: 60,
isFirst: true,
timer: null,
isTimer: false, // 是否开始倒计时
shareInfo: {
url: '',
share_code: '',
command: '【七月在线送你一个红包】https://www.julyedu.com/'
},
doneInfo: { //领取后的状态,1:领取成功,2:领取超时
status: 2,
txt: '手机号绑定超时,红包已失效!',
desc: ''
},
money: '', // 红包金额,
endTime: 10, // 手机绑定时限
countdownTimer: null,
countdown: '00分00秒', // 绑定时间
accountInfo: {},
bindInfo: {},
country: {
num: '86'
}
}
}
render() {
const { country, validate, isTimer } = this.state;
return (
<div className="popup-form">
<Formik
initialValues={{
tel: '',
code: ''
}}
validate={({tel, code}) => {
const errors = {};
// if (!validateTel(tel)) {
if(!/^\d+$/.test(tel)) {
errors.tel = '请填写正确格式的手机号';
}
if (!/[0-9]{6}/.test(code)) {
errors.code = '请输入验证码';
}
return errors;
}}
onSubmit={(values, { setStatus, setSubmitting }) => {
this.setState({
accountInfo: {
...values
}
});
this.toContinueBind();
}}
render={({values: {tel, code}, errors}) => (
<Form className="popup-form__content">
<h4 className="popup-form__title">绑定手机号</h4>
<div className="popup-form__item">
<Link
className="popup-form__button--num"
to={`/country?id=${getParam('id')}&share_code`}>
+{country.num}
<i className="iconfont iconiconfront-69"/>
</Link>
<Field
name="tel"
render={({field}) => {
return (
<input
{...field}
className="popup-form__ipt"
data-bdrs="0 6px 6px 0"
data-type="tel"
type="text"
placeholder="请填写手机号"
/>
);
}}
/>
</div>
<Captcha
mrBtm={15}
getInstance={this.getCaptchaInstance}
onVerify={this.onVerify}
/>
<div className="popup-form__item">
<Field
name="code"
render={({field}) => {
return (
<input
{...field}
className="popup-form__ipt popup-form__ipt--left"
type="text"
placeholder="输入验证码"
/>
);
}}
/>
<button
className="popup-form__button--code"
data-status={(validate && !isTimer)? 'do': ''}
type="button"
onClick={() => this.handleToSend({tel, code})}
>
{
isTimer? `重新发送${seconds}s` : '发送验证码'
}
</button>
</div>
<button
className="popup-packet__button--bundle"
data-status={(tel && code && isEmpty(errors))? 'do': 'done'}
type="submit"
>
完成绑定
</button>
</Form>
)}
/>
<i
className="popup-password__button--close iconfont iconiconfront-2"
onClick={() => this.handleToClose(false)}
/>
</div>
)
}
}
export default withRouter(BindPhone);
\ No newline at end of file
// form
.popup-form {
text-align: center;
.popup-form__title {
margin-bottom: 15px;
}
.popup-packet__button--bundle {
margin-top: 5px;
}
}
.popup-form__content {
width: 290px;
height: 257px;
padding: 20px 20px 0;
border-radius: 10px;
box-sizing: border-box;
background-color: #fff;
}
.popup-form__title {
font-size: 15px;
font-weight: 400;
color: #333;
line-height: 1;
}
.popup-form__item {
display: flex;
align-items: center;
justify-content: center;
height: 36px;
margin-bottom: 15px;
.popup-form__ipt {
flex: 1;
}
.popup-form__ipt--left {
width: 130px;
}
.popup-form__button--code {
margin-left: 10px;
}
}
.popup-form__button--num {
display: block;
position: relative;
height: 36px;
padding: 0 8px;
border: 1px solid #99D6FF;
border-right-style: none;
border-radius: 6px 0 0 6px;
box-sizing: border-box;
font-size: 14px;
color: #333;
line-height: 36px;
&::after {
display: block;
content: '';
position: absolute;
top: 0;
right: 0;
bottom: 0;
width: 1px;
height: 14px;
margin: auto 0;
background-color: #AAAAAA;
}
.iconfont {
font-size: 12px;
color: #333;
}
}
.popup-form__ipt {
height: 36px;
padding: 0 8px;
border: 1px solid #99D6FF;
border-radius: 6px;
box-sizing: border-box;
font-size: 12px;
color: #999;
line-height: 36px;
outline: none;
&[data-bdrs="0 6px 6px 0"] {
border-radius: 0 6px 6px 0;
}
&[data-type="tel"] {
border-left-style: none;
}
}
.popup-form__tip {
margin: 0;
font-size: 12px;
color: #FF3131;
.iconfont {
font-size: 15px;
color: #FF3131;
}
}
.popup-form__button--code {
width: 110px;
height: 36px;
padding: 0;
border: 1px solid #E5E5E5;
border-radius: 6px;
box-sizing: border-box;
font-size: 13px;
color: #999;
text-align: center;
line-height: 36px;
background-color: transparent;
&[data-status='do'] {
border-color: #0099FF;
color: #0099FF;
}
}
\ No newline at end of file
import React, { Component } from 'react';
import './index.scss';
class ConfirmPhone extends Component {
render() {
const { bindInfo = { }, desc, skip = 'year' } = this.props;
return (
<div className="popup-bind" data-skip={skip}>
{
desc
? <div className="popup-bind__desc">{desc}</div>
: <p className="popup-bind__desc">该手机号已绑定到以下账号,继续绑定将解除以下绑定状态</p>
}
<ul className="popup-bind__list">
{
bindInfo['email'] &&
<li className="popup-bind__account">
{/* 邮箱 */}
<i className="popup-bind__icon" data-plat="mail"></i>
<p className="popup-bind__account--name">{bindInfo['email']}</p>
</li>
}
{
bindInfo['wechat_nickname'] &&
<li className="popup-bind__account">
{/* wechat */}
<i className="popup-bind__icon" data-plat="wachat"></i>
<p className="popup-bind__account--name">{bindInfo['wechat_nickname']}</p>
</li>
}
{
bindInfo['qq_nickname'] &&
<li className="popup-bind__account">
{/* qq */}
<i className="popup-bind__icon" data-plat="qq"></i>
<p className="popup-bind__account--name">{bindInfo['qq_nickname']}</p>
</li>
}
{
bindInfo['sina_nickname'] &&
<li className="popup-bind__account">
{/* 微博 */}
<i className="popup-bind__icon" data-plat="sina"></i>
<p className="popup-bind__account--name">{bindInfo['sina_nickname']}</p>
</li>
}
</ul>
<div className="popup-bind__footer">
<button
className="popup-bind__button popup-bind__button--cancle"
onClick={() => this.handleToClose(false)}>取消</button>
<button
className="popup-bind__button popup-bind__button--confirm"
onClick={() => this.toContinueBind(0)}>继续绑定</button>
</div>
</div>
)
}
}
export default ConfirmPhone;
\ No newline at end of file
[data-skip="default"] {
.popup-bind__desc {
width: 249px;
font-size: 15px;
color: #666;
line-height: 21px;
}
.popup-bind__account {
padding: 4px;
}
.popup-bind__account--name {
padding-left: 7px;
font-size: 12px;
color: #999;
}
.popup-bind__icon {
width: 22px;
height: 22px;
}
.popup-bind__footer {
padding: 0 18px;
}
.popup-bind__button {
width: 105px;
height: 30px;
border-radius: 15px;
font-size: 14px;
}
.popup-bind__button--cancle {
border: 1px solid #0099FF;
color: #0099FF;
}
.popup-bind__button--confirm {
border-style: none;
color: #fff;
background-color: #0099FF;
}
}
[data-skip="year"] {
.popup-bind__desc {
width: 269px;
font-size: 12px;
color: #FF2121;
line-height: 18px;
}
.popup-bind__account {
padding: 14px 4px;
}
.popup-bind__account--name {
padding-left: 12px;
font-size: 15px;
color: #090909;
}
.popup-bind__icon {
width: 33px;
height: 33px;
}
.popup-bind__footer {
padding: 0 15px;
}
.popup-bind__button {
width: 130px;
height: 44px;
border-radius: 5px;
font-size: 16px;
}
.popup-bind__button--cancle {
border: 1px solid #090909;
color: #090909;
}
.popup-bind__button--confirm {
border: 1px solid #090909;
color: #090909;
background-color: #FFE319;
}
}
.popup-bind {
text-align: center;
}
.popup-bind__desc {
margin: 10px 15px 0;
text-align: left;
}
.popup-bind__list {
padding: 0 0 10px;
}
.popup-bind__account {
display: flex;
align-items: center;
margin: 0 52px;
text-align: left;
&:nth-child(n+2) {
border-top: 1px solid #E5E5E5;
}
}
.popup-bind__account--name {
margin: 0;
}
.popup-bind__icon {
display: inline-block;
background-size: auto 100%;
background-repeat: no-repeat;
background-position: center;
&[data-plat="mail"] {
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="wachat"] {
background-image: url('https://julyedu-cdn.oss-cn-beijing.aliyuncs.com/newyear20/H5/icon-wechat.png');
}
}
.popup-bind__footer {
display: flex;
align-items: center;
justify-content: space-between;
}
.popup-bind__button {
box-sizing: border-box;
cursor: pointer;
outline: none;
}
.popup-bind__button--cancle {
background-color: transparent;
}
\ No newline at end of file
import React, { Component } from 'react';
import { HeaderBar, Popup } from '@common';
import AddressPopup from '@common/addressPopup/index';
import BindPhone from '@common/bindPhone/index';
import ConfirmPhone from '@common/confirmPhone/index';
import TreasureTeam from './team';
import { http } from '@/utils';
import './index.scss';
......@@ -14,18 +16,30 @@ class MyTreasure extends Component {
isEmpty: false,
seconds: 3,
teams: [],
bindInfo: {
email: 'a',
wechat_nickname: 'b',
qq_nickname: 'c',
sina_nickname: 'd',
}, // 绑定手机号冲突信息
};
}
componentDidMount() {
const { isEnd } = this.state;
const { isEnd, bindInfo } = this.state;
if(isEnd) {
this.startCountDown();
}
this.fetchMyTreasure();
this.fetchActivityStatus();
// 绑定地址--宝箱
Popup({
title: '绑定确认',
content: <ConfirmPhone
bindInfo={bindInfo}
tip={<p className="confirm-treasure__desc">该手机号已绑定以下账号,继续绑定将解除以下绑定状态</p>}
/>
});
}
handleToBindPhone = () => {
......@@ -64,6 +78,10 @@ class MyTreasure extends Component {
isEmpty: false,
teams,
});
}else{
this.setState({
isEmpty: true,
});
}
}
});
......
......@@ -39,22 +39,25 @@ class LiveRoom extends Component {
// 预约直播
subscribe = (id) => {
// 检查是否已登录
this.checkLogin();
http.get(`${API['base-api']}/sys/createLiveQrcode/${id}`).then(res => {
let { errno, data, msg } = res.data;
console.log(res);
if (errno === 200) {
// TODO 显示二维码地址 并且传递给二维码的图片/地址
QRCode.toDataURL(data.url, (err, url) => {
this.setState({
showMark: true,
subUrl: url,
const {hasError, data = {}} = this.props.user;
if(hasError) {
this.props.history.push('/passport/login');
}else{
http.get(`${API['base-api']}/sys/createLiveQrcode/${id}`).then(res => {
let { errno, data, msg } = res.data;
if (errno === 200) {
QRCode.toDataURL(data.url, (err, url) => {
this.setState({
showMark: true,
subUrl: url,
})
})
})
} else {
Toast.info(msg);
}
});
} else {
Toast.info(msg);
}
});
}
}
// 已预约 给提示
tip = () => {
......@@ -62,15 +65,22 @@ class LiveRoom extends Component {
}
// 去直播间
toLivingRoom = (id) => {
this.checkLogin();
window.location.href = `${window.location.protocol}//www.julyedu.com/live/m_room/${id}`
const {hasError, data = {}} = this.props.user;
if(hasError) {
this.props.history.push('/passport/login');
}else{
window.location.href = `${window.location.protocol}//www.julyedu.com/live/m_room/${id}`
}
}
// 查看回放
checkVideo = (url) => {
this.checkLogin();
// TODO 这里需要课程ID 如何获取?
const vCourseId = url.split('/')[0];
history.push(`/play/video?id=${vCourseId}`)
const {hasError, data = {}} = this.props.user;
if(hasError) {
this.props.history.push('/passport/login');
}else{
const vCourseId = url.split('/')[0];
history.push(`/play/video?id=${vCourseId}`)
}
}
// 关闭弹框
closePopup = () => {
......@@ -80,15 +90,8 @@ class LiveRoom extends Component {
// 关闭弹框的时候再次查询接口 查询预约状态
this.getLiveInfo();
}
// 检查是否登录
checkLogin = () => {
const {hasError, data = {}} = this.props.user;
if(hasError) { // 未登录
return;
}
}
// TODO APP内需要保存图片 是否还是这样做 需要确认
// APP内需要保存图片 是否还是这样做 需要确认
saveImage = () => {
let version = getParam('version')
version = typeof version === 'string' ? version.replace('.', '').replace('.', '').slice(0, 3) : ''
......
import React, { Component } from 'react';
import './team.scss'
import { getParam, http, SendMessageToApp, browser } from "@/utils"
import { Toast } from 'antd-mobile'
import { Toast } from 'antd-mobile';
import {withRouter} from 'react-router-dom';
import {compose} from "redux"
import { connect } from "react-redux";
export default class TeamInfo extends Component {
class TeamInfo extends Component {
constructor(props) {
super(props);
this.state = {
is_my_team: true, // 是否有自己的队伍
prize_info: {
name: '',
stage_no: 0,
},
is_my_team: false, // 是否有自己的队伍
prize_info: [],
info: {
removable: 0,
total: 0
},
member: [],
removable_data: [],
my_team: {},
}
}
......@@ -24,17 +26,19 @@ export default class TeamInfo extends Component {
this.getTeamInfo();
}
// 获取队伍信息
getTeamInfo = () => {
http.get(`${API.home}/sys/treasure/teamInfo`).then(res => {
const { code, data, msg } = res.data;
if (code === 200) {
console.log(data);
const { prize_info, is_my_team, info, member } = data;
const { prize_info, is_my_team, info, member, removable_data, my_team } = data;
this.setState({
prize_info,
is_my_team,
info,
member: this.format(member)
member: this.fillTeam(member),
removable_data,
my_team
})
} else {
Toast.info(msg);
......@@ -42,7 +46,50 @@ export default class TeamInfo extends Component {
})
}
format = (list) => {
// 跳转到我的宝箱页
toYearTreasure = (close) => {
if(this.props.user.hasError) {
this.props.history.push('/passport/login');
} else {
let search = '';
if(close) {
const {removable_data, info: {removable}} = this.state;
if(removable > 0) {
let current = removable_data[0];
search = `?team_num=${current.team_num}&owner_uid=${current.captain_uid}`;
}
}
this.props.history.push(`/year/yearTreasure${search}`);
}
}
// 邀请好友组队
createTeam = () => {
if(this.props.user.hasError) {
this.props.history.push('/passport/login');
} else {
const {is_my_team, my_team: {treasure_code}} = this.state;
if(is_my_team) { // 有自己的队伍
// 直接跳转
this.props.history.push('/activity/newyear-2019/landing?origin=1&treasure_code=' + treasure_code);
}else{ // 没自己的队伍
// 请求创建队伍的接口
http.get(`${API.home}/sys/treasure/createMyTeam`).then(res => {
const { code, data, msg } = res.data;
if (code === 200) {
const { treasure_code } = data;
this.props.history.push('/activity/newyear-2019/landing?origin=1&treasure_code=' + treasure_code);
} else {
Toast.info(msg);
}
});
}
}
}
// 队伍成员信息必须满五个 不满的需要填充
fillTeam = (list) => {
let len = list.length;
for(let i=0;i<5-len;i++) {
list.push({
......@@ -55,7 +102,12 @@ export default class TeamInfo extends Component {
}
render() {
const { prize_info: { name, stage_no }, is_my_team, info: {removable, total}, member } = this.state;
const { prize_info, is_my_team, info: {removable, total}, member } = this.state;
let name = '', stage_no = 0;
if(prize_info.length > 0) {
name = prize_info[0].name;
stage_no = prize_info[0].stage_no;
}
// 显示文案控制
let Text = '';
if(total === 0) {
......@@ -82,7 +134,11 @@ export default class TeamInfo extends Component {
<img className='head__image' src={item.head_img} alt=""/>
)
}
{
index === 0 ? (
<img className='caption__flag' src="https://julyedu-cdn.oss-cn-beijing.aliyuncs.com/newyear20/H5/caption.png" alt=""/>
) : (null)
}
<div className='shadow'></div>
</div>
<div className={`member__join ${item.nobody ? '' : 'join'}`}></div>
......@@ -93,20 +149,34 @@ export default class TeamInfo extends Component {
</ul>
<div className='box__number'>
<img src="https://julyedu-cdn.oss-cn-beijing.aliyuncs.com/newyear20/H5/treasure-box-icon.png" alt="" />
<p className='box__text'>
<img onClick={() => this.toYearTreasure(true)} src="https://julyedu-cdn.oss-cn-beijing.aliyuncs.com/newyear20/H5/treasure-box-icon.png" alt="" />
<p onClick={() => this.toYearTreasure(false)} className='box__text'>
{Text}
</p>
<img className='position__arrow' src="https://julyedu-cdn.oss-cn-beijing.aliyuncs.com/newyear20/H5/arrow_jinzhan.png" alt=""/>
{
removable > 0 && (
<div className='position__number'>{removable}</div>
)
}
</div>
</div>
<div className='invite__btn'>
<div onClick={this.createTeam} className='invite__btn'>
{
is_my_team ? ('继续组队') : ('组队开宝箱')
}
</div>
<p className='stage_prize'>{`第${stage_no}次必中${name}`}</p>
{
stage_no > 0 && name && <p className='stage_prize'>{`第${stage_no}次必中${name}`}</p>
}
</div>
)
}
}
export default compose(
connect(
state => ({user: state.user}),
null
),
withRouter
)(TeamInfo)
......@@ -30,12 +30,12 @@
margin-left: 1px;
&:first-child {
margin-left: 0;
.member__join{
.member__join {
border-radius: 2px 0 0 2px;
}
}
&:last-child {
.member__join{
.member__join {
border-radius: 0 2px 2px 0;
}
}
......@@ -58,6 +58,13 @@
position: absolute;
bottom: -6px;
}
.caption__flag {
position: absolute;
width: 18px;
height: 10px;
left: 50%;
top: 0;
}
}
.member__join {
width: 40px;
......@@ -66,8 +73,9 @@
box-shadow: 1px 1px 2px 0px rgba(3, 52, 91, 0.35);
}
.join {
background:rgba(255,221,29,1);
box-shadow:1px 2px 2px 0px rgba(253,253,253,0.46) inset, 1px 2px 2px 0px rgba(253,253,253,0.46) inset;
background: rgba(255, 221, 29, 1);
box-shadow: 1px 2px 2px 0px rgba(253, 253, 253, 0.46) inset,
1px 2px 2px 0px rgba(253, 253, 253, 0.46) inset;
}
}
}
......@@ -87,7 +95,7 @@
.box__text {
width: 1000px;
font-size: 100px;
transform: scale(0.1) ;
transform: scale(0.1);
text-decoration: underline;
color: rgba(255, 227, 0, 1);
position: absolute;
......@@ -101,6 +109,22 @@
left: -7px;
top: 18px;
}
.position__number {
min-width: 22px;
height: 18px;
font-size: 12px;
background: rgba(255, 60, 22, 1);
border: 1px solid rgba(255, 227, 0, 1);
border-radius: 9px 9px 9px 0px;
color: rgba(255, 227, 0, 1);
position: absolute;
display: flex;
justify-content: center;
align-items: center;
padding: 0 5px;
right: -4px;
top: -4px;
}
}
}
.invite__btn {
......
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