Commit b0d657c4 by wangshuo

宝箱活动

parent be3a798d
.box-container {
position: relative;
background: #327443 url("https://julyedu-cdn.oss-cn-beijing.aliyuncs.com/newyear20/PC/sd_nr_bj2.png") repeat-y;
background-size: 100% auto;
padding: 14px 0;
.image-box {
height: 100%;
}
@mixin common-deco($bg) {
content: '';
position: absolute;
left: 0;
width: 100%;
height: 14px;
display: block;
background: url($bg) no-repeat;
background-size: 375px auto;
}
&::before {
@include common-deco("https://julyedu-cdn.oss-cn-beijing.aliyuncs.com/newyear20/PC/sd_nr_bj1.png");
top: 0;
}
&::after {
@include common-deco("https://julyedu-cdn.oss-cn-beijing.aliyuncs.com/newyear20/PC/sd_nr_bj3.png");
bottom: 0;
}
}
import React, { Component } from 'react'
import './box-container.scss'
class Container extends Component {
render() {
return (
<div className={'box-container'}>
<div className="image-box">
{this.props.children}
</div>
</div>
)
}
}
export default Container
import React, { Component } from 'react'
import './index.scss'
export default class CommonContainer extends Component {
constructor(props) {
super(props)
}
render() {
const { id } = this.props;
return (
<div className='common_container' id={id}>
<div className='container_top'></div>
<div className='container_content'>
{
this.props.title &&
<div className='title_container'>
<i></i>
<p>{this.props.title}</p>
<i></i>
</div>
}
{
React.Children.map(this.props.children, function (child) {
return <>{child}</>;
})
}
</div>
<div className='container_bottom'></div>
</div>
)
}
}
.common_container {
margin-bottom: 35px;
.title_container {
width: 100%;
display: flex;
flex-direction: column;
justify-content: center;
align-content: center;
i {
width: 230px;
height: 2px;
margin: auto;
background: linear-gradient(
90deg,
rgba(254, 228, 29, 0) 0%,
rgba(254, 228, 29, 0.98) 48%,
rgba(254, 228, 29, 0) 100%
);
margin: 0 auto;
}
p {
font-size: 18px;
line-height: 18px;
font-weight: 500;
color: rgba(254, 228, 29, 1);
margin: 8px auto;
background: linear-gradient(
0deg,
rgba(254, 228, 29, 1) 23.9013671875%,
rgba(255, 204, 0, 1) 50.146484375%,
rgba(254, 228, 29, 1) 75%
);
background-clip: text;
-webkit-text-fill-color: transparent;
}
}
.container_top {
background: url("https://julyedu-cdn.oss-cn-beijing.aliyuncs.com/newyear20/H5/m_top_bj.png")
center center no-repeat;
background-size: 100% 100%;
width: 100%;
height: 18px;
}
.container_bottom {
background: url("https://julyedu-cdn.oss-cn-beijing.aliyuncs.com/newyear20/H5/m_bottom_bj.png")
center center no-repeat;
background-size: 100% 100%;
width: 100%;
height: 22px;
}
.container_content {
background: url("https://julyedu-cdn.oss-cn-beijing.aliyuncs.com/newyear20/H5/m_middle_bj.png");
background-size: contain;
width: 100%;
min-height: 25px;
margin: -1px 0;
padding: 6px 15px;
}
}
import React, { Component } from 'react';
import './index.scss';
export default class index extends Component {
constructor(props) {
super(props);
}
computedStyle = () => {
return {
'top': `${this.props.top}px`,
'width': `${this.props.width}px`
}
}
// 控制点击空白处是否关闭弹窗 需要传递一个boolean属性 mark
closePopup = () => {
if(this.props.mark) {
this.props.closePopup();
}
}
render() {
return (
<div className='popup__container' onClick={this.closePopup}>
<div className='content__container' style={this.computedStyle()} onClick={(e) => {e.stopPropagation()}}>
<img className="close__btn" onClick={this.props.closePopup} src='https://julyedu-cdn.oss-cn-beijing.aliyuncs.com/newyear20/H5/close-btn.png' alt="" />
{
React.Children.map(this.props.children, function (child) {
return <>{child}</>;
})
}
</div>
</div>
)
}
}
.popup__container {
position: fixed;
left: 0;
top: 0;
width: 100vw;
height: 100vh;
background: rgba(0, 0, 0, 0.6);
z-index: 99;
.content__container {
width: 320px;
min-height: 240px;
border-radius: 5px;
background: rgba(255,255,255,1);
position: absolute;
left: 50%;
transform: translateX(-50%);
top: 160px;
.close__btn {
position: absolute;
left: 50%;
transform: translateX(-50%);
width: 33px;
height: 33px;
bottom: -57px
}
}
}
\ No newline at end of file
import React from 'react';
import './index.scss';
export default (props) => {
console.log(props);
const {
data: {
team_num = 1,
lack_member = 4,
member = [],
},
handleToInvite
} = props;
const members = new Array(5).fill({});
return (
<div className="team-success">
<h2 className="team-success__title">创建成功</h2>
<p className="team-success__tip">
{<span>{team_num}</span>}号队伍 还差{<span>{lack_member}</span>}名队员即可获得宝箱哦~
</p>
<i className="team-success__icon"></i>
<ul className='team-success__member members'>
{
members.map((item, index) => {
const _member = member[index]
return (
<li className="member-item" key={index}>
{
_member && _member['is_captain'] && <sup className="member-item__captain">队长</sup>
}
<img
className="member-item__avatar"
src={
_member
? _member['head_img']
: "https://julyedu-cdn.oss-cn-beijing.aliyuncs.com/newyear20/H5/not-joined-placeholder.png"
}
alt=""/>
</li>
);
})
}
</ul>
<button type={'button'} className="team-success__button" onClick={handleToInvite}>邀请好友加入队伍</button>
</div>
)
}
\ No newline at end of file
.team-success__title {
margin: 10px 0 0;
font-size: 18px;
color: #111;
text-align: center;
line-height: 1;
}
.team-success__tip {
margin: 12px 0 0;
font-size: 15px;
color: #666;
text-align: center;
line-height: 1;
span {
color: #FF2121;
}
}
.team-success__icon {
display: block;
width: 120px;
height: 72px;
margin: 20px auto;
background-size: cover;
background-image: url('https://julyedu-cdn.oss-cn-beijing.aliyuncs.com/newyear20/H5/treasure-box-icon.png');
}
.team-success__member {
display: flex;
padding: 0 12px;
.member-item {
position: relative;
margin: 0 8px;
}
.member-item__captain {
position: absolute;
top: -13px;
right: -10px;
width: 30px;
height: 16px;
border: 1px solid rgba(255, 255, 255, 1);
border-radius: 8px 8px 8px 0;
color: #0E7442;
font-size: 10px;
text-align: center;
line-height: 16px;
background: rgba(255, 227, 0, 1);
}
.member-item__avatar {
width: 44px;
height: 44px;
border-radius: 50%;
}
}
.team-success__button {
display: block;
width: 270px;
height: 44px;
margin: 20px auto;
padding: 0;
border: 1px solid #090909;
border-radius: 5px;
box-sizing: border-box;
font-size: 16px;
color: #090909;
line-height: 44px;
background-color: #FFE319;
}
\ No newline at end of file
import React, { Component } from 'react'
import { http } from "@/utils"
import './prizes.scss'
import { Popup } from "@common/index"
import { Toast } from "antd-mobile"
import Loadable from '@loadable/component'
const SystemBulletScreen = Loadable(() => import(/* webpackChunkName: 'system-notices' */'@components/activity/newyear-2019/common/system-bullet-screen'))
class Prizes extends Component {
prizeBox
prizeList
bg
innerBox
closeIcon = 'https://julyedu-cdn.oss-cn-beijing.aliyuncs.com/newyear20/H5/close-btn.png'
state = {
prizes: [],
notices: [],
rule: [],
unfoldList: false,
}
componentDidMount() {
this.getPrizes()
}
getPrizes = () => {
http.get(`${API.home}/sys/prize_data`)
.then(res => {
const {code, data, msg} = res.data
if (code == 200) {
this.setState({
prizes: data['prize_data'],
notices: data['notices'],
rule: data['rule']
})
} else {
Toast.info(msg, 2, null, false)
}
})
}
showRules = () => {
Popup({
title: '组队开宝箱活动规则',
className: 'landing-treasure-rules',
content: <div dangerouslySetInnerHTML={{__html: this.state.rule}}/>,
closeIcon: this.closeIcon
})
}
showMore = () => {
this.setState(prev => {
if (this.state.unfoldList) {
this.bg.style = this.innerBox.style = this.prizeBox.style = ''
} else {
let headHeight = parseFloat(getComputedStyle(this.prizeBox, ':before').getPropertyValue('height')),
footerHeight = parseFloat(getComputedStyle(this.prizeBox, ':after').getPropertyValue('height')),
innerOffsetTop = 0.12458,
footerOffsetTop = 0.595,
h = this.prizeList.scrollHeight,
scrollListHeight = headHeight + h - (innerOffsetTop * headHeight) - (footerOffsetTop * footerHeight) + footerHeight,
bottomOffset = 27
this.prizeBox.style.height = `${scrollListHeight + bottomOffset}px`
this.innerBox.style.height = `${h}px`
this.bg.style.height = `${h - footerHeight + innerOffsetTop * headHeight + bottomOffset}px`
}
return {unfoldList: !prev.unfoldList}
})
}
render() {
const {
showSystemNotices
} = this.props
const {notices} = this.state
return (
<>
{(showSystemNotices && notices && notices.length) ? <SystemBulletScreen bullets={notices}/> : null}
<div className={'prizes-box'} ref={el => this.prizeBox = el}>
<a href="javascript:;" className='rule-btn' onClick={this.showRules}>活动规则 > </a>
<div className={`bg`} ref={el => this.bg = el}/>
<div className={`inner-box`} ref={el => this.innerBox = el}>
<ul className='prize-list' ref={el => this.prizeList = el}>
{
this.state.prizes.map((item, index) => {
return (
<li key={index}>
{
item.img_name
? <i className="prize-list__image" style={{
backgroundImage: `url(${item.img_name})`
}}/>
: <i className="prize-list__image"/>
}
{/* <img src={item.img_name} alt=""/> */}
{
item.is_captain != 0 && <span className='captain top-tag'>队长专属</span>
}
{
item.mode === 2 && <span className='stage top-tag'>{item.stage_no}个必中</span>
}
{
item.grant_max
?
<div className='bottom-bar'>
<div className="progress-bar"><span className={'progress'} style={{width: `${(item.surplus / item.grant_max) * 100}%`}}/></div>
<span>限量{item.grant_max}</span>
</div>
: <span className='no-limit'>不限量</span>
}
</li>
)
})
}
<li>
<img src="https://julyedu-cdn.oss-cn-beijing.aliyuncs.com/newyear20/prize-placeholder.png" alt=""/>
</li>
</ul>
</div>
<div className="show-more" onClick={this.showMore}>
{
this.state.unfoldList
? <div>
收起
<img src="https://julyedu-cdn.oss-cn-beijing.aliyuncs.com/newyear20/H5/fold-icon.png" alt=""/>
</div>
: <div>
查看全部奖品
<img src="https://julyedu-cdn.oss-cn-beijing.aliyuncs.com/newyear20/H5/unfold-icon.png" alt=""/>
</div>
}
</div>
</div>
</>
)
}
}
export default Prizes
.trans-height {
transition: height .25s ease-in-out;
}
.prizes-box {
@extend .trans-height;
position: relative;
height: 348px;
background-size: 100% auto;
.show-more {
position: absolute;
bottom: 30px;
left: 50%;
transform: translateX(-50%);
width: 125px;
height: 27px;
background: #FF2121;
border: 2px solid rgba(255, 33, 33, 1);
border-radius: 5px 5px 0 0;
font-size: 13px;
color: #fff;
line-height: 27px;
text-align: center;
z-index: 20;
img {
margin-left: 4.5px;
width: 10.05px;
}
}
.rule-btn {
position: absolute;
top: 32.5px;
left: 50%;
transform: translateX(-50%);
color: #FFDD1D;
font-size: 12px;
text-decoration: underline;
}
@mixin common-deco($bg) {
content: '';
display: block;
width: 100%;
background: url($bg) no-repeat;
background-size: 100% auto;
}
&::before {
@include common-deco('https://julyedu-cdn.oss-cn-beijing.aliyuncs.com/newyear20/H5/landing-box-head.png');
height: 148.5px;
}
&::after {
@include common-deco('https://julyedu-cdn.oss-cn-beijing.aliyuncs.com/newyear20/H5/landing-box-footer.png');
height: 85px;
margin-top: -1px;
}
.bg {
@extend .trans-height;
width: 100%;
height: 115px;
margin-top: -1px;
overflow: hidden;
z-index: 10;
background: url("https://julyedu-cdn.oss-cn-beijing.aliyuncs.com/newyear20/H5/landing-box-bg.png") repeat-y;
background-size: 100% auto;
}
.inner-box {
@extend .trans-height;
position: absolute;
top: 130px;
left: 0;
width: 100%;
z-index: 20;
height: 187px;
overflow: hidden;
}
.prize-list {
display: flex;
flex-flow: wrap;
padding: 0 57px;
& li:nth-of-type(2n) {
margin-right: 0;
}
li {
position: relative;
width: 125px;
height: 99px;
background: rgba(255, 255, 255, 1);
border: 2px solid rgba(255, 227, 0, 1);
box-shadow: 0 2px 4px 0 rgba(0, 0, 0, 0.1);
border-radius: 1px;
margin-right: 10.5px;
margin-bottom: 6.5px;
.prize-list__image {
display: block;
width: 100%;
height: 100%;
background-position: center;
background-size: cover;
}
img {
width: 90px;
object-fit: contain;
}
}
& li:last-child {
display: flex;
align-items: center;
justify-content: center;
}
.top-tag {
position: absolute;
top: 0;
right: 0;
border-radius: 0 0 0 4px;
font-size: 12px;
line-height: 16px;
text-align: center;
padding: 0 4px;
color: #fff;
}
.captain {
background: linear-gradient(270deg, rgba(255, 93, 0, 1) 0%, rgba(255, 23, 0, 1) 100%);
}
.stage {
background: linear-gradient(-90deg, rgba(0, 75, 251, 1) 0%, rgba(0, 156, 255, 1) 100%);
}
.no-limit {
position: absolute;
bottom: 0;
right: 0;
background: rgba(0, 0, 0, .8);
font-size: 12px;
color: #fff;
padding: 0 4px;
border-radius: 6px 0 0 0;
}
.bottom-bar {
position: absolute;
bottom: 0;
left: 0;
width: 100%;
//height: 18px;
padding: 0 5px;
display: flex;
justify-content: space-between;
align-items: center;
background: rgba(0, 0, 0, .8);
font-size: 12px;
color: #fff;
.progress-bar {
position: relative;
flex: 0 1 45px;
height: 2px;
background: #fff;
border-radius: 1px;
.progress {
position: absolute;
right: 0;
top: 0;
//width: 80%;
height: 100%;
background: linear-gradient(-90deg, rgba(255, 140, 0, 1) 0%, rgba(255, 23, 0, 1) 100%);
border-radius: 1px;
}
}
}
}
}
.common_container {
.container_content {
.prizes-box {
margin: 0 -15px;
}
}
}
.landing-treasure-rules {
width: 320px;
&.popup-container {
top: 50%;
transform: translate(-50%, -50%);
.title {
font-size: 18px;
color: #111111;
}
}
.content {
padding: 0 19px 15px;
margin-top: 22px;
color: #666666;
font-size: 14px;
li {
margin-bottom: 5px;
}
}
}
import React, { Component } from 'react';
import { http } from '@/utils';
import './index.scss';
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(data);
if(data.bind_phone) {
setTimeout(() => {
handleToBindPhone(data.id);
}, 500);
}else if(data.bind_address) {
setTimeout(() => {
handleToBindAddress(data.id, data.prize_name);
}, 500);
}
}else if(code === 12000) {
// 请先绑定手机号再拆宝箱
handleToBindPhone();
}else if(code === 12001) {
// 请先填写收货地址再拆宝箱
handleToBindAddress();
}
});
}
render() {
const {
ids,
data: {
member = [],
prize_img,
prize_name,
},
handleToInvite,
children,
} = this.props;
return (
<div data-skip="split">
<h2 className="split-success__title">恭喜你获得</h2>
<div className="split-success__image">
<img src={prize_img} alt=""/>
</div>
<p className="split-success__prize">{prize_name}</p>
{children}
<div className="split-success__member">
{
member.map((item, index) => (
<div className="member-item" key={index}>
<span className="member-item__avatar" style={this.computedBg(item.avatar)}>
{
item.is_captain && <i className="member-item__captain">队长</i>
}
</span>
{
item.prize
? <span className="member-item__prize">{item.prize}</span>
: <span className="member-item__prize">尚未开宝箱</span>
}
</div>
))
}
</div>
{
ids.length > 0
? <button className="split-success__jump" onClick={this.continueSplitTreasure}>继续开宝箱</button>
: <button className="split-success__jump" onClick={handleToInvite}>继续组队开宝箱</button>
}
</div>
);
}
}
export default SplitSuccess;
\ No newline at end of file
[data-skip="split"] {
text-align: center;
.split-success__title {
margin: 10px 0 0;
font-size: 18px;
color: #111;
line-height: 1;
}
.split-success__image {
width: 130px;
height: 103px;
margin: 12px auto 0;
border: 2px solid #CDCDCD;
box-sizing: border-box;
overflow: hidden;
img {
display: block;
width: 100%;
}
}
.split-success__prize {
margin: 8px 0 0;
font-size: 15px;
font-weight: 500;
color: #FF232D;
text-align: center;
line-height: 1;
}
.team-result {
display: inline-block;
margin: 8px 0 0;
font-size: 12px;
color: #666;
text-align: center;
line-height: 1;
span {
text-decoration: underline;
}
}
.split-success__member {
margin: 18px 18px 0;
padding: 4px 12px;
border-radius: 6px;
background-color: #EFEFEF;
}
.member-item {
display: flex;
align-items: center;
margin: 8px 0;
}
.member-item__avatar {
display: inline-block;
position: relative;
width: 25px;
height: 25px;
border-radius: 50%;
background-color: #fff;
background-size: cover;
}
.member-item__captain {
position: absolute;
top: -14px;
right: -18px;
width: 30px;
height: 18px;
border: 1px solid #fff;
border-radius: 9px 9px 9px 0;
font-size: 12px;
font-style: normal;
color: #0B7B45;
text-align: center;
background-color: #FFE319;
}
.member-item__prize {
padding-left: 8px;
font-size: 12px;
color: #090909;
}
.split-success__jump {
width: 270px;
height: 44px;
margin: 18px 25px 8px;
border: 1px solid #090909;
border-radius: 5px;
box-sizing: border-box;
font-size: 16px;
color: #090909;
text-align: center;
line-height: 44px;
background-color: #FFE319;
}
}
\ No newline at end of file
import React, { Component } from 'react'
import Swiper from 'swiper'
import 'swiper/dist/css/swiper.min.css'
import './system-bullet-screen.scss'
class SystemBulletScreen extends Component {
swiper
count = 0
sysNotice
state = {
showNotices: true
}
componentDidMount() {
this.initializeSwiper()
}
componentWillUnmount() {
this.swiper && this.swiper.destroy()
}
initializeSwiper = () => {
const _this = this
this.swiper = new Swiper('.sys-bullet-screen-swiper-container', {
allowTouchMove: false,
direction: 'vertical',
loop: true,
on: {
init() {
Array.from(this.slides).forEach(item => {
item.querySelector('span').addEventListener('transitionend', _this.transitionEnd)
})
},
slideChangeTransitionEnd() {
_this.slideHorizontal(this)
},
transitionEnd() {
const el = this.slides[this.previousIndex].querySelector('span')
el.style.transition = 'unset'
el.style.transform = 'translate3d(0,0,0)'
}
}
})
}
slideHorizontal = (swiper) => {
let el = swiper.slides[swiper.activeIndex],
content = el.querySelector('span'),
contentWidth = content.offsetWidth,
wrapperWidth = el.clientWidth
const co = 131.25
if (contentWidth > wrapperWidth) {
content.style.transition = `transform ${contentWidth / co}s linear`
setTimeout(() => {
content.style.transform = `translate3d(${-(contentWidth - wrapperWidth) - 10}px,0,0)`
}, 1000)
} else {
const {bullets} = this.props
const len = bullets.length * 3
setTimeout(() => {
if (++this.count === len) {
this.sysNotice.style.height = `0px`
}
(swiper && !swiper.destroyed) && swiper.slideNext()
}, 3000)
}
}
transitionEnd = () => {
const {bullets} = this.props
const len = bullets.length * 3
if (++this.count === len) {
setTimeout(() => {
this.sysNotice.style.height = `0px`
}, 2000)
} else {
setTimeout(() => {
this.swiper && this.swiper.slideNext()
}, 1000)
}
}
removeSystemNotices = e => {
e.persist()
if (e.target === this.sysNotice) {
this.setState({
showNotices: false
})
}
}
render() {
const {
bullets
} = this.props
return (
this.state.showNotices &&
<div id="system-bullet-screen" onTransitionEnd={this.removeSystemNotices} ref={el => this.sysNotice = el}>
<img className='avatar'
src='https://julyedu-cdn.oss-cn-beijing.aliyuncs.com/newyear20/system-notice-icon.png' alt=""/>
<div className='sys-bullet-screen-swiper-container'>
<ul className="swiper-wrapper">
{
(bullets && bullets.length) ? bullets.map((item, index) => {
return (
<li className="swiper-slide" key={index}>
<span>{item}</span>
</li>
)
})
: null
}
</ul>
</div>
</div>
)
}
}
export default SystemBulletScreen
@import "../user-bullet-screen/bullet-screen";
#system-bullet-screen {
@extend .bullet-screen;
overflow: hidden;
margin-top: 11px;
margin-bottom: 16px;
padding-left: 2px;
display: flex;
align-items: center;
transition: height .1s ease-out;
.sys-bullet-screen-swiper-container{
height: 100%;
}
ul {
flex: auto;
max-width: 293px;
}
li {
overflow: hidden;
height: 30px;
span {
display: inline-block;
white-space: nowrap;
overflow: visible;
line-height: 30px;
}
}
}
.bullet-screen{
width: 329px;
height: 30px;
margin: 0 auto 28px;
background: rgba(0, 0, 0, .6);
border-radius: 15px;
line-height: 30px;
text-align: left;
li {
height: 100%;
padding: 2px;
line-height: 26px;
display: flex;
align-items: center;
}
.avatar {
width: 26px;
height: 26px;
border-radius: 50%;
margin-right: 7px;
vertical-align: middle;
}
& span:nth-of-type(1) {
margin-right: 5px;
}
span {
font-size: 12px;
color: #fff;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
}
#user-bullet-screen {
@extend .bullet-screen
}
import React, { Component } from 'react'
import { http } from "@/utils"
import Swiper from 'swiper'
import 'swiper/dist/css/swiper.min.css'
import './bullet-screen.scss'
class UserBulletScreen extends Component {
swiper
state = {
bulletScreenData: []
}
componentDidMount() {
this.getBulletScreenData(true)
}
componentWillUnmount() {
this.swiper && this.swiper.destroy()
}
initializeBulletScreen = () => {
const _this = this
const slidesPerRequest = 20
const indexArray = [...Array(slidesPerRequest - 1).keys()]
let removed = false
this.swiper = new Swiper('.swiper-container', {
direction: 'vertical',
allowTouchMove: false,
autoplay: true,
on: {
transitionEnd() {
if (this.slides.length > slidesPerRequest) {
this.removeSlide(0)
this.autoplay.start()
}
if (this.activeIndex === this.slides.length - 1 && !removed) {
this.autoplay.stop()
_this.getBulletScreenData().then(res => {
removed = true
this.removeSlide(indexArray)
this.appendSlide(_this.getSlides(res))
setTimeout(() => {
this.autoplay.start()
removed = false
})
})
}
}
}
})
}
getSlides = list => list.map(item => {
return `
<li class="swiper-slide">
<img class="avatar" src="${item.avatar_file}" alt="">
<span>${item.user_name} ${item.msg}</span>
</li>
`
})
getBulletScreenData = (initializeSwiper = false) => {
return http.get(`${API.home}/sys/barrage_data`)
.then(res => {
const {data, code} = res.data
if (code == 200) {
if (initializeSwiper) {
this.setState({
bulletScreenData: data
}, () => {
this.initializeBulletScreen()
})
} else {
return data
}
}
})
}
render() {
const {bulletScreenData} = this.state
return (
<div id="user-bullet-screen" className='swiper-container'>
<ul className='swiper-wrapper'>
{
bulletScreenData.length && bulletScreenData.map((item, index) => {
return (
<li className='swiper-slide' key={index}>
<img src={item['avatar_file']}
alt="" className="avatar"/>
<span>{item.user_name} {item.msg}</span>
</li>
)
})
}
</ul>
</div>
)
}
}
export default UserBulletScreen
.sup {
position: absolute;
right: -10px;
top: 0;
transform: translateY(-50%);
width: 30px;
height: 16px;
background: rgba(255, 227, 0, 1);
border: 1px solid rgba(255, 255, 255, 1);
border-radius: 8px 8px 8px 0;
color: #0E7442;
font-size: 10px;
text-align: center;
line-height: 16px;
}
#landing {
background: #BC2A18;
text-align: center;
min-height: 100%;
#to-square {
position: fixed;
width: 100%;
height: 30px;
background: #FF2121;
color: #fff;
font-size: 14px;
line-height: 30px;
text-align: center;
z-index: 21;
}
.box-container {
width: 100%;
}
.snow-deco {
position: absolute;
top: 30px;
left: 0;
display: block;
width: 100%;
height: 68px;
background: url("https://julyedu-cdn.oss-cn-beijing.aliyuncs.com/newyear20/H5/snow-deco.png") no-repeat;
background-size: contain;
&.standby {
top: 0;
}
}
.main-avatar {
width: 49px;
height: 49px;
border-radius: 50%;
margin-bottom: 5px;
margin-top: 55px;
object-fit: cover;
}
.des {
font-size: 14px;
color: #FFDC1E;
span {
display: inline-block;
width: 15px;
height: 15px;
line-height: 16px;
color: #327443;
border-radius: 50%;
background: #FFDC1E;
}
}
.standby-space {
height: 25px;
}
.standby-tip {
position: relative;
width: 270px;
height: 32px;
background: #FFDE00;
border-radius: 5px;
margin: 0 auto -40px;
line-height: 32px;
text-align: center;
color: #202426;
font-size: 15px;
&::after {
content: '';
display: block;
position: absolute;
top: -120%;
right: -6%;
width: 50px;
height: 38px;
background: url("https://julyedu-cdn.oss-cn-beijing.aliyuncs.com/newyear20/H5/standby-share-tip-icon.png");
background-size: contain;
}
}
.group {
ul.member {
display: flex;
padding: 0 49px;
}
& li:nth-last-child(1) {
margin-right: 0;
}
li {
margin-right: 24.5px;
}
.avatar-wrapper {
position: relative;
&::after {
content: '';
display: block;
position: absolute;
bottom: 0;
left: 50%;
transform: translateX(-50%);
width: 22px;
height: 3px;
background: #243529;
opacity: 0.8;
border-radius: 50%;
}
sup {
@extend .sup;
}
img {
width: 36px;
height: 36px;
border-radius: 50%;
border: 1px solid #fff;
}
}
.bars {
display: flex;
padding-left: 37.5px;
margin-top: 15px;
& li:nth-child(1) {
border-radius: 2px 0 0 2px;
}
& li:nth-last-child(1) {
border-radius: 0 2px 2px 0;
margin-right: 0;
}
li {
width: 59px;
height: 5px;
margin-right: 1.5px;
background: #035B34;
&.active {
background: #FFDD1D;
}
}
}
&-des {
margin-top: 27px;
font-size: 14px;
color: #FFE300;
}
.invite-btn {
width: 320px;
height: 44px;
line-height: 44px;
margin: 14.5px auto 57px;
color: #0B7B45;
font-size: 15px;
background: #FFE300;
border: 0;
outline: 0;
-webkit-appearance: none;
border-radius: 3px;
font-family: "HiraginoSansGB-W6", "Helvetica Neue", Helvetica, "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei", "微软雅黑", Arial, sans-serif;
}
.certainly-prompt {
margin-top: 27px;
padding-bottom: 16px;
font-size: 14px;
color: #FFE300;
}
}
.activity-end {
display: flex;
flex-flow: column;
align-items: center;
margin-top: 26px;
font-size: 14px;
color: #FFE300;
div:first-child {
margin-bottom: 5px;
}
div:nth-child(2) {
margin-bottom: 19px;
}
img {
width: 120px;
height: 120px;
margin-bottom: 12px;
}
div:last-child {
color: #fff;
font-size: 12px;
}
}
.am-whitespace.am-whitespace-xl {
height: 35px;
}
.loading{
transform: scale(1);
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
background: rgba(0,0,0,.8);
z-index: 1000;
display: flex;
align-items: center;
justify-content: center;
}
}
.popup-container {
.tip {
font-size: 15px;
line-height: 37px;
color: #666;
text-align: center;
span {
color: #FF2121;
}
}
}
.popup-button {
width: 270px;
height: 44px;
padding: 0;
margin-top: 20px;
background: #FFE319;
border: 1px solid #090909;
border-radius: 5px;
line-height: 44px;
font-size: 16px;
color: #090909;
}
.landing-treasure-rules {
width: 320px;
&.popup-container {
.title {
font-size: 18px;
color: #111111;
}
}
.content {
padding: 0 19px 15px;
margin-top: 22px;
color: #666666;
font-size: 14px;
li {
margin-bottom: 5px;
}
}
}
.landing-join-success-wrapper {
&.popup-container {
width: 320px;
text-align: center;
.title {
img {
width: 54px;
height: 54px;
margin-bottom: 10px;
}
font-size: 18px;
color: #111111;
}
}
/*.tip {
font-size: 15px;
line-height: 37px;
color: #666;
text-align: center;
}*/
button {
@extend .popup-button;
}
}
.landing-create-success {
text-align: center;
&.popup-container {
width: 320px;
padding: 20px;
.title {
font-size: 18px;
color: #111111;
}
}
img.treasure-box {
margin: 20px 0;
width: 120px;
height: 72px;
}
.members {
display: flex;
& li:nth-last-child(1) {
margin-right: 0;
}
li {
position: relative;
margin-right: 15px;
}
.avatar {
width: 44px;
height: 44px;
border-radius: 50%;
}
sup {
@extend .sup;
}
}
button {
@extend .popup-button;
}
}
.landing-remind {
&.popup-container {
width: 320px;
text-align: center;
padding: 20px 30px;
.title {
font-size: 18px;
color: #111;
margin-bottom: 8px;
}
}
img {
margin: 15px 0 16px;
width: 137px;
height: 137px;
}
.des {
font-size: 14px;
color: #666;
}
button {
width: 270px;
height: 44px;
background: rgba(255, 227, 25, 1);
border: 1px solid rgba(9, 9, 9, 1);
border-radius: 5px;
font-size: 16px;
font-weight: normal;
color: rgba(9, 9, 9, 1);
margin-bottom: 15px;
}
}
.landing-open-in-browser-tip, .landing-share-tip {
font-size: 17px;
color: #111;
&.popup-container {
position: absolute;
width: 270px;
text-align: center;
top: 114px;
padding: 20px 33px;
}
span {
color: #FF2121;
}
}
.landing-open-in-browser-tip.wechat, .landing-share-tip.wechat {
&.popup-container {
&::after {
content: '';
display: block;
position: absolute;
top: -50px;
right: -18px;
width: 50px;
height: 38px;
background: url("https://julyedu-cdn.oss-cn-beijing.aliyuncs.com/newyear20/H5/share-indicator.png") no-repeat;
background-size: contain;
}
}
}
.landing-open-in-browser-tip {
&.popup-container {
width: 312px;
}
}
.year19-index {
display: none;
}
[data-skip="treasure"] {
min-height: 100vh;
background-color: #0E7442;
&+ .year19-index {
display: none;
}
.treasure-content {
padding: 16px 0 10px;
}
.team-container {
margin: 0 10px 12px;
}
.activity-end__desc {
font-size: 30px;
color: #fff;
text-align: center;
line-height: 42px;
}
.team-empty {
padding-top: 118px;
}
.team-empty__icon {
display: block;
width: 56px;
height: 49px;
margin: 0 auto 18px;
background-size: cover;
background-image: url('https://julyedu-cdn.oss-cn-beijing.aliyuncs.com/newyear20/PC/icon-empty.png');
}
.team-empty__desc {
margin: 0 70px;
font-size: 15px;
color: #fff;
text-align: center;
line-height: 21px;
}
.team-empty__button {
display: block;
width: 297px;
height: 44px;
margin: 20px auto 0;
border: 1px solid #090909;
border-radius: 5px;
box-sizing: border-box;
font-size: 16px;
color: #090909;
background-color: #FFE319;
}
.activity-rule__header {
display: flex;
align-items: center;
justify-content: center;
margin: 49px 0 0;
}
.activity-rule__title {
margin: 0 16px;
font-size: 18px;
color: #FFE300;
line-height: 1;
}
.activity-rule__decorate {
display: inline-block;
width: 11px;
height: 12px;
background-size: cover;
background-image: url('https://julyedu-cdn.oss-cn-beijing.aliyuncs.com/newyear20/PC/icon-decorate-0.png');
}
.activity-rule__body {
margin: 13px 0 0;
padding: 0 21px 40px;
p {
font-size: 12px;
color: #FFE300;
line-height: 18px;
}
}
}
.mask-content {
&.popup-bind-phone {
height: 350px;
}
&.popup-bind-address {
height: 316px;
}
}
// 所有弹窗
.popup-container {
&.year {
.close-icon {
position: absolute;
bottom: 80px;
left: 0;
right: 0;
margin: 0 auto;
}
}
}
// 地址弹窗--宝箱
.address-treasure__desc {
margin: 12px 0 0;
font-size: 14px;
color: #666;
line-height: 1;
}
.address-treasure__notice {
margin: 10px 0 16px;
font-size: 12px;
color: #FF2121;
line-height: 1;
}
// 绑定手机弹窗--宝箱
.phone-treasure__desc {
width: 269px;
margin: 10px 25px 0;
font-size: 14px;
color: #666;
line-height: 1;
}
.phone-treasure__notice {
width: 269px;
margin: 9px 25px 15px;
font-size: 12px;
color: #FF2121;
line-height: 18px;
}
\ No newline at end of file
import React, { Component } from 'react';
import ReactDOM from 'react-dom';
import classnames from 'classnames';
import './mask.scss';
const Root = document.querySelector('body');
class Mask extends Component {
constructor(props) {
super(props);
if(!this.el) {
this.el = document.createElement('div');
}
}
componentDidMount() {
Root.appendChild(this.el);
}
componentWillUnmount() {
Root.removeChild(this.el);
}
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);
}
.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
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 === 1) &&
<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>
}
{/* 第三:奖品,任意线上课程兑换券 */}
{
(!bind_phone && !bind_address && prize_type === 5) &&
<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 classnames from 'classnames';
import { Link } from 'react-router-dom';
import './team.scss';
import { getParam } from "@/utils"
class TreasureTeam extends Component {
constructor(props) {
super(props);
this.state = {
team: {},
currentMember: {}
};
}
componentDidMount() {
this.initMemberInfo();
}
componentWillReceiveProps(nextProps) {
const { data: oldData } = this.props;
const { data: newData } = nextProps;
if(newData.is_open != oldData.is_open) {
this.initMemberInfo(newData);
}
}
initMemberInfo = (params = {}) => {
const { data, userInfo } = this.props;
const arr = JSON.stringify(params) !== '{}'? params: data;
let member = arr.member;
let len = member.length - 5;
for(; len < 0; len++) {
member.push({});
}
this.setState({
team: Object.assign({}, arr, {
member
}),
currentMember: userInfo.uid? member.filter(item => item.uid == userInfo.uid)[0] : {}
});
}
computedClass = (id) => {
const { data: { is_open } } = this.props;
const { currentMember } = this.state;
return classnames(
'team-member__item',
{
'active': id === currentMember.uid && is_open,
}
);
}
computedBg = (val) => {
return val? {
backgroundImage: `url(${val})`
} : {};
}
// 查看队友的奖品,条件:宝箱已拆
toCheckPrize = (id) => {
const { team: { is_open, member = []} } = this.state;
if(is_open) {
const data = member.filter(item => item.uid === id);
this.setState({
currentMember: data[0]
});
}
}
render() {
const {
team: {
is_captain,
status,
team_num,
lack_member,
is_open,
treasure_code,
member = [],
},
currentMember
} = this.state;
const {
toSplitTreasure,
userInfo,
children
} = this.props;
return (
<div className="team-container" data-skip="team">
{
!is_captain &&
<i className="team-friend"></i>
}
{/* 组队状态 */}
{
status === 1
? <i className="team-status">组队中..</i>
: <i className="team-decorate"></i>
}
{/* 队伍类型 */}
{
is_captain
? <h2 className="team-title">{team_num}号队伍</h2>
: <h2 className="team-title">好友队伍</h2>
}
{/* 队员情况 */}
{
status === 1
? <p className="team-desc">还差{lack_member}名队员即可获得宝箱哦~</p>
: <p className="team-desc">组队成功</p>
}
<div className="team-member">
{
member.map((item, index) => (
<div
className={this.computedClass(item.uid)}
onClick={() => this.toCheckPrize(item.uid)}
key={index}
style={this.computedBg(item.head_img)}
>
{
item.is_captain &&
<span className="team-member__captain">队长</span>
}
</div>
))
}
</div>
<div className="team-footer" data-layout={is_open? 'column': 'row'}>
{/* 队伍未满 */}
{
status === 1 &&
<>
{
getParam('version')
? is_captain
? <a className="team-button" href={`https://h5.julyedu.com/activity/newyear-2019/landing?treasure_code=${treasure_code}&origin=1&version=${getParam('version')}`}>继续邀请队友</a>
: <a className="team-button" href={`https://h5.julyedu.com/activity/newyear-2019/landing?treasure_code=${treasure_code}&origin=2&version=${getParam('version')}`}>帮好友完成组队</a>
: is_captain
? <a className="team-button" href={`https://h5.julyedu.com/activity/newyear-2019/landing?treasure_code=${treasure_code}&origin=1`}>继续邀请队友</a>
: <a className="team-button" href={`https://h5.julyedu.com/activity/newyear-2019/landing?treasure_code=${treasure_code}&origin=2`}>帮好友完成组队</a>
}
</>
}
{/* 可拆状态 */}
{
(status === 2 && !is_open) &&
<>
<span className="team-icon" data-direction="left"></span>
<span className="team-button--split" onClick={toSplitTreasure}></span>
<span className="team-icon" data-direction="right"></span>
</>
}
{/* 已拆状态 */}
{
(status === 2 && is_open) &&
<>
{
currentMember.prize_name
? <p className="team-prize">{currentMember.prize_name}</p>
: <p className="team-prize">尚未开宝箱</p>
}
{
currentMember.uid == userInfo.uid
? children
: null
}
</>
}
</div>
</div>
)
}
}
export default TreasureTeam;
.team-container {
&[data-skip="team"] {
height: 195px;
border-radius: 3px;
box-sizing: border-box;
background-color: #fff;
}
}
[data-skip="team"] {
position: relative;
padding: 10px 0 0;
.team-friend {
position: absolute;
top: 0;
left: 0;
width: 22px;
height: 22px;
padding-left: 2px;
box-sizing: border-box;
font-size: 12px;
font-style: normal;
color: #fff;
background-size: cover;
background-image: url('https://julyedu-cdn.oss-cn-beijing.aliyuncs.com/newyear20/PC/team-friend-bg.png');
}
.team-status {
position: absolute;
top: 0;
right: 0;
width: 54px;
border-radius: 0 3px 0 5px;
font-size: 12px;
font-style: normal;
color: #fff;
text-align: center;
line-height: 24px;
background-color: #00C091;
}
.team-decorate {
position: absolute;
top: -10px;
right: -10px;
width: 25px;
height: 25px;
background-size: cover;
background-image: url('https://julyedu-cdn.oss-cn-beijing.aliyuncs.com/newyear20/PC/team-decorate.png');
}
.team-title {
margin: 5px 0 0;
font-size: 16px;
color: #090909;
text-align: center;
line-height: 1;
}
.team-desc {
margin: 10px 0 0;
font-size: 12px;
color: #FF2121;
text-align: center;
line-height: 1;
}
.team-member {
display: flex;
align-items: center;
justify-content: center;
margin: 18px 0 0;
}
.team-member__item {
position: relative;
width: 44px;
height: 44px;
margin: 0 10px;
border-radius: 50%;
background-size: cover;
background-image: url('https://julyedu-cdn.oss-cn-beijing.aliyuncs.com/newyear20/PC/team-bg.png');
&.active {
border: 1px solid #00C091;
&::after {
display: block;
}
}
&::after {
content: '';
display: none;
position: absolute;
left: 0;
bottom: -12px;
right: 0;
width: 24px;
height: 3px;
margin: 0 auto;
border-radius: 50%;
background-color: #E6E6E6;
}
}
.team-member__captain {
position: absolute;
top: -6px;
right: -23px;
width: 33px;
height: 18px;
border-radius: 9px 9px 9px 1px;
border: 1px solid #fff;
box-sizing: border-box;
font-size: 12px;
color: #0B7B45;
text-align: center;
line-height: 18px;
background-color: #FFE319;
}
.team-footer {
display: flex;
align-items: center;
justify-content: center;
margin: 17px 0 0;
&[data-layout="column"] {
flex-direction: column;
}
}
.team-button {
display: block;
width: 297px;
height: 44px;
margin: 0 auto;
border: 1px solid #090909;
border-radius: 5px;
box-sizing: border-box;
font-size: 16px;
color: #090909;
text-align: center;
line-height: 44px;
background-color: #FFE319;
}
.team-button--split {
display: inline-block;
width: 60px;
height: 46px;
margin: 0 20px;
background-size: cover;
background-image: url('https://julyedu-cdn.oss-cn-beijing.aliyuncs.com/newyear20/treasure-split.gif');
}
.team-icon {
display: inline-block;
width: 31px;
height: 21px;
background-size: cover;
&[data-direction="left"] {
background-image: url('https://julyedu-cdn.oss-cn-beijing.aliyuncs.com/newyear20/PC/icon-direction-left.png');
}
&[data-direction="right"] {
background-image: url('https://julyedu-cdn.oss-cn-beijing.aliyuncs.com/newyear20/PC/icon-direction-right.png');
}
}
.team-prize {
margin: 5px 0 0;
font-size: 15px;
color: #303030;
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
import React, { Component } from 'react';
import './index.scss';
import { Toast } from 'antd-mobile';
import {Link, withRouter} from "react-router-dom"
import { getParam, http, SendMessageToApp, browser } from "@/utils"
import CommonContainer from './../../common/commonContainer/index'
import CommonPopup from './../../common/commonPopup/index';
import { connect } from 'react-redux';
import { Popup } from "@common/index"
import QRCode from 'qrcode'
@connect(state => ({
user: state.user
}))
class LiveRoom extends Component {
constructor(props) {
super(props);
this.state = {
list: [],
showMark: false,
subUrl: '',
QRCodeUrl: '',
}
}
componentDidMount() {
this.getLiveInfo();
}
shouldComponentUpdate(nextProps, nextState, nextContext) {
if (this.props.isAppUpdate !== nextProps.isAppUpdate) {
this.getLiveInfo();
return false
}
return true
}
getLiveInfo = () => {
http.get(`${API.home}/activity/get_live_info`).then(res => {
const { code, data, msg } = res.data;
if (code === 200) {
this.setState({
list: data
})
} else {
Toast.info(msg);
}
});
}
// 预约直播
subscribe = (id) => {
// 检查是否已登录
const {hasError, data = {}} = this.props.user;
if(hasError) {
this.toLogin();
}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,
QRCodeUrl: data.url,
})
})
} else {
Toast.info(msg);
}
});
}
}
// 已预约 给提示
tip = () => {
Toast.info('你已预约该直播');
}
// 去直播间
toLivingRoom = (id) => {
const {hasError, data = {}} = this.props.user;
if(hasError) {
this.toLogin();
}else{
window.location.href = `${window.location.protocol}//www.julyedu.com/live/m_room/${id}`
}
}
// 查看回放
checkVideo = (url) => {
const {hasError, data = {}} = this.props.user;
if(hasError) {
this.toLogin();
}else{
const vCourseId = url.split('/')[0];
window.location.href = `/play/video?id=${vCourseId}`
}
}
// 关闭弹框
closePopup = () => {
this.setState({
showMark: false,
})
// 关闭弹框的时候再次查询接口 查询预约状态
this.getLiveInfo();
}
// APP内需要保存图片 是否还是这样做 需要确认
saveImage = () => {
let version = getParam('version')
version = typeof version === 'string' ? version.replace('.', '').replace('.', '').slice(0, 3) : ''
const {QRCodeUrl} = this.state
if (version && parseInt(version) < 451) {
Toast.info('当前不支持此功能,升级到最新版本app可以点击保存二维码!', 2, null, false)
} else {
SendMessageToApp('generateQRCode', QRCodeUrl)
}
}
// 去登录
toLogin = () => {
if (!getParam('version')) {
this.props.history.push('/passport/login')
} else {
SendMessageToApp("toLogin")
}
}
render() {
const { list,showMark,subUrl } = this.state;
return (
<div className='live__container'>
{
showMark && (
<CommonPopup top={50} closePopup={this.closePopup} mark={true}>
<div className='sub__code_container'>
<p className='sub__title'>扫码关注“七月在线”服务号即可预约</p>
<img className='sub__qr_code' id={'live-qr-code'} src={subUrl} alt=""/>
{
browser.isAndroidApp ? (
<button className={'save-image'} onClick={this.saveImage}>保存二维码</button>
) : null
}
</div>
</CommonPopup>
)
}
<CommonContainer title='“薪”年好课免费学' id="year-live">
<ul className='live__list'>
{
list.length && (
list.map((item, index) => {
return <li key={index} className='live_room_item'>
<img className='user__avatar' src={item.avatar} alt="" />
<div className='live__info'>
<div className="theme">
<span>主题:</span>
<p>{item.title}</p>
</div>
{/*<div className="info__item">*/}
{/*<span>时间:</span>*/}
{/*<p>{item.date}</p>*/}
{/*</div>*/}
<div className="info__item">
<span>讲师:</span>
<p>{item.teacher}</p>
</div>
{/*{*/}
{/*item.on_live == 0 && item.is_end == 0 && item.is_subscribe == 0 && (*/}
{/*<span onClick={ ()=>this.subscribe(item.live_id)} className="order__btn">立即预约</span>*/}
{/*)*/}
{/*}*/}
{/*{*/}
{/*item.is_end == 1 && item.transcribe_url=='' && (*/}
{/*<span className="order__btn live__end">已结束</span>*/}
{/*)*/}
{/*}*/}
{/*{*/}
{/*item.on_live == 0 && item.is_end == 0 && item.is_subscribe == 1 && (*/}
{/*<span onClick={this.tip} className="order__btn subscribed">已预约</span>*/}
{/*)*/}
{/*}*/}
{/*{*/}
{/*item.on_live == 1 && item.is_end == 0 && (*/}
{/*<span onClick={()=>this.toLivingRoom(item.room_url)} className="order__btn living">正在直播</span>*/}
{/*)*/}
{/*}*/}
{
item.transcribe_url != '' && (
<span onClick={() => this.checkVideo(item.transcribe_url)} className="order__btn check__video">点击查看</span>
)
}
</div>
</li>
})
)
}
</ul>
</CommonContainer>
</div>
)
}
}
export default withRouter(LiveRoom)
.live__container {
.live_room_item {
width: 330px;
height: 100px;
margin: 0 auto;
display: flex;
justify-content: center;
align-items: center;
padding-bottom: 15px;
margin-top: 15px;
&:first-child {
border-bottom: 1px solid rgba(13, 77, 43, 1);
}
.user__avatar {
width: 73px;
height: 85px;
flex: 0 0 auto;
margin-right: 12px;
background: #ddd;
border-radius: 4px;
}
.live__info {
display: flex;
flex-direction: column;
justify-content: flex-start;
align-items: flex-start;
color: #fff;
font-size: 14px;
width: 246px;
height: 85px;
position: relative;
.info__item {
display: flex;
justify-content: flex-start;
align-content: center;
&:nth-child(2) {
margin: 9px 0;
}
span {
width: 46px;
flex: 0 0 auto;
color: #eaf787;
line-height: 16px;
}
p {
line-height: 16px;
}
}
.theme {
span {
display: block;
width: 46px;
float: left;
color: #eaf787;
line-height: 16px;
}
p {
width: 198px;
overflow: hidden;
text-overflow: ellipsis;
display: -webkit-box;
-webkit-line-clamp: 2;
float: left;
line-height: 16px;
color: #fff;
/* autoprefixer: off */
-webkit-box-orient: vertical;
}
}
.order__btn {
position: absolute;
right: 0;
bottom: 0;
width: 89px;
height: 28px;
border-radius: 4px;
display: flex;
justify-content: center;
align-items: center;
color: #070f08;
background: linear-gradient(
90deg,
rgba(255, 227, 0, 1) 0%,
rgba(255, 202, 0, 1) 100%
);
}
.subscribed {
background: rgba(254, 228, 29, 1);
}
.live__end{
background: #999;
color: #fff;
}
.living {
background: rgba(0, 153, 255, 1);
color: #fff;
}
.check__video {
background: rgba(114, 220, 141, 1);
color: #fff;
}
}
}
.sub__code_container {
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
.sub__title {
color: #525c65;
font-size: 16px;
line-height: 16px;
font-weight: 500;
text-align: center;
margin: 20px 0;
}
}
.save-image {
margin-top: 16px;
width: 270px;
height: 44px;
background: rgba(255, 227, 25, 1);
border: 1px solid rgba(9, 9, 9, 1);
border-radius: 5px;
font-size: 16px;
font-weight: normal;
color: rgba(9, 9, 9, 1);
}
}
.year-index-course {
.boss__add {
font-size: 12px;
color: #fff;
text-align: center;
height: 16px;
line-height: 16px;
text-decoration: underline;
display: block;
margin: 12px auto 0;
}
.course-conter {
.course-item {
width: 168px;
padding: 4px;
background-color: #fff;
position: relative;
border-radius: 2px;
span {
position: absolute;
right: 4px;
top: 4px;
width: 60px;
display: block;
text-align: center;
padding-left: 5px;
border-radius: 0 0 0 10px;
background-color: #EB1612;
color: #fff;
font-size: 12px;
}
a {
width: 160px;
height: 104px;
img {
width: 100%;
height: 100%;
}
}
}
}
.course-box {
display: flex;
justify-content: space-between;
flex-wrap: wrap;
.course-container {
width: 168px;
margin: 15px 0 0 0;
text-align: center;
position: relative;
}
.group-num {
width: 66px;
height: 16px;
position: absolute;
left: 10px;
top: 10px;
line-height: 16px;
background: #CA161C;
opacity: 0.8;
border-radius: 1px;
font-size: 12px;
color: #fff;
text-align: center;
}
.bargain-price {
position: absolute;
left: 4px;
top: 10px;
margin: 0;
height: 18px;
padding: 0 8px;
border-radius: 0 9px 9px 0;
font-size: 12px;
color: #fff;
line-height: 18px;
background-color: #F01D0E;
}
.coupon-course__footer {
.course-title {
padding-left: 10px;
font-size: 15px;
color: #333;
font-weight: 500;
margin-top: 7px;
}
.btn {
display: inline-block;
width: 138px;
height: 24px;
text-align: center;
line-height: 24px;
border-radius: 2px;
font-size: 12px;
outline: none;
border: none;
letter-spacing: 1px;
}
.big-course {
background-color: #FEE41D;
border: 1px solid #090F08;
color: #090F08;
margin-top: 10px;
}
.to-study {
background-color: #09f;
color: #fff;
position: absolute;
left: 10px;
bottom: 10px;
}
.free-study {
background: linear-gradient(-90deg, #EB1612 0%, #F92927 100%);
color: #fff;
margin-top: 10px;
}
.free-course-num {
font-size: 12px;
color: #070F08;
margin-top: 7px;
letter-spacing: 1px;
span {
font-size: 14px;
color: #FF0002;
}
}
}
.type {
text-align: left;
padding-left: 7px;
margin-top: 3px;
.tag {
display: inline-block;
padding: 0 6px;
height: 14px;
line-height: 15px;
text-align: center;
font-size: 12px;
color: #FFF;
position: relative;
z-index: 0;
}
.time {
display: inline-block;
height: 15px;
line-height: 15px;
padding: 0 6px;
margin-left: 5px;
position: relative;
font-size: 12px;
color: #555;
text-align: center;
z-index: 0;
}
.time:before {
content: '';
position: absolute;
top: 0;
right: 0;
bottom: 0;
left: 0;
background-color: #E6E6E6;
transform: skewX(-20deg);
z-index: -1;
}
.tag:before {
content: '';
position: absolute;
top: 0;
right: 0;
bottom: 0;
left: 0;
background-color: #FF0002;
transform: skewX(-20deg);
z-index: -1;
}
.tag[data-color="green"]:before {
background-color: #357345;
}
}
.price {
margin-top: 3px;
padding-left: 4px;
font-size: 12px;
color: #FF0002;
text-align: left;
&.price-group {
font-size: 0;
height: 30px;
}
.price-label {
font-size: 12px;
}
.new-price {
font-size: 16px;
}
.old-price {
margin-left: 2px;
font-size: 12px;
color: #666;
}
}
.status {
position: absolute;
left: 0;
bottom: 10px;
right: 0;
padding: 0 5px;
text-align: left;
&[data-layout="row"] {
display: flex;
.to-group {
font-size: 12px;
&:nth-child(1) {
margin-right: 2px;
}
&:nth-child(2) {
margin-left: 2px;
}
}
}
.status-btn {
display: inline-block;
height: 22px;
line-height: 22px;
border-radius: 2px;
text-align: center;
font-size: 12px;
color: #fff;
}
.to-buy {
width: 55px;
background-color: #FF8080;
}
.to-group {
display: block;
width: 100%;
height: 22px;
border-radius: 11px;
box-sizing: border-box;
font-size: 14px;
color: #fff;
text-align: center;
line-height: 22px;
background: linear-gradient(-90deg,rgba(235,22,18,1) 0%,rgba(255,0,2,1) 100%);
&[data-status="study"] {
background: #0099FF;
}
&[data-status="done"] {
border: 1px solid #090F08;
font-size: 12px;
color: #090F08;
background: #FEE41D;
}
}
.add-wish, .add-wish-success {
width: 88px;
margin-left: 5px;
outline: none;
color: #FF0002;
background-color: #fff;
border: 1px solid #FF0002;
img {
width: 12px;
height: 11px;
margin-right: 2px;
position: relative;
top: 1px;
}
}
.add-wish-success {
color: #fff;
background: linear-gradient(90deg, rgba(235, 22, 18, 1) 0%, rgba(249, 41, 39, 1) 100%);
}
}
}
.bigcourse .course-container {
height: 156px;
}
.freecourse .course-container {
height: 177px;
}
.groupcourse .course-container {
height: 195px;
}
.groupcourse[data-stage="2"] .course-container {
height: 215px;
}
.progree-and-sale {
display: flex;
align-items: center;
justify-content: center;
padding-left: 5px;
}
.progress {
width: 90px;
height: 8px;
border-radius: 4px;
background-color: #E6E6E6;
}
.progress_bar {
display: block;
width: 10%;
height: 100%;
border-radius: 4px 0 0 4px;
background-color: #FF0002;
}
.sale-sum {
flex: 1;
margin: 0;
font-size: 12px;
color: #333;
text-align: center;
line-height: 1;
}
.ai-course__subtitle {
width: 73px;
height: 24px;
margin: 15px auto 0;
border-radius: 12px;
font-size: 14px;
font-weight: 500;
color: #070F08;
text-align: center;
line-height: 22px;
letter-spacing: 2px;
background-color: #FFE300;
border: 1px solid #070F08;
}
.more-button {
display: block;
width: 75px;
height: 26px;
margin: 15px auto 5px;
padding: 0;
border-radius: 12px;
font-size: 12px;
font-weight: 400;
color: #fff;
line-height: 26px;
cursor: pointer;
outline: none;
background-color: #0F6237;
border: none;
letter-spacing: 1px;
}
.sub__code_container {
padding: 20px;
}
.save-image {
display: block;
width: 133px;
height: 30px;
margin: 20px auto 0 auto;
background: rgba(83, 39, 250, 1);
border-radius: 15px;
font-size: 14px;
color: #fff;
-webkit-appearance: none;
outline: 0;
border: none;
}
.nav-right {
width: 100px;
height: 125px;
background-image: url("https://julyedu-cdn.oss-cn-beijing.aliyuncs.com/newyear20/H5/sd_fc_bj.png");
background-repeat: no-repeat;
background-size: cover;
position: fixed;
right: 0;
bottom: 20%;
margin-top: -57px;
z-index: 22;
.nav-right__link {
display: block;
position: relative;
font-size: 12px;
font-weight: 500;
color: #fff;
text-align: center;
top: 47px;
line-height: 25px;
}
.nav-right__number {
position: absolute;
top: -5px;
right: 5px;
padding: 0 5px;
border: 1px solid #F7D067;
border-radius: 7px 7px 7px 0px;
font-size: 12px;
font-style: normal;
color: #FEE41D;
background-color: #FF4F24;
height: 16px;
line-height: 14px;
}
}
.nav-right-wish {
background-image: url("https://julyedu-cdn.oss-cn-beijing.aliyuncs.com/newyear20/H5/fanc-bx.png");
.nav-right__link{
top: 60px;
left: 10px;
}
}
}
\ No newline at end of file
import React, {Component} from 'react'
import './index.scss'
import LiveRoom from './LiveRoom/index'
import YearCourse from './YearCourse/index'
import TreasureBox from './../treasure-box/index'
import TreasureNav from './nav'
import CommonPopup from './../common/commonPopup/index'
import cookie from "js-cookie"
import {setCurrentUser, startFetchUser} from "@/store/userAction"
import {SendMessageToApp, getParam, http} from '@/utils'
import {addDays} from "date-fns"
import {connect} from "react-redux"
import {Toast} from 'antd-mobile'
import {compose} from "redux"
@connect(state => ({
user: state.user
}),
{setCurrentUser, startFetchUser}
)
export default class index extends Component {
state = {
removable: 0, // 未拆宝箱的数量
currentOpenId: 0, // 当前要拆的宝箱的队伍的ID
treasure_stage: 0, // 宝箱的活动阶段
activity_stage: 0, // 整个活动的阶段
userInfoList: [],
userInfo: {},
isAppUpdate: false,
showMark: false,
banner: 'https://julyedu-cdn.oss-cn-beijing.aliyuncs.com/newyear20/new-year/m-banner.png'
}
componentDidMount() {
const _this = this
// 获取App登录信息
window['loginInfo'] = result => {
_this.loginInfo(result)
}
_this.getStage()
document.title = '七月在线新春献礼,幸运宝箱随你开,100%有奖!“薪”年好课免费学,精品课程1分秒!';
}
// 获取app登录数据
loginInfo = (result) => {
this.setState({
userInfoList: result
}, () => {
if (this.state.userInfoList.length) {
this.props.startFetchUser()
this.appLogin()
}
})
}
// 保存cookie
appLogin = () => {
let expires = addDays(new Date(), 90)
this.state.userInfoList.map((item, index) => {
cookie.set("token", item.token, {expires, path: '/', domain: '.julyedu.com'})
cookie.set("plat", item.plat, {expires, path: '/', domain: '.julyedu.com'})
cookie.set("uid", item.uid, {expires, path: '/', domain: '.julyedu.com'})
cookie.set("uname", item.uname, {expires, path: '/', domain: '.julyedu.com'})
cookie.set("avatar_file", item.avatar_file, {expires, path: '/', domain: '.julyedu.com'})
})
if (cookie.get("token") && cookie.get("uid")) {
this.setState({
isAppUpdate: true
})
}
this.props.setCurrentUser(this.transformUser(this.state.userInfoList))
}
transformUser = res => {
let payload
res.map((item, index) => {
payload = {
hasError: false,
data: {
username: item.uname,
avatar: item.avatar_file,
token: item.token,
uid: item.uid
},
isFetching: false
}
})
return payload
}
// 关闭弹框
closePopup = () => {
this.setState({
showMark: false,
})
}
// 获取未拆宝箱数量
getRemovable = (removable, currentOpenId) => {
}
// 获取活动以及宝箱的阶段
getStage = () => {
http.get(`${API.home}/activity/stage`).then(res => {
const {code, data, msg} = res.data
if (code === 200) {
if(Number(data.activity_stage) === 0) {
// this.props.history.push('/');
return;
}
// treasure_stage,宝箱阶段,0-不在活动时间,1-活动时间内
this.setState({
activity_stage: data.activity_stage,
treasure_stage: data.treasure_stage
})
if(data.activity_stage == 3){
this.setState({
banner: 'https://julyedu-cdn.oss-cn-beijing.aliyuncs.com/newyear20/H5/m_banner_fc.png',
})
} else {
this.setState({
banner: 'https://julyedu-cdn.oss-cn-beijing.aliyuncs.com/newyear20/new-year/m-banner.png',
})
}
} else {
Toast.info(msg, 2)
}
})
}
render() {
const {
banner,
activity_stage,
treasure_stage,
} = this.state
return (
<div className={'year-index'}>
<div className="banner-treasure">
<div id="banner" className="banner-treasure__header"
style={{backgroundImage: `url(${banner})`}}></div>
<div className="banner-treasure__nav">
<TreasureNav id="banner" treasure_stage={treasure_stage} activeStage={activity_stage}/>
</div>
<div className="banner-treasure__decorate"></div>
</div>
{/* 大咖直播 */}
{/* <LiveRoom isAppUpdate={this.state.isAppUpdate}/> */}
{/* 组队开宝箱 */}
{
treasure_stage === 1 &&
<TreasureBox isAppUpdate={this.state.isAppUpdate} getRemovable={this.getRemovable}/>
}
{/* 课程 */}
{/* <YearCourse stage={activity_stage} treasureStage={treasure_stage} isAppUpdate={this.state.isAppUpdate} /> */}
{/*好友加入队伍提醒;获得宝箱提醒;开售提醒弹窗,需要自取,注意修改文案*/}
{
this.state.showMark &&
<CommonPopup top={50} closePopup={this.closePopup} mark={true}>
<div className='sub__code_container'>
<p className='sub__title'>提醒服务</p>
<p className='sub__tip'>有好友加入队伍后第一时间通知我~</p>
<img className='sub__qr_code' id={'live-qr-code'}
src='//julyedu-cdn.oss-cn-beijing.aliyuncs.com/2018christyear/h5/qrcode.jpg' alt=""/>
<p className='sub__tip'>长按识别/扫码 关注【七月在线】服务号即可预约</p>
</div>
</CommonPopup>
}
{/*规则弹窗*/}
{
this.state.showMark &&
<CommonPopup top={50} closePopup={this.closePopup} mark={true}>
<div className='sub__code_container'>
<p className='sub__title'>组队开宝箱活动规则</p>
<p className='sub__rule'>
1. 活动期间(1218-1231日)可随时参与开宝箱;<br/>
2. 当前队伍满员后可继续创建新队伍;<br/>
3. 每人有一次机会加入好友的队伍;<br/>
4. 队伍满员后所有成员均可随机获得宝箱内奖品,队长奖励更丰厚哦~<br/>
5. 代金券、课程等虚拟奖品将直接发放至账户,实物奖品活动结束后统一邮寄;<br/>
6. 现金可提现:我的 赚奖学金 提现。
</p>
</div>
</CommonPopup>
}
<div className={'btm-rule'}>* 本活动解释权归北京七月在线科技有限公司所有 *</div>
</div>
)
}
}
.year-index {
padding-bottom: 30px;
background-color: #BC2A18;
.banner-treasure {
}
.banner-treasure__header {
height: 320px;
background-size: cover;
background-position: center;
}
.banner-treasure__nav {
height: 30px;
}
.banner-treasure__decorate {
height: 20px;
//background-size: cover;
//background-image: url('https://julyedu-cdn.oss-cn-beijing.aliyuncs.com/newyear20/H5/m_nv_bj%402x.png');
}
.sub__code_container {
padding: 20px 30px;
text-align: center;
.sub__title {
font-size: 18px;
color: #111;
font-weight: normal;
}
.sub__qr_code {
width: 137px;
height: 137px;
}
.sub__tip {
font-size: 14px;
color: #666;
margin: 13px 0;
letter-spacing: 1px;
i {
font-style: normal;
color: #FF0000;
font-size: 16px;
}
}
.sub__rule {
font-size: 14px;
color: #666;
text-align: left;
margin-top: 20px;
margin-bottom: 5px;
}
}
.btm-rule {
color: #fff;
font-size: 12px;
width: 100%;
text-align: center;
}
}
.year-index + .year19-index {
display: none;
}
\ No newline at end of file
import React, { Component } from 'react';
import classnames from 'classnames';
import { http } from '@/utils';
import './nav.scss';
class TreasureNav extends Component {
constructor(props) {
super(props);
this.state = {
isFixed: false,
curIndex: 0,
formatNavs: [],
navs: [
{
id: 'year-live',
name: '好课免费学'
},
{
id: 'year-treasure',
name: '组队开宝箱'
},
{
id: 'year-wuhan',
name: '驰援武汉'
},
{
id: 'year-course',
name: '重磅好课'
},
// {
// id: 'year-free',
// name: '免费学'
// },
{
id: 'year-group',
name: '1分拼团'
},
{
id: 'year-discount',
name: '抄底专区'
},
]
};
}
componentDidMount() {
window.addEventListener('scroll', this.calcNavActive)
}
componentWillUnmount () {
window.removeEventListener('scroll', this.calcNavActive);
}
componentWillReceiveProps(nextProps) {
this.initNav(nextProps.treasure_stage,nextProps.activeStage);
}
initNav = (treasure_stage,activeStage) => {
let {navs} = this.state;
// treasure_stage,宝箱阶段,0-不在活动时间,1-活动时间内
let data = this.state.navs
if(treasure_stage === 0) {
data = navs.filter(item => item.id !== 'year-treasure')
}
if(activeStage === 3) {
data = data.filter(item => item.id !== 'year-free')
}
this.setState({
formatNavs: data
})
}
calcNavActive = () => {
const { formatNavs } = this.state;
const { id } = this.props;
const bannerEl = document.querySelector(`#${id}`);
setTimeout(() => {
let y = window.scrollY,
len = formatNavs.length - 1;
this.setState({
isFixed: y >= bannerEl.offsetHeight
});
for (; len > -1; len--) {
let el = document.querySelector(`#${formatNavs[len].id}`);
if (el && (y + 200) >= el.offsetTop) {
this.setState({
curIndex: len
})
break;
}
}
}, 100);
}
selectToNav = (i) => {
const { formatNavs } = this.state;
const id = `#${formatNavs[i]['id']}`;
let el = document.querySelector(id);
if(el) {
this.setState({
curIndex: i
});
window.scrollTo({
top: el.offsetTop,
left: 0
});
}
}
render() {
const { isFixed, curIndex, formatNavs } = this.state;
return (
<div className={classnames("treasure-nav", {'fixed': isFixed})} data-skip="nav">
{
formatNavs.map((item, index) => (
<a
href={`#${item.id}`}
className={classnames("treasure-nav__item", {'active': index === curIndex})}
key={item.id}
onClick={() => this.selectToNav(index)}
>{item.name}</a>
))
}
</div>
)
}
}
export default TreasureNav;
\ No newline at end of file
.treasure-nav {
&[data-skip="nav"] {
display: flex;
align-items: center;
justify-content: center;
height: 30px;
background-color: #357345;
}
&.fixed {
position: fixed;
top: 0;
width: 100%;
z-index: 999;
}
}
[data-skip="nav"] {
.treasure-nav__item {
flex: 1;
box-sizing: border-box;
font-size: 12px;
color: #fff;
text-align: center;
line-height: 26px;
&.active {
border: 1px solid #090F08;
border-radius: 3px;
color: #090F08;
background-color: #FEE41D;
}
}
}
\ No newline at end of file
import React, { Component } from 'react';
import { withRouter } from 'react-router-dom';
import CommonContainer from './../common/commonContainer/index';
import TreasureRank from './rank';
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 {
constructor(props) {
super(props);
}
render() {
return (
<CommonContainer id="year-treasure" title={'组队开宝箱'}>
<div style={{
textAlign: 'center',
fontSize: '12px',
color: '#FFDC1E',
marginTop: '10px'
}}>邀请好友组队一起开宝箱,满5人后将随机获得以下奖品~</div>
<Prizes showSystemNotices={true}/>
<UserBulletScreen/>
<TeamInfo isAppUpdate={this.props.isAppUpdate} getRemovable={this.props.getRemovable} />
<TreasureRank history={this.props.history} />
</CommonContainer>
)
}
}
export default withRouter(TreasureBox);
import React, { Component } from 'react';
import { http, getParam, SendMessageToApp } from '@/utils';
import './rank.scss'
class TreasureRank extends Component {
constructor(props) {
super(props);
this.state = {
rank: [],
rankList: [],
isMore: false,
}
}
componentDidMount() {
this.fetchRankInfo();
}
fetchRankInfo = () => {
http.get(`${API.home}/sys/treasure/ranking`).then(res => {
const { code, data } = res.data;
if(code === 200) {
if(JSON.stringify(data) !== '{}') {
if(data.length > 5) {
this.setState({
rank: data.filter((item, index) => index < 5),
rankList: data,
isMore: true,
});
}else {
this.setState({
rank: data,
rankList: data,
isMore: false,
});
}
}
}
});
}
switchMoreRank = () => {
const { rankList, isMore } = this.state;
if(isMore) {
this.setState({
rank: rankList,
isMore: false,
})
}else {
this.setState({
rank: rankList.filter((item, index) => index < 5),
isMore: true,
})
}
}
handleToVip = (id) => {
const { history } = this.props;
if(id) {
if(getParam('version')) {
SendMessageToApp('toCourse', id);
}else {
history.push(`/detail?id=${id}`);
}
}
}
render() {
const { rank, isMore } = this.state;
return (
<>
{
rank.length !== 0 &&
<div data-skip="rank">
<div className="rank-title">
<i className="rank-title__decorate"></i>
<h2 className="rank-title__txt">宝箱达人榜</h2>
<i className="rank-title__decorate"></i>
</div>
<p className="rank-desc">宝箱数量前50名可额外获得一份奖品,数量相同的用时短者排名在前</p>
<dl className="rank-header">
<dd className="rank-column">排名</dd>
<dd className="rank-column">用户</dd>
<dd className="rank-column">宝箱数量</dd>
<dd className="rank-column">奖品</dd>
</dl>
<div className="rank-body">
{
rank.map((item, index) => (
<dl className="rank-item" key={index}>
<dd className="rank-column">
{
index <= 2
? <span className="rank-column__number" data-num={index}></span>
: <span>{index+1}</span>
}
</dd>
<dd className="rank-column">
<span className="rank-column__name">{item.user_name}</span>
</dd>
<dd className="rank-column">
<span>{item.num}</span>
</dd>
<dd className="rank-column">
{
item.url
? <a className="rank-column__txt" onClick={() => this.handleToVip(item.url)}>{item.prize_name}</a>
: <span className="rank-column__txt">{item.prize_name}</span>
}
</dd>
</dl>
))
}
<div className="rank-more" onClick={this.switchMoreRank}>
<span className="rank-more__txt">{isMore? '展开' : '收起'}</span>
<i className="rank-more__icon" data-more={isMore}></i>
</div>
</div>
</div>
}
</>
)
}
}
export default TreasureRank;
\ No newline at end of file
[data-skip="rank"] {
.rank-title {
display: flex;
align-items: center;
justify-content: center;
}
.rank-title__decorate {
display: inline-block;
width: 11px;
height: 12px;
background-size: cover;
background-image: url('https://julyedu-cdn.oss-cn-beijing.aliyuncs.com/newyear20/PC/icon-decorate-0.png');
}
.rank-title__txt {
position: relative;
margin: 0 8px;
font-size: 18px;
font-weight: normal;
color: #FFE300;
text-align: center;
line-height: 1;
&::after {
content: '';
position: absolute;
top: -8px;
right: -8px;
width: 14px;
height: 11px;
background-size: cover;
background-image: url('https://julyedu-cdn.oss-cn-beijing.aliyuncs.com/newyear20/PC/icon-decorate-1.png');
}
}
.rank-desc {
margin: 7px 0 0;
padding: 0 48px;
font-size: 12px;
color: #FFE300;
text-align: center;
line-height: 16px;
}
.rank-header {
margin: 12px 10px 0;
border-radius: 5px 5px 0 0;
font-size: 0;
overflow: hidden;
.rank-column {
color: #1D5432;
font-size: 12px;
line-height: 30px;
background-color: #FFE300;
}
}
.rank-body {
margin: 0 10px;
border-left: 1px solid #81F3AF;
border-bottom: 1px solid #81F3AF;
border-right: 1px solid #81F3AF;
border-radius: 0 0 5px 5px;
background-color: #1D5432;
}
.rank-item {
border-bottom: 1px solid #0E7442;
.rank-column {
display: inline-flex;
align-items: center;
justify-content: center;
height: 40px;
font-size: 12px;
color: #fff;
}
}
.rank-column {
display: inline-block;
text-align: center;
vertical-align: middle;
&:nth-child(1) {
width: 10%;
}
&:nth-child(2) {
width: 25%;
}
&:nth-child(3) {
width: 20%;
}
&:nth-child(4) {
width: 45%;
}
}
.rank-column__number {
display: inline-block;
width: 11px;
height: 12px;
background-size: cover;
&[data-num="0"] {
background-image: url('https://julyedu-cdn.oss-cn-beijing.aliyuncs.com/active19_717/m/717/-s-diyiming.png');
}
&[data-num="1"] {
background-image: url('https://julyedu-cdn.oss-cn-beijing.aliyuncs.com/active19_717/m/717/-s-dierming.png');
}
&[data-num="2"] {
background-image: url('https://julyedu-cdn.oss-cn-beijing.aliyuncs.com/active19_717/m/717/-s-disanming.png');
}
}
.rank-column__name {
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.rank-column__txt {
display: inline-block;
width: 100%;
box-sizing: border-box;
padding: 0 5px;
text-align: left;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
a.rank-column__txt {
text-decoration: underline;
}
.rank-more {
display: flex;
align-items: center;
justify-content: center;
height: 40px;
}
.rank-more__txt {
font-size: 14px;
color: #fff;
}
.rank-more__icon {
width: 11px;
height: 12px;
margin-left: 5px;
background-size: cover;
background-image: url('https://julyedu-cdn.oss-cn-beijing.aliyuncs.com/newyear20/H5/icon-arrow-double.png');
&[data-more="false"] {
transform: rotate(180deg);
}
}
}
import React, { Component } from 'react';
import './team.scss'
import { getParam, http, SendMessageToApp } from "@/utils"
import { Toast } from 'antd-mobile';
import {withRouter} from 'react-router-dom';
import {compose} from "redux"
import { connect } from "react-redux";
import jsCookie from 'js-cookie'
class TeamInfo extends Component {
constructor(props) {
super(props);
this.state = {
is_my_team: false, // 是否有自己的队伍
prize_info: [],
info: {
removable: 0,
total: 0
},
member: [],
removable_data: [],
my_team: {},
}
}
componentDidMount() {
this.getTeamInfo();
}
// 获取队伍信息
getTeamInfo = () => {
http.get(`${API.home}/sys/treasure/teamInfo`).then(res => {
const { code, data, msg } = res.data;
if (code === 200) {
const { prize_info, is_my_team, info, member, removable_data, my_team } = data;
this.setState({
prize_info,
is_my_team,
info,
member: this.fillTeam(member, is_my_team),
removable_data,
my_team
})
let currentId = null;
if(info.removable > 0) {
currentId = removable_data[0].id;
}
this.props.getRemovable(info.removable, currentId);
} else {
Toast.info(msg);
}
})
}
// 跳转到我的宝箱页
toYearTreasure = (close) => {
if(this.props.user.hasError) {
this.toLogin();
} else {
let search = '';
if(close) {
const {removable_data, info: {removable}} = this.state;
if(removable > 0) {
let current = removable_data[0];
search = `?id=${current.id}`;
}
}
if (!getParam('version')) {
this.props.history.push(`/year/yearTreasure${search}`);
} else {
this.props.history.push(`/year/yearTreasure${search}?version=${getParam('version')}`);
}
}
}
// 去登录
toLogin = () => {
if (!getParam('version')) {
this.props.history.push('/passport/login')
} else {
SendMessageToApp("toLogin")
}
}
shouldComponentUpdate(nextProps, nextState, nextContext) {
if (this.props.isAppUpdate !== nextProps.isAppUpdate) {
this.getTeamInfo();
return false
}
return true
}
// 邀请好友组队
createTeam = () => {
if(this.props.user.hasError) {
this.toLogin();
} else {
sessionStorage.setItem('showShareTip', '1')
const {is_my_team, my_team: {treasure_code}} = this.state;
if(is_my_team) { // 有自己的队伍
// 直接跳转
if (!getParam('version')) {
// this.props.history.push('/activity/newyear-2019/landing?origin=1&treasure_code=' + treasure_code);
window.location.assign('https://h5.julyedu.com/activity/newyear-2019/landing?origin=1&treasure_code=' + treasure_code);
} else {
window.location.assign('https://h5.julyedu.com/activity/newyear-2019/landing?origin=1&treasure_code=' + treasure_code + '&version='+ getParam('version'));
}
}else{ // 没自己的队伍
// 请求创建队伍的接口
http.get(`${API.home}/sys/treasure/createMyTeam`).then(res => {
const { code, data, msg } = res.data;
if (code === 200) {
const { treasure_code } = data;
if (!getParam('version')) {
// this.props.history.push('/activity/newyear-2019/landing?origin=1&treasure_code=' + treasure_code);
window.location.assign('https://h5.julyedu.com/activity/newyear-2019/landing?origin=1&treasure_code=' + treasure_code);
} else {
window.location.assign('https://h5.julyedu.com/activity/newyear-2019/landing?origin=1&treasure_code=' + treasure_code + '&version='+ getParam('version'));
}
} else {
Toast.info(msg);
}
});
}
}
}
// 队伍成员信息必须满五个 不满的需要填充
fillTeam = (list, is_my_team) => {
let len = list.length;
// 没有创建队伍 并且没有加入他人队伍
if(this.props.user.hasError) {
for(let i=0;i<5-len;i++) {
list.push({
head_img: '',
user_name: '',
nobody: true,
})
}
} else {
if(len === 0 && !is_my_team) {
list.push({
head_img: jsCookie.get('avatar_file'),
user_name: jsCookie.get('user_name'),
})
for(let i=0;i<4;i++) {
list.push({
head_img: '',
user_name: '',
nobody: true,
})
}
}else{
for(let i=0;i<5-len;i++) {
list.push({
head_img: '',
user_name: '',
nobody: true,
})
}
}
}
return list;
}
render() {
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) {
Text = `我的宝箱`;
} else if (removable === 0) {
Text = `共${total}个宝箱`;
} else {
Text = `共${total}个宝箱/${removable}个未开`;
}
return (
<div className='team_info__container'>
<div className='team__member'>
<ul className='member__list'>
{
member && member.length > 0 && (
member.map((item, index) => {
return <li key={index} className='member__item'>
<div className='avatar__container'>
{
item.nobody ? (
<img className='head__image' src="https://julyedu-cdn.oss-cn-beijing.aliyuncs.com/newyear20/H5/default-member-avatar.png" alt=""/>
) : (
<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>
</li>
})
)
}
</ul>
<div className='box__number'>
<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 onClick={this.createTeam} className='invite__btn'>
{
is_my_team ? ('继续组队') : ('组队开宝箱')
}
</div>
{
stage_no > 0 && name && <p className='stage_prize'>{`第${stage_no}个宝箱必中${name}`}</p>
}
</div>
)
}
}
export default compose(
connect(
state => ({user: state.user}),
null
),
withRouter
)(TeamInfo)
.team_info__container {
margin-bottom: 30px;
display: flex;
flex-direction: column;
justify-content: flex-start;
align-items: center;
.team__member {
height: 72px;
width: 100%;
display: flex;
justify-content: center;
align-items: center;
margin-bottom: 16px;
.member__list {
height: 50px;
width: 224px;
display: flex;
justify-content: flex-start;
align-items: center;
margin-right: 12px;
.member__item {
width: 44px;
height: 50px;
display: flex;
flex-direction: column;
justify-content: space-between;
align-items: center;
margin-left: 1px;
&:first-child {
margin-left: 0;
.member__join {
border-radius: 2px 0 0 2px;
}
}
&:last-child {
.member__join {
border-radius: 0 2px 2px 0;
}
}
.avatar__container {
width: 27px;
height: 27px;
position: relative;
border: 1px solid #fff;
border-radius: 50%;
.head__image {
border-radius: 50%;
width: 100%;
height: 100%;
}
.shadow {
width: 24px;
height: 3px;
background: #1a3528;
border-radius: 50%;
position: absolute;
bottom: -6px;
}
.caption__flag {
position: absolute;
width: 18px;
height: 10px;
left: 50%;
top: 0;
}
}
.member__join {
width: 40px;
height: 5px;
background: rgba(0, 88, 51, 1);
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;
}
}
}
.box__number {
width: 108px;
height: 100%;
display: flex;
flex-direction: column;
justify-content: flex-start;
align-items: center;
position: relative;
img {
width: 92px;
height: 50px;
}
.box__text {
width: 1000px;
font-size: 100px;
transform: scale(0.1);
text-decoration: underline;
color: rgba(255, 227, 0, 1);
position: absolute;
bottom: -72px;
text-align: center;
}
.position__arrow {
width: 18px;
height: 18px;
position: absolute;
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 {
width: 320px;
height: 44px;
background: rgba(255, 227, 0, 1);
border-radius: 3px;
display: flex;
justify-content: center;
align-items: center;
font-size: 15px;
color: rgba(11, 123, 69, 1);
margin-bottom: 12px;
}
.stage_prize {
font-size: 12px;
line-height: 12px;
color: rgba(255, 227, 0, 1);
text-align: center;
}
}
html, body, #root {
height: 100%;
}
.year-wish {
min-height: 100%;
background-color: #BA2C21;
padding-bottom: 35px;
.banner {
width: 100%;
margin-bottom: 30px;
}
.course-box {
display: flex;
justify-content: space-between;
flex-wrap: wrap;
.course-container {
width: 168px;
margin: 15px 0 0 0;
text-align: center;
position: relative;
}
.group-num {
width: 66px;
height: 16px;
position: absolute;
left: 10px;
top: 10px;
line-height: 16px;
background: #CA161C;
opacity: 0.8;
border-radius: 1px;
font-size: 12px;
color: #fff;
text-align: center;
}
.bargain-price {
position: absolute;
left: 4px;
top: 10px;
margin: 0;
height: 18px;
padding: 0 8px;
border-radius: 0 9px 9px 0;
font-size: 12px;
color: #fff;
line-height: 18px;
background-color: #F01D0E;
}
.coupon-course__footer {
.course-title {
padding-left: 10px;
font-size: 15px;
color: #333;
font-weight: 500;
margin-top: 7px;
}
.btn {
display: inline-block;
width: 138px;
height: 24px;
text-align: center;
line-height: 24px;
border-radius: 2px;
font-size: 12px;
outline: none;
border: none;
letter-spacing: 1px;
}
.big-course {
background-color: #FEE41D;
border: 1px solid #090F08;
color: #090F08;
margin-top: 10px;
}
.to-study {
background-color: #09f;
color: #fff;
position: absolute;
left: 10px;
bottom: 10px;
}
.free-study {
background: linear-gradient(-90deg, #EB1612 0%, #F92927 100%);
color: #fff;
margin-top: 10px;
}
.free-course-num {
font-size: 12px;
color: #070F08;
margin-top: 7px;
letter-spacing: 1px;
span {
font-size: 14px;
color: #FF0002;
}
}
}
.type {
text-align: left;
padding-left: 7px;
margin-top: 3px;
.tag {
display: inline-block;
padding: 0 6px;
height: 14px;
line-height: 15px;
text-align: center;
font-size: 12px;
color: #FFF;
position: relative;
z-index: 0;
}
.time {
display: inline-block;
height: 15px;
line-height: 15px;
padding: 0 6px;
margin-left: 5px;
position: relative;
font-size: 12px;
color: #555;
text-align: center;
z-index: 0;
}
.time:before {
content: '';
position: absolute;
top: 0;
right: 0;
bottom: 0;
left: 0;
background-color: #E6E6E6;
transform: skewX(-20deg);
z-index: -1;
}
.tag:before {
content: '';
position: absolute;
top: 0;
right: 0;
bottom: 0;
left: 0;
background-color: #FF0002;
transform: skewX(-20deg);
z-index: -1;
}
.tag[data-color="green"]:before {
background-color: #357345;
}
}
.price {
margin-top: 3px;
padding-left: 4px;
font-size: 12;
color: #FF0002;
text-align: left;
&.price-group {
font-size: 0;
height: 30px;
}
.price-label {
font-size: 12px;
}
.new-price {
font-size: 16px;
}
.old-price {
margin-left: 2px;
font-size: 12px;
color: #666;
}
}
.status {
position: absolute;
left: 0;
bottom: 10px;
right: 0;
padding: 0 5px;
text-align: left;
&[data-layout="row"] {
display: flex;
.to-group {
font-size: 12px;
&:nth-child(1) {
margin-right: 2px;
}
&:nth-child(2) {
margin-left: 2px;
}
}
}
.status-btn {
display: inline-block;
height: 22px;
line-height: 22px;
border-radius: 2px;
text-align: center;
font-size: 12px;
color: #fff;
}
.to-buy {
width: 148px;
background-color: #FF8080;
}
.to-group {
display: block;
width: 100%;
height: 22px;
border-radius: 11px;
box-sizing: border-box;
font-size: 14px;
color: #fff;
text-align: center;
line-height: 22px;
background: linear-gradient(-90deg,rgba(235,22,18,1) 0%,rgba(255,0,2,1) 100%);
&[data-status="study"] {
background: #0099FF;
}
&[data-status="done"] {
border: 1px solid #090F08;
font-size: 12px;
color: #090F08;
background: #FEE41D;
}
}
}
}
.groupcourse .course-container {
height: 195px;
}
.notData {
margin: 100px auto 0;
text-align: center;
img {
width: 56px;
height: 49px;
}
p{
font-size: 16px;
color: #fff;
margin-top: 20px;
}
}
}
.year-wish + .year19-index {
display: none;
}
......@@ -304,5 +304,10 @@ export default [
path:'/free',
exact: true,
component: loadable(() => import(/*limit-free*/'@/components/limit-free'))
}
},
// 新的开宝箱活动
{
path: '/box/boxActive',
component: loadable(() => import(/* webpackChunkName: 'newyear-yearIndex' */ '@components/activity/box/preheat/index'))
},
]
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