Commit cbc340c6 by zhanghaozhe

Merge branch '2020-717' into dev

parents b3475f4f 68e66bf0
import React, { Component } from 'react';
import { debounce, groupBy, isEmpty } from "lodash";
import { http } from "@/utils"
import { Toast } from "antd-mobile";
import { Link } from "react-router-dom";
import { connect } from "react-redux";
import './index.scss'
import { Popup } from "@common/index"
class Anniversary2020 extends Component {
nav = null
stages = {
1: '基础',
2: '进阶',
3: '高阶',
4: '拓展',
}
stageParams = ['one', 'two', 'three', 'four']
records = null
answerRule = `
1.邀请好友加入队伍,好友答对题你和好友均可增加抽奖机会
2.每增加3个队员答对题,你可以增加N次抽奖机会,N=1 ,2, 3 (有3个队员答对题,你可+1次抽奖机会;6个队员答对题,你再+2次抽奖机会,超过6个队员答对题时,每+3人答对题都可+3次抽奖机会)
3.被邀请好友答对题TA可+1次抽奖机会
4.每人只能当1次队员哦
`
state = {
navs: [
{
text: '一分拼团',
id: '#group',
},
{
text: '抽华为P40Pro+',
id: '#lottery',
},
{
text: '组队答题',
id: '#group-answer',
},
{
text: '免费试听',
id: '#audition',
},
{
text: '冰点秒杀',
id: '#stage-course',
},
],
titleImages: [
require('./images/title_1.png'),
require('./images/title_2.png'),
require('./images/title_3.png'),
require('./images/title_4.png'),
require('./images/title_5.png'),
],
rankIcons: [
require('./images/rank1.png'),
require('./images/rank2.png'),
require('./images/rank3.png'),
],
navActive: 0,
sectionsPosition: [],
auditions: [],
auditionShowAll: false,
group: [],
groupShowAll: false,
stageCourses: [],
activityData: {},
team: {},
userAddress: {
name: '',
phone: '',
address: '',
},
isShowUserAddress: false,
prizeData: {},
prizeRecords: [],
prizeRecordsPagination: 0,
isShowPrizesRecords: false,
}
componentDidMount() {
this.getActivityStage()
this.getTeam()
this.getUserAddress()
this.getPrizeData()
this.getPrizeRecords()
this.getAuditionCourses()
this.getGroupCourses()
this.getStageCourses('zero')
}
componentDidUpdate(prevProps, prevState) {
if (prevState.navActive !== this.state.navActive) {
this.showActiveNav()
}
}
getActivityStage = () => {
http.get(`${API.home}/activity/anniversary/activityStage`)
.then(res => {
const {code, msg, data} = res.data
if (code === 200) {
this.setState({
activityData: data,
}, this.bindNavAction);
} else {
Toast.info(msg)
}
})
}
getAuditionCourses = () => {
http.get(`${API.home}/activity/anniversary/big_course`)
.then(res => {
const {code, msg, data} = res.data
if (code === 200) {
this.setState({
auditions: data,
}, this.bindNavAction);
} else {
Toast.info(msg)
}
return 1
})
}
getGroupCourses = () => {
http.get(`${API.home}/activity/anniversary/point_course`)
.then(res => {
const {code, msg, data} = res.data
if (code === 200) {
this.setState({
group: data,
});
} else {
Toast.info(msg)
}
})
}
getStageCourses = (key) => {
http.get(`${API.home}/activity/anniversary/four_stage/${key}`)
.then(res => {
const {code, msg, data} = res.data
if (code === 200) {
this.setState(state => {
if (key === 'zero') {
return {
stageCourses: groupBy(data, item => {
return item.stage
}),
}
} else {
const index = this.stageParams.findIndex(item => item === key) + 1
state.stageCourses[index] = data
return {
stageCourses: state.stageCourses,
}
}
}, this.bindNavAction)
} else {
Toast.info(msg)
}
})
}
getPrizeData = () => {
http.get(`${API.home}/activity/anniversary/prize_data`)
.then(res => {
const {code, msg, data} = res.data
if (code === 200) {
this.setState({
prizeData: data,
})
} else {
Toast.info(msg)
}
})
}
getTeam = () => {
http.get(`${API.home}/activity/anniversary/teamInfo`)
.then(res => {
const {code, msg, data} = res.data
if (code === 200) {
this.setState({
team: data,
}, this.bindNavAction);
} else {
Toast.info(msg)
}
})
}
getPrizeRecords = (() => {
let hasMore = true, isFetching = false
return () => {
if (isFetching || !hasMore) {
return
}
isFetching = true
http.get(`${API.home}/activity/anniversary/user_prizes/${this.state.prizeRecordsPagination}`)
.then(res => {
const {code, msg, data} = res.data
if (code === 200) {
if (isEmpty(data)) {
hasMore = false
}
const _records = Array.isArray(data) ? data : []
this.setState(state => {
return {
prizeRecords: [...state.prizeRecords, ..._records],
prizeRecordsPagination: state.prizeRecordsPagination + 1,
}
}, () => {
setTimeout(() => {
isFetching = false
}, 100)
});
} else {
Toast.info(msg)
}
})
}
})()
handleRecordsScroll = debounce((e) => {
let scrollTop = e.target.scrollTop, scrollHeight = e.target.scrollHeight, height = e.target.clientHeight
if (scrollTop > scrollHeight - height - 120) {
this.getPrizeRecords()
}
}, 16)
componentWillUnmount() {
document.removeEventListener('scroll', this.setNavActive)
document.body.style.overflow = 'auto'
}
handleChange = e => {
let name = e.target.name, value = e.target.value
this.setState(state => {
return {
userAddress: {...state.userAddress, ...{[name]: value}},
}
});
}
submitUserAddress = () => {
http.post(`${API.home}/sys/update_address`, this.state.userAddress)
.then(res => {
const {code, msg} = res.data
if (code === 200) {
Toast.info('提交成功')
this.setState({
isShowUserAddress: false,
});
} else {
Toast.info(msg)
}
})
}
getUserAddress = () => {
http.get(`${API.home}/sys/user_address_info`)
.then(res => {
const {code, msg, data} = res.data
if (code === 200) {
this.setState({
userAddress: data,
});
}
})
}
bindNavAction = () => {
document.removeEventListener('scroll', this.setNavActive)
this.setNavActive()
this.setState({
sectionsPosition: this.state.navs.map(item => {
const el = document.querySelector(item.id)
return {
top: el.offsetTop - 50,
height: el.offsetHeight,
}
}),
}, () => {
document.addEventListener('scroll', this.setNavActive)
})
}
setNavActive = debounce(() => {
const {navActive, sectionsPosition} = this.state
const pageY = window.pageYOffset
for (let i = navActive; i < sectionsPosition.length; i++) {
const section = sectionsPosition[i]
const nextSection = sectionsPosition[i + 1]
const prevSection = i > 0 && sectionsPosition[i - 1]
if (pageY > section.top + section.height && nextSection) {
if (pageY < nextSection.top || pageY < nextSection.top + nextSection.height) {
this.setState({
navActive: i + 1,
});
break
}
} else {
if (pageY < section.top + section.height && prevSection && pageY < prevSection.top + prevSection.height) {
this.setState({
navActive: i - 1 ? i - 1 : 0,
})
break
}
}
}
}, 1000 / 60)
showRule = (content) => {
this.popupInstance = Popup({
className: 'rule-popup',
title: '活动规则',
content,
})
}
showActiveNav = () => {
const listItems = this.nav.querySelectorAll('li')
const activeItem = listItems[this.state.navActive]
const box = activeItem.getBoundingClientRect()
let offsetWidth = this.nav.offsetWidth, scrollLeft = this.nav.scrollLeft
if (box.left < 0) {
this.nav.scrollLeft = box.left
} else if (box.right > offsetWidth + scrollLeft) {
this.nav.scrollLeft = box.right
}
}
draw = () => {
}
render() {
const {
navs,
navActive,
titleImages,
rankIcons,
auditions,
auditionShowAll,
group,
groupShowAll,
stageCourses,
activityData,
team,
userAddress,
isShowUserAddress,
prizeData,
isShowPrizesRecords,
prizeRecords,
} = this.state
const {history} = this.props
const _auditions = auditionShowAll && auditions.length ? auditions : auditions.slice(0, 4)
const _group = groupShowAll && group.length ? group : group.slice(0, 4)
return (
<div className={'anniversary-2020'}>
<div className="banner">
<img src="" alt=""/>
</div>
<nav ref={el => this.nav = el}>
<ul>
{
navs.map((item, index) => {
return <li key={index} className={index === navActive ? 'active' : ''}>
<a href='javascript:void(0);' onClick={() => {
this.setState({
navActive: index,
});
window.scrollTo(0, this.state.sectionsPosition[index].top)
}}>{item.text}</a>
</li>
})
}
</ul>
</nav>
<section id={'group'} className="group block">
<h2 className="block-title"
style={{background: `url(${titleImages[0]}) no-repeat`, backgroundSize: 'contain'}}></h2>
<ul className={'course-container'}>
{
!!_group.length && _group.map((item, index) => {
let Button
if (activityData.stage === 1) {
Button = <button className={'unavailable'}>715日开始</button>
} else if (activityData.stage === 2) {
switch (item.is_assemble) {
case 0:
Button = <button className="main"><Link to={`/detail?id=${item.course_id}`}>立即拼团</Link></button>
break
case 1:
Button = <button className="main"><Link to={`/detail?id=${item.course_id}`}>继续拼团</Link></button>
break
default:
Button =
<button className={'study'}><Link to={`/play?id=${item.v_course_id}`}>开始学习</Link></button>
}
} else {
Button = <button className={'unavailable'}>活动已结束</button>
}
return <li className={'course'} key={index} onClick={(e) => {
let nodeName = e.target.nodeName.toLowerCase()
if (nodeName !== 'a' || nodeName !== 'button') {
history.push(`/detail?id=${item.course_id}`)
}
}}>
<div className="cover">
<img src={item.image_name}
alt=""/>
</div>
<div className="info">
<div className="title">{item.course_title}</div>
<div className="des">{item.simpledescription}</div>
{
item.is_buy
? <div className="purchased">已购买</div>
: <div className="prices">
<span>¥{item.price1}</span>
<span>¥{item.price0}</span>
</div>
}
<div className="btn">
{Button}
</div>
</div>
</li>
})
}
{
group.length > 4 &&
<li>
<button className={'show-more'} onClick={() => {
this.setState({
groupShowAll: true,
})
}}>查看更多
</button>
</li>
}
</ul>
</section>
<section id={'lottery'} className={'lottery block'}>
<div className="block-title"
style={{background: `url(${titleImages[1]}) no-repeat`, backgroundSize: 'contain'}}></div>
<div className="rule">
<a href="javascript:void(0);" onClick={this.showRule.bind(this, prizeData.rule)}>规则</a>
</div>
<div className="prize-container">
<div className={'h-bar'}></div>
<div className={'h-bar'}></div>
<div className={'v-bar'}></div>
<div className={'v-bar'}></div>
<ul className="prizes">
{
Array(9).fill('a').map((item, index) => {
return <li key={index}
className={index === 4 ? (prizeData.odd_times ? 'available' : 'unavailable') : ''}>
{
index !== 4
? <div className={'prize'}>
<img src="" alt=""/>
</div>
: activityData.stage === 1 ?
<div className={'draw'} style={{lineHeight: '350%'}}>715日开始</div> : <div className={'draw'}>
<div>抽奖</div>
<div>剩余{prizeData.odd_times || 0}次机会</div>
</div>
}
</li>
})
}
</ul>
</div>
<div className="content">
<div className={'operations'}>
<a href="javascript:void(0);" onClick={() => {
this.setState({
isShowUserAddress: true,
})
}}>收货信息</a>
<a href="javascript:void(0);" onClick={() => {
document.body.style.overflow = 'hidden'
this.setState({
isShowPrizesRecords: true,
}, () => {
this.records && this.records.addEventListener('scroll', this.handleRecordsScroll)
});
}}>中奖纪录</a>
</div>
<div className="lottery-info">
<div className={'title'}><i></i>如何获取更多抽奖机会?</div>
<ul className={'rules'}>
{
prizeData.more_rule && prizeData.more_rule.split('\n').map((item, index) => {
return <li key={index}>
<span className={'index'}>{index + 1}</span>
{item}
</li>
})
}
</ul>
</div>
</div>
</section>
<section id={'group-answer'} className={'group-answer block'}>
<div className="block-title" style={{background: `url(${titleImages[2]})`, backgroundSize: 'contain'}}></div>
<div style={{textAlign: 'center', marginBottom: '10px'}}>
<a className="rule-btn" href="javascript:void(0);"
onClick={this.showRule.bind(this, this.answerRule)}>规则</a>
</div>
<div className="content">
<div className="team">
<div className="func">
<i className={'my-team-icon'}></i>
<div className="summary">
<span><span className={'count'}>{team.people_num}</span>人</span>
<span>排名<span className={'count'}>{team.ranking}</span></span>
</div>
<ul>
{
!!team.team_info && team.team_info.length && team.team_info.map((item, index) => {
return <li key={index}>
<img
src="https://julyedu-img-public.oss-cn-beijing.aliyuncs.com/Public/Image/home/avatar_20191104.png"
alt=""/>
</li>
})
}
{
activityData.stage !== 1 && <li className={'more'}>更多</li>
}
</ul>
<div className="invite">
{
activityData.stage === 1 ? <button className={'invite'}>715日开始</button> :
<button className={'invite'}>邀请好友加入队伍</button>
}
</div>
</div>
<div className="des">
<div className="title">组队答题抽奖</div>
<ol>
<li>
1. 邀请好友加入队伍,好友答对题可获得一次抽奖机会;
</li>
<li>
2. 3个队员答对题,你可以获得N次抽奖机会,N=123(上限)。
</li>
</ol>
</div>
</div>
<div className="exercise">
<div className="func">
{
activityData.stage === 1
? <div className="btn">
<button>715日开始</button>
</div>
: <>
<div className="btn">
<button><i></i>开始练习</button>
</div>
< div className="chance">今日剩余<span>{activityData.practice_num}</span>次</div>
</>
}
</div>
<div className="des">
<div className="title">练一练</div>
<ol>
<li>1. 每日可练习 2 。每次 1 道题,从题库中随机抽取;</li>
<li> 2. 答对可增加1次抽奖机会。</li>
</ol>
</div>
</div>
<div className="rank-list">
<div className="title">测试排行榜</div>
<div className="description">仅展示前50名,队员越多、用时越短排名越靠前</div>
<div className="prize-display">
<ul>
<li className={'top-three'}>
<img src="https://julyedu-cdn.oss-cn-beijing.aliyuncs.com/active20_717/m/top1.png" alt=""/>
</li>
<li className={'top-three'}>
<img src="https://julyedu-cdn.oss-cn-beijing.aliyuncs.com/active20_717/m/top2.png" alt=""/>
</li>
<li className={'top-three'}>
<img src="https://julyedu-cdn.oss-cn-beijing.aliyuncs.com/active20_717/m/top3.png" alt=""/>
</li>
<li>
<img src="https://julyedu-cdn.oss-cn-beijing.aliyuncs.com/active20_717/m/top4%EF%BD%9E7.png"
alt=""/>
</li>
<li>
<img src="https://julyedu-cdn.oss-cn-beijing.aliyuncs.com/active20_717/m/top8%EF%BD%9E15.png"
alt=""/>
</li>
<li>
<img src="https://julyedu-cdn.oss-cn-beijing.aliyuncs.com/active20_717/m/top16%EF%BD%9E30.png"
alt=""/>
</li>
<li>
<img src="https://julyedu-cdn.oss-cn-beijing.aliyuncs.com/active20_717/m/top31%EF%BD%9E50.png"
alt=""/>
</li>
</ul>
</div>
{
prizeData.stage !== 1 && <table>
<thead>
<tr>
<th>名次</th>
<th>队长</th>
<th>队员</th>
<th>奖品</th>
</tr>
</thead>
<tbody>
{
Array(5).fill('a').map((item, index) => {
return <tr key={index}>
<td>
{
index < 3 ? <img src={rankIcons[index]} alt=""/> : index + 1
}
</td>
<td>
<img
src="https://julyedu-img-public.oss-cn-beijing.aliyuncs.com/Public/Image/home/avatar_20191104.png"
alt="" className={'avatar'}/>
限制宽度比例限制宽度比例
</td>
<td>723</td>
<td>最多就显示这么多几个字吧</td>
</tr>
})
}
</tbody>
</table>
}
<div className="btn">
<button>查看更多</button>
</div>
</div>
</div>
</section>
<section id={'audition'} className={'audition'}>
<div className="block-title"
style={{background: `url(${titleImages[3]}) no-repeat`, backgroundSize: 'contain'}}></div>
<ul className="course-container">
{
!!_auditions.length && _auditions.map((item, index) => {
return <li className={'course'} key={index} onClick={(e) => {
if (e.target.nodeName.toLowerCase() !== 'a') {
history.push(`/detail?id=${item.course_id}`)
}
}}>
<div className="cover">
<img src={item.image_name}
alt=""/>
</div>
<div className="info">
<div className="title">{item.course_title}</div>
<div className="des">{item.simpledescription}</div>
{
item.is_buy
? <div className="purchased">已购买</div>
: <div className="prices">
<span>¥{item.price1}</span>
<span>¥{item.price0}</span>
</div>
}
<div className="btn">
{
item.is_buy
?
<button className={'study-btn'}><Link to={`/play?id=${item.v_course_id}`}>开始学习</Link></button>
: <button className="audition-btn"><a
href="https://q.url.cn/AB8aue?_type=wpa&qidian=true">免费试听</a></button>
}
{
!!item.is_dist &&
<button><Link to={`/detail?id=${item.course_id}`}>{item.dist_amount}</Link></button>
}
</div>
</div>
</li>
})
}
{
auditions.length > 4 &&
<li>
<button className={'show-more'} onClick={() => {
this.setState({
auditionShowAll: true,
});
}}>查看更多
</button>
</li>
}
</ul>
</section>
<section id={'stage-course'} className={'stage-course'}>
<div className="block-title"
style={{background: `url(${titleImages[4]}) no-repeat`, backgroundSize: 'contain'}}></div>
<div className="course-container">
{
!isEmpty(stageCourses) && Object.keys(stageCourses).map(key => {
return <ul key={key}>
<li><span className={'stage'}>{this.stages[key]}</span></li>
{
!!stageCourses[key].length && stageCourses[key].map((item, index) => {
let Button = null
if (activityData.stage === 1) {
Button = <button className={'unavailable'}>715日开始</button>
} else if (activityData.stage === 2) {
switch (item.type) {
case 0:
Button = <button>立即报名</button>
break
case 1:
Button =
<button className={'study-btn'}><Link to={`/play?id=${item.v_course_id}`}>开始学习</Link>
</button>
break
case 2:
Button = <button><Link to={`/detail?id=${item.course_id}`}>立即拼团</Link></button>
break
case 3:
Button = <button><Link to={`/detail?id=${item.course_id}`}>继续参团</Link></button>
break
case 4:
Button = <button><Link to={`/detail?id=${item.course_id}`}>继续砍价</Link></button>
break
case 5:
Button = <button><Link to={`/detail?id=${item.course_id}`}>我要砍价</Link></button>
break
}
} else {
Button = <button className={'unavailable'}>活动已结束</button>
}
return <li className={'course'} key={index}>
<div className="cover">
{
item.save && <span>立省{item.save}</span>
}
<img src={item.image_name}
alt=""/>
</div>
<div className="info">
<div className="title">{item.course_title}</div>
<div className="des">{item.simpledescription}</div>
{
item.type === 1
? <div className="purchased">已购买</div>
: <div className="prices">
<span>¥{item.price0}</span>
<span>¥{item.price1}</span>
</div>
}
<div className="btn">
{Button}
{
!!item.is_dist && <button>{item.dist_amount}</button>
}
</div>
</div>
</li>
})
}
{
stageCourses[key].length === 4 && <li className={'show-more-box'}>
<button className={'show-more'}
onClick={() => this.getStageCourses(this.stageParams[key - 1])}>查看更多
</button>
</li>
}
</ul>
})
}
</div>
</section>
{
isShowUserAddress &&
<div className="modal-cover">
<div className="modal recipient">
<h4 className="title">收货信息</h4>
<div className="tip">获奖用户(以最终榜单为准)请及时填写收货信息</div>
<input type="text" name={'name'} value={userAddress.name} placeholder={'收件人'}
onChange={this.handleChange}/>
<input type="text" name={'phone'} value={userAddress.phone} placeholder={'联系方式'}
onChange={this.handleChange}/>
<input type="text" name={'address'} value={userAddress.address} placeholder={'收货地址'}
onChange={this.handleChange}/>
<button disabled={!userAddress.name || !userAddress.phone || !userAddress.address}
onClick={this.submitUserAddress}>提交
</button>
<i className={'iconfont iconiconfront-2 close'} onClick={() => {
this.setState({
isShowUserAddress: false,
})
}}></i>
</div>
</div>
}
{
isShowPrizesRecords && <div className={'modal-cover prize-records'}>
<div className="modal">
<h4 className="title">中奖纪录</h4>
<div className="content" ref={el => this.records = el}>
<div className="rule">
1. 现金红包自动发放到账户中,可前往 我的- 赚奖学金 中提现;<br/>
2. 代金券碎片自动发放到账户中,可前往优惠券 - 碎片合成 中兑换代金券;<br/>
3. 实物奖品请尽快填写收货信息,活动结束后统一邮寄。
</div>
<ul className={'records'}>
{
!!prizeRecords.length && prizeRecords.map((item, index) => {
return <li key={index}>
<div className="record">
<div className="name">
{item.prize_name} {(item.prize_type === 1 || item.prize_type === 2) && `${item.amount}元`}
</div>
<div className="time">{item.create_time}</div>
</div>
{
item.prize_type === 4 && <div className="contact">{item.prize_info}</div>
}
</li>
})
}
</ul>
<i className={'iconfont iconiconfront-2 close'} onClick={() => {
this.records.removeEventListener('scroll', this.handleRecordsScroll)
document.body.style.overflow = 'auto'
this.setState({
isShowPrizesRecords: false,
});
}}></i>
</div>
</div>
</div>
}
</div>
);
}
}
export default connect(
({user}) => ({user}),
null,
)(Anniversary2020);
\ No newline at end of file
.anniversary-2020 {
background-color: #2E00DC;
padding: 0 10px 75px;
.banner {
height: 220px;
img {
width: 100%;
height: 100%;
}
}
@mixin button {
-webkit-appearance: none;
outline: 0;
border: 0;
background: transparent;
}
nav {
position: sticky;
top: 0;
left: 0;
height: 44px;
margin-bottom: 20px;
margin-left: -10px;
margin-right: -10px;
background: #059BFF;
color: #fff;
font-size: 15px;
z-index: 100;
overflow: auto;
ul {
white-space: nowrap;
}
li {
display: inline-block;
line-height: 44px;
padding: 0 24px;
text-align: center;
&.active {
background: #FFE400;
color: #333;
}
}
}
a.rule-btn {
font-size: 14px;
color: #fff;
text-decoration: underline;
letter-spacing: 3px;
}
.block {
&:target {
&::before {
display: block;
content: " ";
margin-top: -75px; // Set the Appropriate Height
height: 75px; // Set the Appropriate Height
visibility: hidden;
}
}
&-title {
width: 150px;
height: 32px;
margin: 0 auto 10px;
}
.container {
padding: 10px;
border: 2px solid;
background: #2B5FFF;
border-image: linear-gradient(0deg, rgba(40, 0, 254, 1), rgba(60, 168, 255, 1)) 10 10;
border-radius: 2px;
}
}
.prices {
span:nth-child(1) {
color: #FF2121;
font-size: 18px;
margin-right: 10px;
}
span:nth-child(2) {
color: #777;
font-size: 12px;
text-decoration: line-through;
}
}
.cover {
position: relative;
flex: 0 0 auto;
width: 140px;
height: 101px;
margin-right: 10px;
span {
position: absolute;
top: 0;
right: 0;
display: inline-block;
width: 74px;
height: 22px;
background: linear-gradient(90deg, rgba(253, 61, 59, 1) 0%, rgba(255, 103, 77, 1) 100%);
border-radius: 11px 0 0 11px;
text-align: center;
font-size: 12px;
color: #fff;
line-height: 22px;
}
img {
width: 100%;
height: 100%;
}
}
.purchased {
font-size: 12px;
color: #09f;
}
.study {
width: 91px;
height: 28px;
background: rgba(0, 153, 255, 1);
border-radius: 2px;
font-size: 13px;
color: #fff;
}
.unavailable {
width: 91px;
height: 28px;
background: rgba(153, 153, 153, 1) !important;
border-radius: 2px;
color: #fff;
font-size: 13px;
}
.course-container {
width: 355px;
padding: 10px;
background: rgba(43, 95, 255, 1);
border: 2px solid;
border-image: linear-gradient(0deg, rgba(40, 0, 254, 1), rgba(60, 168, 255, 1)) 10 10;
border-radius: 2px;
li:last-child {
margin-top: 10px;
margin-bottom: 5px;
text-align: center;
}
.show-more {
@include button;
width: 95px;
height: 33px;
border: 1px solid rgba(255, 255, 255, 1);
border-radius: 17px;
color: #fff;
}
}
.course {
display: flex;
justify-content: space-between;
padding: 10px;
margin-bottom: 8px;
height: 121px;
background-color: #fff;
.info {
position: relative;
}
.title, .des {
width: 162px;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
.des {
margin-bottom: 8px;
}
.btn {
position: absolute;
left: 0;
bottom: 0;
button {
@include button;
height: 28px;
margin-right: 10px;
border-radius: 2px;
color: #fff;
}
}
}
.group {
margin-bottom: 20px;
.course .btn {
.main {
padding: 0 20px;
background: #FF2121;
}
.study-btn {
background: #09f;
}
}
}
.lottery {
margin-bottom: 20px;
background: rgba(45, 0, 219, 1);
border: 2px solid;
border-image: linear-gradient(0deg, rgba(39, 0, 253, 1), rgba(59, 167, 255, 1)) 10 10;
.block-title {
width: 217px;
height: 32px;
}
.rule {
margin: 10px 0;
font-size: 14px;
color: #fff;
text-align: center;
a {
text-decoration: underline;
letter-spacing: 4px;
}
}
.prize-container {
position: relative;
padding: 11px;
margin-bottom: 8px;
.h-bar {
position: absolute;
left: 50%;
top: 0;
transform: translateX(-50%);
width: 280px;
height: 6px;
background: url("./images/h-bar.png");
background-size: contain;
& + .h-bar {
top: initial;
bottom: 0;
}
}
.v-bar {
position: absolute;
top: 3px;
left: 0;
width: 6px;
height: 198px;
background: url("./images/v-bar.png");
background-size: contain;
& + .v-bar {
left: initial;
right: 0;
}
}
.prizes {
display: flex;
justify-content: space-around;
flex-wrap: wrap;
padding: 0 4px;
li {
width: 95px;
height: 55px;
padding: 5px;
background: #2658FF;
border-radius: 3px;
&:nth-child(n + 4) {
margin-top: 13px;
}
&:nth-child(5) {
background-size: contain;
&.available {
background: url("./images/lottery-button-available.png") no-repeat;
}
&.unavailable {
background: url("./images/draw.png") no-repeat !important;
}
}
}
.draw {
text-align: center;
color: #fff;
div:nth-child(1) {
font-size: 18px;
}
div:nth-child(2) {
font-size: 12px;
}
}
.prize {
display: flex;
justify-content: center;
align-items: center;
width: 85px;
height: 47px;
background: rgba(255, 254, 255, 1);
box-shadow: 0 0 1px 0 rgba(10, 12, 122, 0.3);
img {
max-width: 59px;
max-height: 38px;
}
}
}
}
.content {
padding-top: 10px;
padding-bottom: 18px;
background: #2558FF;
}
.operations {
display: flex;
justify-content: space-between;
padding: 0 20px;
margin-bottom: 15px;
a {
color: #FFFDFF;
font-size: 14px;
text-decoration: underline;
}
}
.lottery-info {
.title {
display: flex;
align-items: center;
width: 223px;
height: 30px;
padding-left: 18px;
margin: 0 auto 9px;
background: linear-gradient(90deg, rgba(37, 87, 255, 1) 0%, rgba(46, 0, 219, 1) 100%);
border-radius: 15px;
font-size: 15px;
color: #FFFDFF;
i {
display: inline-block;
width: 14px;
height: 16px;
margin-right: 9px;
background: url("./images/lottery-icon.png") no-repeat;
background-size: contain;
}
}
li {
padding: 0 10px;
font-size: 12px;
color: #FFFDFF;
}
.index {
display: inline-block;
width: 12px;
height: 12px;
margin-right: 6px;
background: rgba(255, 217, 9, 1);
border-radius: 50%;
color: #2D00DB;
text-align: center;
line-height: 12px;
}
}
}
.group-answer {
margin-bottom: 20px;
.content {
width: 355px;
padding: 10px 7px 0;
background: rgba(43, 95, 255, 1);
border: 2px solid;
border-image: linear-gradient(0deg, rgba(39, 0, 253, 1), rgba(59, 167, 255, 1)) 10 10;
border-radius: 2px;
}
.func {
position: relative;
width: 341px;
height: 149px;
padding-top: 12px;
margin: 0 auto;
}
.des {
width: 341px;
height: 95px;
margin-top: -9px;
margin-bottom: 15px;
background: rgba(34, 39, 255, 1);
border-radius: 0 0 4px 4px;
.title {
position: relative;
padding: 8px 0;
font-size: 14px;
color: #fff;
opacity: .5;
text-align: center;
@mixin pseudo {
position: absolute;
top: 50%;
transform: translateY(-50%);
content: '';
width: 10px;
height: 2px;
background-color: #fff;
display: block;
}
&::before {
@include pseudo;
left: 103px;
}
&::after {
@include pseudo;
right: 103px;
}
}
ol {
padding: 0 15px;
font-size: 12px;
color: #EFF1FF;
}
}
.team {
i {
position: absolute;
left: 0;
top: 15px;
display: inline-block;
width: 84px;
height: 25px;
background: url("./images/my-team.png");
background-size: contain;
}
.func {
background: url("https://julyedu-cdn.oss-cn-beijing.aliyuncs.com/active20_717/m/team-info-bg.png");
background-size: contain;
li {
width: 30px;
height: 30px;
border: 0 solid rgba(255, 255, 255, 1);
border-radius: 50%;
overflow: hidden;
line-height: 30px;
text-align: center;
&:last-child {
border: 1px solid #fff;
color: #fff;
}
}
}
.summary {
font-size: 12px;
text-align: center;
color: #fff;
span:nth-child(2) {
margin-left: 20px;
}
.count {
font-size: 18px;
margin: 0 5px;
}
}
ul {
display: flex;
justify-content: space-around;
padding: 0 33px;
margin-top: 10px;
margin-bottom: 15px;
}
.invite {
text-align: center;
button {
@include button;
width: 160px;
height: 30px;
background: rgba(255, 228, 0, 1);
border-radius: 4px;
color: #2127FF;
font-size: 14px;
}
}
}
.exercise {
.func {
height: 127px;
padding-top: 34px;
background: url("https://julyedu-cdn.oss-cn-beijing.aliyuncs.com/active20_717/m/exercise-bg.png") no-repeat;
background-size: contain;
text-align: center;
color: #fff;
.btn {
margin-bottom: 9px;
button {
@include button;
width: 160px;
height: 30px;
background: linear-gradient(90deg, rgba(34, 221, 255, 1) 0%, rgba(57, 167, 255, 1) 100%);
border-radius: 4px;
font-size: 14px;
line-height: 30px;
color: #fff;
}
i {
display: inline-block;
width: 14px;
height: 14px;
margin-right: 8px;
background: url("./images/start-exercise.png");
background-size: contain;
}
}
span {
font-size: 18px;
margin: 0 5px;
}
}
}
.rank-list {
color: #fff;
.title {
position: relative;
text-align: center;
font-size: 18px;
@mixin pseudo {
content: '';
display: block;
position: absolute;
top: 50%;
transform: translateY(-50%);
width: 25px;
height: 11px;
background: url("./images/rank-title-decorator.png");
}
&::before {
@include pseudo;
left: 90px;
background-size: contain;
}
&::after {
@include pseudo;
right: 90px;
transform: translateY(-50%) scale(-1);
background-size: contain;
}
}
.description {
margin-top: 10px;
margin-bottom: 18px;
text-align: center;
font-size: 12px;
opacity: .8;
}
.prize-display {
ul {
display: flex;
flex-wrap: wrap;
justify-content: space-between;
}
li {
img {
width: 167px;
height: 80px;
}
}
.top-three {
img {
width: 110px;
height: 100px;
}
&:nth-child(3) {
margin-right: 0;
}
}
}
.btn {
height: 58px;
padding-top: 10px;
text-align: center;
button {
@include button;
width: 95px;
height: 33px;
border: 1px solid rgba(255, 255, 255, 1);
border-radius: 17px;
font-size: 14px;
color: #fff;
}
}
}
}
.audition {
margin-bottom: 20px;
.block-title {
width: 197px;
height: 32px;
}
.course {
.btn {
display: flex;
justify-content: space-between;
width: 100%;
font-size: 0;
button {
padding: 0 5%;
font-size: 13px;
border-radius: 2px;
margin: 0;
}
.study-btn {
background: #09f;
}
.audition-btn {
background: linear-gradient(90deg, rgba(0, 201, 235, 1) 0%, rgba(0, 138, 242, 1) 100%);
}
button:nth-child(2) {
margin-right: 0;
background: linear-gradient(90deg, rgba(255, 68, 0, 1) 2%, rgba(255, 0, 2, 1) 100%);
}
}
}
}
.stage-course {
.block-title {
width: 252px;
height: 32px;
}
.stage {
display: inline-block;
width: 85px;
height: 26px;
line-height: 26px;
background: linear-gradient(90deg, rgba(43, 95, 255, 1) 0%, rgba(46, 0, 220, 1) 100%);
border-radius: 13px;
font-size: 14px;
color: #fff;
}
.course-container {
li:first-child {
margin-top: 20px;
margin-bottom: 15px;
text-align: center;
}
}
.show-more-box {
text-align: center;
}
.show-more {
margin-bottom: 20px;
}
.prices {
text-align: left;
}
.course {
.btn {
display: flex;
justify-content: space-between;
width: 100%;
button {
padding: 0 5%;
font-size: 13px;
border-radius: 2px;
margin-right: 0;
}
button:nth-child(1) {
background: linear-gradient(90deg, rgba(0, 201, 235, 1) 0%, rgba(0, 138, 242, 1) 100%);
}
button:nth-child(2) {
background: linear-gradient(90deg, rgba(255, 68, 0, 1) 2%, rgba(255, 0, 2, 1) 100%);
}
}
}
}
table {
width: 105%;
margin: 10px -7px 0;
text-align: center;
border-collapse: collapse;
table-layout: fixed;
thead {
height: 38px;
line-height: 38px;
background: #00CBFF;
color: #fff;
border-spacing: 0;
font-size: 0;
th {
width: 25%;
font-size: 14px;
&:nth-child(1) {
width: 10%;
}
&:nth-child(2) {
width: 30%;
}
&:nth-child(3) {
width: 15%;
}
&:nth-child(4) {
width: 43%;
}
}
}
tbody {
tr {
height: 48px;
line-height: 48px;
font-size: 12px;
&:nth-of-type(even) {
background: #2139F1;
}
}
}
td:nth-of-type(1) {
font-size: 16px;
img {
width: 14px;
height: 18px;
}
}
td:nth-of-type(2) {
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
.avatar {
width: 18px;
height: 18px;
margin-right: 6px;
border-radius: 50%;
vertical-align: middle;
}
}
.modal-cover {
position: fixed;
top: 0;
left: 0;
right: 0;
bottom: 0;
background-color: rgba(0, 0, 0, .6);
z-index: 200;
.modal {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
width: 300px;
padding: 20px 25px;
background: #fff;
border-radius: 10px;
}
.close {
position: absolute;
bottom: -54px;
left: 50%;
transform: translateX(-50%);
font-size: 24px;
color: #fff;
}
.title {
font-size: 16px;
color: #525C65;
text-align: center;
margin-bottom: 6px;
}
.tip {
font-size: 13px;
color: #ED6A1D;
}
.recipient {
input {
width: 100%;
height: 40px;
line-height: 40px;
padding: 0 10px;
margin-top: 10px;
border: 1px solid #DDD;
font-size: 13px;
&:first-child {
margin-top: 15px;
}
&::placeholder {
color: #999;
}
}
button {
@include button;
width: 121px;
height: 33px;
transform: translateX(50%);
margin-top: 18px;
border-radius: 17px;
color: #fff;
font-size: 15px;
background: #09f;
&[disabled] {
background: rgba(84, 92, 100, .3);
}
}
}
}
}
.rule-popup {
.title {
font-size: 16px;
color: #525C65;
text-align: center;
margin-bottom: 6px;
}
.content {
font-size: 14px;
color: #525C65;
white-space: pre-line;
line-height: 21px;
}
}
.prize-records {
.modal {
padding-left: 15px !important;
padding-right: 15px !important;
}
.content {
max-height: 280px;
overflow: auto;
}
.rule {
font-size: 13px;
color: #ED6A1D;
white-space: pre-line;
}
.records {
li {
.record {
display: flex;
justify-content: space-between;
width: 270px;
height: 30px;
margin-top: 5px;
line-height: 30px;
background: rgba(255, 255, 255, 1);
border: 1px solid rgba(209, 219, 228, .4);
}
.name {
width: 140px;
white-space: nowrap;
text-overflow: ellipsis;
overflow: hidden;
color: #271BD3;
font-size: 12px;
}
.time {
color: #545C64;
font-size: 12px;
}
}
}
.contact {
width: 270px;
height: 15px;
line-height: 15px;
background: rgba(240, 240, 240, 1);
color: #333;
font-size: 12px;
text-align: center;
}
}
\ No newline at end of file
...@@ -346,4 +346,9 @@ export default [ ...@@ -346,4 +346,9 @@ export default [
path: '/problems/:id', path: '/problems/:id',
component: loadable(() => import('@/components/problems')), component: loadable(() => import('@/components/problems')),
}, },
//2020-717
{
path: '/anniversary_2020',
component: loadable(() => import('@/components/activity/2020-717')),
},
] ]
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