Commit 69d4a07e by zhanghaozhe

周年庆

parent 641df1d2
...@@ -33,14 +33,19 @@ ...@@ -33,14 +33,19 @@
overflow: auto; overflow: auto;
ul { ul {
display: inline-flex;
height: 100%;
white-space: nowrap; white-space: nowrap;
} }
li { li {
display: inline-block; display: flex;
line-height: 44px; align-items: center;
padding: 0 24px; width: 100px;
height: 100%;
padding: 0 1em;
text-align: center; text-align: center;
white-space: normal;
&.active { &.active {
background: #FFE400; background: #FFE400;
...@@ -49,6 +54,17 @@ ...@@ -49,6 +54,17 @@
} }
} }
.sign {
position: fixed;
top: 25%;
right: 0;
width: 56px;
height: 54px;
background: url("../images/sign.png");
background-size: contain;
z-index: 101;
}
a.rule-btn { a.rule-btn {
font-size: 14px; font-size: 14px;
color: #fff; color: #fff;
...@@ -227,8 +243,7 @@ ...@@ -227,8 +243,7 @@
.lottery { .lottery {
margin-bottom: 20px; margin-bottom: 20px;
background: rgba(45, 0, 219, 1); 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 { .block-title {
width: 217px; width: 217px;
...@@ -247,10 +262,77 @@ ...@@ -247,10 +262,77 @@
} }
} }
.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;
}
}
}
.prize-container { .prize-container {
border: 2px solid;
border-image: linear-gradient(0deg, rgba(39, 0, 253, 1), rgba(59, 167, 255, 1)) 10 10;
.prize-wrapper {
position: relative; position: relative;
padding: 11px; padding: 11px;
margin-bottom: 8px; margin-bottom: 8px;
}
.h-bar { .h-bar {
position: absolute; position: absolute;
...@@ -311,6 +393,10 @@ ...@@ -311,6 +393,10 @@
background: url("../images/draw.png") no-repeat !important; background: url("../images/draw.png") no-repeat !important;
} }
} }
&.active {
background: #FFE300;
}
} }
.draw { .draw {
...@@ -343,65 +429,17 @@ ...@@ -343,65 +429,17 @@
} }
} }
.content { .am-carousel {
padding-top: 10px; margin-bottom: 6px;
padding-bottom: 18px; text-align: center;
background: #2558FF;
}
.operations {
display: flex;
justify-content: space-between;
padding: 0 20px;
margin-bottom: 15px;
a {
color: #FFFDFF;
font-size: 14px; font-size: 14px;
text-decoration: underline; color: #FFDA09;
}
}
.lottery-info { .bullet {
.title { width: 351px;
display: flex;
align-items: center;
width: 223px;
height: 30px; height: 30px;
padding-left: 18px; line-height: 30px;
margin: 0 auto 9px; background: linear-gradient(90deg, rgba(46, 0, 220, 1) 0%, rgba(141, 10, 255, 1) 49%, rgba(46, 0, 220, 1) 100%);
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;
}
} }
} }
...@@ -554,6 +592,12 @@ ...@@ -554,6 +592,12 @@
.btn { .btn {
margin-bottom: 9px; margin-bottom: 9px;
&.no-chance {
button {
background: #999;
}
}
button { button {
@include button; @include button;
width: 160px; width: 160px;
...@@ -870,7 +914,6 @@ ...@@ -870,7 +914,6 @@
transform: translateX(-50%); transform: translateX(-50%);
font-size: 24px; font-size: 24px;
color: #fff; color: #fff;
} }
.title { .title {
...@@ -996,3 +1039,81 @@ ...@@ -996,3 +1039,81 @@
text-align: center; text-align: center;
} }
} }
.win-prize {
.des {
margin-bottom: 30px;
text-align: center;
font-size: 15px;
color: #545C64;
.name {
color: #EB5018;
}
}
.contact {
width: 250px;
height: 40px;
margin-bottom: 40px;
line-height: 40px;
border: 1px solid rgba(221, 221, 221, 1);
color: #271BD3;
text-align: center;
}
button {
width: 121px;
height: 33px;
transform: translateX(50%);
background: rgba(0, 153, 255, 1);
border-radius: 17px;
font-size: 15px;
color: #fff;
-webkit-appearance: none;
outline: 0;
border: 0;
}
}
.members {
li {
display: flex;
align-items: center;
justify-content: space-between;
height: 44px;
line-height: 44px;
font-size: 14px;
border-bottom: 1px solid #E5E5E5;
> div {
display: flex;
align-items: center;
}
.avatar {
width: 24px;
height: 24px;
margin-right: 10px;
border-radius: 50%;
}
.username {
color: #333;
}
.status {
&.correct {
color: #2CDBAF;
}
&.wrong {
color: #FF6000;
}
&.unanswered {
color: #525C65;
}
}
}
}
\ No newline at end of file
...@@ -2,6 +2,7 @@ import React, { Component } from 'react'; ...@@ -2,6 +2,7 @@ import React, { Component } from 'react';
import { Switch, Route } from "react-router-dom"; import { Switch, Route } from "react-router-dom";
import Anniversary2020 from "@components/activity/2020-717/activity" import Anniversary2020 from "@components/activity/2020-717/activity"
import Question from "@components/activity/2020-717/question" import Question from "@components/activity/2020-717/question"
import Invitation from "@components/activity/2020-717/invitation"
class Anniversary2020Entry extends Component { class Anniversary2020Entry extends Component {
...@@ -9,7 +10,9 @@ class Anniversary2020Entry extends Component { ...@@ -9,7 +10,9 @@ class Anniversary2020Entry extends Component {
const match = this.props.match const match = this.props.match
return ( return (
<Switch> <Switch>
<Route path={`${match.path}/question/:assistId?`} render={routeProps => (<Question {...routeProps}></Question>)}></Route> <Route path={`${match.path}/question/:assistId?`}
render={routeProps => (<Question {...routeProps}></Question>)}></Route>
<Route path={`${match.path}/invitation`} render={routeProps => (<Invitation {...routeProps}/>)}></Route>
<Route path={'/anniversary_2020'} <Route path={'/anniversary_2020'}
render={routeProps => (<Anniversary2020 {...routeProps}></Anniversary2020>)}></Route> render={routeProps => (<Anniversary2020 {...routeProps}></Anniversary2020>)}></Route>
</Switch> </Switch>
......
import React, { Component } from 'react';
import './index.scss'
import { WithFullSize } from "@/HOCs"
import { connect } from "react-redux";
import { compose } from "redux";
import { HeaderBar } from "@common/index"
import { getParam, http, browser } from "@/utils"
import { Toast } from "antd-mobile";
import { CopyToClipboard } from "react-copy-to-clipboard";
class Invitation extends Component {
state = {
prizes: [],
invitationInfo: {},
inviteUid: getParam('invite_uid'),
isShowGuide: false,
teamInfo: {},
isTeamHead: true,
isMaster: !getParam('team_code'),
isActivityEnd: false,
}
componentDidMount() {
this.getPrizesInfo()
if (getParam('team_code')) {
this.getTeamInfo()
} else {
this.getInvitationInfo()
}
}
getPrizesInfo = () => {
http.get(`${API.home}/activity/anniversary/prizeInfo`)
.then(res => {
const {code, msg, data} = res.data
data.splice(4, 0, {})
if (code === 200) {
this.setState({
prizes: data,
});
} else {
Toast.info(msg)
}
})
}
getInvitationInfo = () => {
http.get(`${API.home}/activity/anniversary/invite`, {
params: {
invite_uid: this.state.inviteUid || 0,
},
})
.then(res => {
const {code, msg, data} = res.data
if (code === 200) {
this.setState({
invitationInfo: data,
});
} else {
Toast.info(msg)
}
})
}
getTeamInfo = () => {
http.get(`${API.home}/activity/anniversary/assist`, {
params: {
team_code: getParam('team_code'),
},
})
.then(res => {
const {code, msg, data} = res.data
if (code === 200) {
this.setState({
teamInfo: data,
});
} else {
Toast.info(msg)
}
}).catch(err => {
Toast.fail('请求过于频繁,请稍后再试')
})
}
joinTeam = () => {
const {user, history} = this.props
if (user.hasError) {
if (browser.isWeixin) {
window.location.href = "https://open.weixin.qq.com/connect/oauth2/authorize?appid=wx23dac6775ac82877&redirect_uri=" + encodeURIComponent(url + "&aa=bb").toLowerCase() + "&response_type=code&scope=snsapi_userinfo&state=STATE#wechat_redirect"
} else {
history.push('/passport')
}
return
}
http.post(`${API.home}/activity/anniversary/joinTeam`, {
team_code: getParam('team_code'),
})
.then(res => {
const {code, msg} = res.data
if (code === 200) {
Toast.info('加入成功')
this.setState((state, props) => {
return {
teamInfo: {...state.teamInfo, ...{status: 2}},
}
});
} else if (code === 25015) {
this.setState({
isActivityEnd: true,
});
} else {
Toast.info(msg)
}
})
}
render() {
const {prizes, invitationInfo, isShowGuide, teamInfo, isMaster, isActivityEnd} = this.state
const {location} = this.props
return (
<div id={'invitation'}>
<HeaderBar title={'答题抽奖'} arrow={true}/>
{
isMaster
? <div className="banner"></div>
: <div className="team-head">
<img src={teamInfo.avatar_file} alt=""/>
<div className="username">{teamInfo.user_name}</div>
<div>加入我的队伍,一起答题抽大奖</div>
</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">
{
!!prizes.length && prizes.map((item, index) => {
return <li key={index}
className={index === 4 ? 'empty' : ''}>
{
index === 4
? <div>答题抽奖</div>
: <div className={'prize'}><img src={item.img_name} alt=""/></div>
}
</li>
})
}
</ul>
<div className="op">
{
isMaster ?
<>
<div className="tip">再有{invitationInfo.invite_num}位队员答对即可获得{invitationInfo.draw_chance}次抽奖机会</div>
{
browser.isWeixin
? <button className={'btn'} onClick={() => {
this.setState({
isShowGuide: true,
});
}}>立即邀请</button>
: <CopyToClipboard text={`${API.m}${location.pathname}?team_code=${invitationInfo.team_code}`}
onCopy={() => {
Toast.info('链接已复制,快去粘贴发给好友吧')
}}>
<button className={'btn'}>立即邀请</button>
</CopyToClipboard>
}
</>
: <>
{
teamInfo.status !== 1 && <div className={'tip'}>
{
teamInfo.status === 2 ? '已加入当前队伍' : teamInfo === 3 ? '已加入其他队伍' : null
}
</div>
}
{
isActivityEnd
? <button className={'activity-end'}>活动结束</button>
: teamInfo.status === 1
? <button className={'btn'} onClick={this.joinTeam}>加入队伍</button>
: <button className={'btn'}>答题抽奖</button>
}
</>
}
</div>
</div>
{
isShowGuide && <div className="guide" onClick={() => {
this.setState({
isShowGuide: false,
});
}}>
<i className={'indicator'}></i>
<div className="tip">点击右上角,分享给好友</div>
</div>
}
</div>
);
}
}
export default compose(
WithFullSize,
connect(
({user}) => ({user}),
null,
),
)(Invitation);
\ No newline at end of file
#invitation {
height: 100%;
background: #2E00DC;
.banner {
height: 67px;
margin: 20px 0;
background: url("https://julyedu-cdn.oss-cn-beijing.aliyuncs.com/active20_717/m/invitation-banner.png");
background-size: contain;
}
.prize-container {
position: relative;
padding: 15px;
margin: 0 auto 8px;
width: 355px;
height: 219px;
background: rgba(39, 27, 211, 1);
border: 4px solid;
border-image: linear-gradient(0deg, rgba(33, 32, 244, 1), rgba(94, 167, 248, 1)) 10 10;
.h-bar {
position: absolute;
left: 50%;
top: 5px;
transform: translateX(-50%);
width: 280px;
height: 6px;
background: url("../images/h-bar.png");
background-size: contain;
& + .h-bar {
top: initial;
bottom: 5px;
}
}
.v-bar {
position: absolute;
top: 9px;
left: 7px;
width: 6px;
height: 198px;
background: url("../images/v-bar.png");
background-size: contain;
& + .v-bar {
left: initial;
right: 7px;
}
}
.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;
text-align: center;
&:nth-child(n + 4) {
margin-top: 9px;
}
&:nth-child(5) {
background: #335DF6;
color: #fff;
line-height: 45px;
font-size: 16px;
border-radius: 4px;
}
}
.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;
}
}
}
}
.team-head {
height: 176px;
padding: 40px 70px;
margin-bottom: 20px;
background: url("https://julyedu-cdn.oss-cn-beijing.aliyuncs.com/active20_717/m/team-head.png") no-repeat;
background-size: contain;
text-align: center;
img {
width: 44px;
height: 44px;
margin-bottom: 7px;
border-radius: 50%;
}
.username {
margin-bottom: 17px;
font-size: 15px;
color: #333;
}
div:last-child {
color: #2E00DC;
font-size: 16px;
}
}
.op {
position: fixed;
bottom: 40px;
left: 0;
width: 100%;
text-align: center;
button {
font-size: 18px;
color: #fff;
-webkit-appearance: none;
outline: 0;
border: 0;
}
.btn {
width: 210px;
height: 40px;
line-height: 40px;
background: #FAE44D;
border-radius: 4px;
color: #2034F5;
}
}
.tip {
margin-bottom: 20px;
font-size: 15px;
color: #fff;
}
.guide {
position: fixed;
top: 0;
left: 0;
bottom: 0;
right: 0;
background: rgba(0, 0, 0, .6);
img {
position: absolute;
right: 15px;
top: 10px;
width: 60px;
height: 44px;
}
.indicator {
display: block;
position: absolute;
right: 15px;
top: 10px;
width: 60px;
height: 44px;
background: url("../images/indicator.png");
background-size: contain;
}
.tip {
position: absolute;
top: 74px;
left: 50%;
transform: translateX(-50%);
width: 290px;
height: 62px;
background: rgba(255, 255, 255, 1);
border-radius: 10px;
text-align: center;
color: #525B65;
font-size: 18px;
line-height: 62px;
}
}
.activity-end {
width: 210px;
height: 40px;
background: rgba(153, 153, 153, 1);
border-radius: 4px;
}
}
\ No newline at end of file
...@@ -2,20 +2,40 @@ import React, { Component } from 'react'; ...@@ -2,20 +2,40 @@ import React, { Component } from 'react';
import './index.scss' import './index.scss'
import { Toast } from "antd-mobile"; import { Toast } from "antd-mobile";
import classnames from 'classnames' import classnames from 'classnames'
import { http } from "@/utils" import { browser, http } from "@/utils"
import { WithFullSize } from "@/HOCs"
import { Link } from "react-router-dom";
import { compose } from 'redux'
import { connect } from 'react-redux'
import { addData, ADD_RECOMMENDS, ADD_QUESTION, ADD_RESULT, REDO } from './store/reducer'
class Question extends Component { class Question extends Component {
state = { state = {
question: {}, question: {},
selectedIndex: 0, result: {},
correctIndex: 2, recommends: [],
wrongIndex: 3, selectedOptionId: 0,
isShowConfirm: false,
isTeamHead: this.props.match.params.assistId === undefined,
isActivityEnd: false,
} }
componentDidMount() { componentDidMount() {
const {history, user} = this.props
if (user.hasError) {
if (browser.isWeixin) {
window.location.href = "https://open.weixin.qq.com/connect/oauth2/authorize?appid=wx23dac6775ac82877&redirect_uri=" + encodeURIComponent(url + "&aa=bb").toLowerCase() + "&response_type=code&scope=snsapi_userinfo&state=STATE#wechat_redirect"
} else {
history.push('/passport')
}
return
}
if (this.props.cache.recommends.length === 0) {
this.getQuestion() this.getQuestion()
} }
}
getQuestion = () => { getQuestion = () => {
const assistId = this.props.match.params.assistId const assistId = this.props.match.params.assistId
...@@ -23,17 +43,106 @@ class Question extends Component { ...@@ -23,17 +43,106 @@ class Question extends Component {
.then(res => { .then(res => {
const {code, msg, data} = res.data const {code, msg, data} = res.data
if (code === 200) { if (code === 200) {
this.props.addData({
type: ADD_QUESTION,
payload: data,
})
} else {
Toast.info(msg)
}
})
}
select = (id) => {
this.setState({
selectedOptionId: id,
});
}
submit = () => {
const assistId = this.props.match.params.assistId
const {selectedOptionId} = this.state
http.post(`${API.home}/activity/anniversary/submit`, {
type: assistId ? 2 : 1,
option_id: selectedOptionId,
id: this.props.cache.question.id,
}).then(res => {
const {code, msg, data} = res.data
if (code === 200) {
this.getRecommends(data.type_id)
this.afterSubmitted(data)
this.setState({ this.setState({
question: data, isShowConfirm: false,
selectedOptionId: undefined,
}); });
this.props.addData({
payload: data,
type: ADD_RESULT,
})
} else { } else {
Toast.info(msg) Toast.info(msg)
} }
}) })
} }
afterSubmitted = (result) => {
const {isTeamHead} = this.state
if (isTeamHead) {
if (result.stage === 4) {
} else {
result.is_correct ? Toast.info('回答正确 抽奖次数+1') : Toast.info('很遗憾 回答错误')
}
} else {
}
}
getRecommends = typeId => {
http.post(`${API.home}/sys/get_commend_course`, {
type_id: typeId,
})
.then(res => {
const {code, data} = res.data
if (code === 200) {
this.props.addData({
payload: data,
type: ADD_RECOMMENDS,
})
}
})
}
getOptionLabel = (index) => {
return String.fromCharCode(65 + index)
}
redo = () => {
this.props.addData({
type: REDO,
})
this.getQuestion()
}
render() { render() {
const {question, selectedIndex, correctIndex, wrongIndex} = this.state const {
selectedOptionId,
isShowConfirm,
isActivityEnd,
isTeamHead,
} = this.state
const {
cache: {
question,
result,
recommends,
},
} = this.props
return ( return (
<div id={'question'}> <div id={'question'}>
<div className="banner"></div> <div className="banner"></div>
...@@ -43,48 +152,120 @@ class Question extends Component { ...@@ -43,48 +152,120 @@ class Question extends Component {
{ {
question.options && !!question.options.length && question.options.map((item, index) => { question.options && !!question.options.length && question.options.map((item, index) => {
return <li key={item.id} className={classnames({ return <li key={item.id} className={classnames({
selected: selectedIndex === index, selected: selectedOptionId === item.id,
correct: correctIndex === index, correct: result.right_id === item.id,
wrong: wrongIndex === index, wrong: !result.is_correct && parseInt(result.option_id) === item.id,
})}> })} onClick={this.select.bind(this, item.id)}>
<span>{String.fromCharCode(65 + index)}</span> <span>{this.getOptionLabel(index)}</span>
{item.des} {item.des}
</li> </li>
}) })
} }
</ul> </ul>
</div> </div>
<div className="answered"> {
result.analysis && <div className="answered">
<div className="analysis"> <div className="analysis">
<div className="estimate"> <div className="estimate">
您选择的是C,正确答案是D 回答错误 您选择的是{this.getOptionLabel(question.options.findIndex(item => item.id == result.option_id))},正确答案是{this.getOptionLabel(question.options.findIndex(item => item.id === result.right_id))} 回答{result.right_id == result.option_id ? '正确' : '错误 '}
</div> </div>
<div className="analysis-content"> <div className="analysis-content">
<div className="title"> <div className="title">
<i className={'icon'}></i> <i className={'icon'}></i>
解析 解析
</div> </div>
<div className="content"> <div className="content" dangerouslySetInnerHTML={{__html: result.analysis}}></div>
解析内容解析内容解析内容解析内容解析内容解析内容解析内容解析内容解析内容解析内容解析内容解析内容解析内容解析内容解析内容解析内容解析内容解析内容解析内容解析内容解析内容解析内容解析内容解析内容解析内容解析内容解析内容解析内容解析内容解析内容解析内容解析内容解析内容解析内容解析内容解析内容解析内容解析内容解析内容解析内容解析内容解析内容解析内容解析内容解析内容解析内容解析内容解析内容解析内容解析内容解析内容解析内容解析内容解析内容解析内容解析内容解析内容解析内容解析内容解析内容解析内容解析内容解析内容解析内容解析内容解析内容解析内容解析内容解析内容解析内容解析内容解析内容解析内容解析内容解析内容解析内容解析内容解析内容解析内容解析内容解析内容
</div> </div>
</div> </div>
{
!!recommends.length && <Recommends recommends={recommends}></Recommends>
}
</div> </div>
<div className="recommends"> }
<div className="title">相关课程</div> <div className="submit-bar">
<ul> <BottomButton result={result}
<li> isTeamHead={isTeamHead}
submit={() => {
if (this.state.selectedOptionId) {
this.setState({
isShowConfirm: true,
});
}
}}
redo={this.redo}
/>
</div>
{
isShowConfirm &&
<Confirm submit={this.submit} cancel={() => {
this.setState({
isShowConfirm: false,
});
}}></Confirm>
}
</div>
);
}
}
</li> function Confirm({submit, cancel}) {
</ul> return <div className="modal-cover">
<div className="modal">
<div className="title">提交确认</div>
<div className="btns">
<button onClick={cancel}>取消</button>
<button onClick={submit}>确认提交</button>
</div> </div>
</div> </div>
<div className="submit-bar">
<button className={'submit'}>提交</button>
{/*<button className={'lottery-related'}>去抽奖</button>*/}
</div> </div>
}
function Result() {
return <div className={'modal-cover'}>
<div className="modal">
<div className="title"></div>
</div> </div>
); </div>
}
function BottomButton({result, submit, isTeamHead, redo}) {
if (result.stage === 4) {
return <button className={'activity-end'}>活动已结束</button>
}
if (isTeamHead) {
if (result.analysis) {
return result.practiceNum === 0
? <button className={'lottery-related'}><Link to={`/anniversary_2020/invitation`}>组队答题抽奖</Link></button>
: <button className={'submit'} onClick={redo}>继续答题</button>
}
} }
return <button className={'submit'} onClick={submit}>提交</button>
}
function Recommends({recommends}) {
return <div className="recommends">
<div className="title">相关课程</div>
<ul>
{
recommends && !!recommends.length && recommends.map(item => {
return <li key={item.course_id}>
<Link to={`/detail?id=${item.course_id}`}>
<img src={item.image_name} alt=""/>
</Link>
</li>
})
}
</ul>
</div>
} }
export default Question; export default compose(
\ No newline at end of file WithFullSize,
connect(
({anniversary2020Question, user}) => ({cache: anniversary2020Question, user}),
dispatch => ({
addData: data => dispatch(addData(data)),
}),
),
)(Question);
\ No newline at end of file
html, body {
min-height: 100%;
}
#root {
min-height: 100%;
}
#question { #question {
background: #F5F5F5; background: #F5F5F5;
min-height: 100%; min-height: 100%;
...@@ -23,6 +15,7 @@ html, body { ...@@ -23,6 +15,7 @@ html, body {
margin-bottom: 8px; margin-bottom: 8px;
.topic { .topic {
white-space: pre-line;
margin-bottom: 20px; margin-bottom: 20px;
font-size: 16px; font-size: 16px;
color: #222; color: #222;
...@@ -31,11 +24,10 @@ html, body { ...@@ -31,11 +24,10 @@ html, body {
li { li {
display: flex; display: flex;
align-items: center; align-items: center;
width: 375px;
height: 49px;
margin-left: -16px; margin-left: -16px;
margin-right: -16px; margin-right: -16px;
padding: 0 16px; margin-bottom: 10px;
padding: 10px 16px;
font-size: 16px; font-size: 16px;
&.selected { &.selected {
...@@ -70,6 +62,7 @@ html, body { ...@@ -70,6 +62,7 @@ html, body {
} }
span { span {
flex: 0 0 auto;
display: inline-block; display: inline-block;
width: 24px; width: 24px;
height: 24px; height: 24px;
...@@ -118,6 +111,7 @@ html, body { ...@@ -118,6 +111,7 @@ html, body {
.recommends { .recommends {
.title { .title {
margin-bottom: 10px;
color: #09f; color: #09f;
} }
...@@ -171,5 +165,67 @@ html, body { ...@@ -171,5 +165,67 @@ html, body {
border-radius: 3em; border-radius: 3em;
color: #2636FB; color: #2636FB;
} }
.activity-end {
width: 210px;
height: 40px;
background: rgba(153, 153, 153, 1);
border-radius: 4px;
font-size: 18px;
color: #fff;
}
}
.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;
background: #fff;
border-radius: 5px;
overflow: hidden;
}
.title {
height: 90px;
text-align: center;
line-height: 90px;
font-size: 18px;
color: #525C65;
}
.btns {
border-top: 1px solid #DDD;
height: 44px;
button {
width: 50%;
height: 100%;
background: transparent;
-webkit-appearance: none;
outline: 0;
border: 0;
font-size: 15px;
color: #333;
&:nth-child(1) {
border-right: 1px solid #DDD;
}
&:nth-child(2) {
color: #3F96FB;
}
}
}
} }
} }
\ No newline at end of file
const initialState = {
question: {},
recommends: [],
result: {},
}
export const ADD_RESULT = 'ADD_RESULT'
export const ADD_QUESTION = 'ADD_QUESTION'
export const ADD_RECOMMENDS = 'ADD_RECOMMENDS'
export const REDO = 'REDO'
export const addData = ({payload, type}) => {
return {
type,
payload,
}
}
export default function anniversary2020Question(state = initialState, action) {
switch (action.type) {
case ADD_RESULT:
return {
...state, ...{result: action.payload},
}
case ADD_QUESTION:
return {
...state, ...{question: action.payload},
}
case ADD_RECOMMENDS:
return {
...state, ...{recommends: action.payload},
}
case REDO:
return initialState
default:
return state
}
}
\ No newline at end of file
...@@ -4,6 +4,7 @@ import courseInfo from '@/components/detail/reducers' ...@@ -4,6 +4,7 @@ import courseInfo from '@/components/detail/reducers'
import user from './userReducer' import user from './userReducer'
import country from '@/components/country/countryRedux' import country from '@/components/country/countryRedux'
import intelligentRecommend from "@components/intelligent-recommend/store" import intelligentRecommend from "@components/intelligent-recommend/store"
import anniversary2020Question from '@components/activity/2020-717/question/store/reducer' //2020周年庆活动答题页
const reducer = combineReducers({ const reducer = combineReducers({
...@@ -11,7 +12,8 @@ const reducer = combineReducers({ ...@@ -11,7 +12,8 @@ const reducer = combineReducers({
courseInfo, courseInfo,
user, user,
country, country,
intelligentRecommend intelligentRecommend,
anniversary2020Question,
}); });
export default reducer; export default reducer;
\ No newline at end of file
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