Commit 7a2dceef by zhanghaozhe

限时免费

parent eeaf420a
No preview for this file type
This source diff could not be displayed because it is too large. You can view the blob instead.
This source diff could not be displayed because it is too large. You can view the blob instead.
No preview for this file type
No preview for this file type
No preview for this file type
.v-list-base-item {
height: 130px;
//height: 130px;
padding: 10px 10px 0;
position: relative;
......
......@@ -149,11 +149,9 @@ class Index extends Component {
}
toCourseDetail = (id) => {
const {dispatch, history} = this.props;
// dispatch(getCourses(id, () => {
const {history} = this.props;
history.push(`/detail?id=${id}`);
return false;
// }));
}
handleLimitFreeClick = () => {
......@@ -161,6 +159,7 @@ class Index extends Component {
}
render() {
//todo 联调
const {limitFree} = this.state
return (
<div className='index-box'>
......
import React, { Component } from 'react'
import { http } from "@/utils"
import './index.scss'
import { HeaderBar } from "@common/index"
import { WhiteSpace } from "antd-mobile";
import VList from '@/common/v-list-base'
class LimitFree extends Component {
state = {
tabs: new Array(5).fill('a').map((item, i) => ({
title: String.fromCharCode(97 + i)
})),
courses: [
{
img: 'https://julyedu-img-public.oss-cn-beijing.aliyuncs.com/Public/Image/20a86c1353.jpg',
title: 'NLP到Word2Vec实战班',
count: '1212',
status: 1,
price: 99,
price1: 199,
},
{
img: 'https://julyedu-img-public.oss-cn-beijing.aliyuncs.com/Public/Image/20a86c1353.jpg',
title: 'NLP到Word2Vec实战班',
count: '1212',
status: 1,
price: 99,
price1: 199,
},
{
img: 'https://julyedu-img-public.oss-cn-beijing.aliyuncs.com/Public/Image/20a86c1353.jpg',
title: 'NLP到Word2Vec实战班',
count: '1212',
status: 1,
price: 99,
price1: 199,
},
]
}
componentDidMount() {
}
handleClick = id => {
}
render() {
const {tabs, courses} = this.state
return (
<div className='limit-free'>
<HeaderBar arrow={true} title={'限时免费'}></HeaderBar>
<div className="banner">
<img src="https://julyedu-cdn.oss-cn-beijing.aliyuncs.com/time_limited_free/M/banner.png" alt=""/>
</div>
<nav>
<ul>
<li></li>
</ul>
</nav>
<WhiteSpace/>
<div className="course-list">
<ul>
<li>
<h2>
<img src="https://julyedu-cdn.oss-cn-beijing.aliyuncs.com/time_limited_free/M/category-icon.png"
alt=""/>
<span>分类1</span>
</h2>
<ul className={'courses'}>
{
courses && courses.length && courses.map((item, index) => {
let des, bottom
switch (item.status) {
case 1:
des = <div className={'learner'}>
<i className='iconfont iconRectangleCopy4'/>
<span>{item.count}人学习</span>
</div>
bottom = <div className={'bottom'}>
<span className={'red'}>限时免费</span>
<span className={'origin-price'}>¥{item.price1}</span>
<button>免费领取</button>
</div>
break
case 2:
des = <div className={'remain-time'}>
<i className={'iconfont iconiconfront-21'}/>
<span>125555分后过期</span>
</div>
break
case 3:
}
const info = (
<div className='info'>
<div className='title'>{item.title}</div>
{des}
{bottom}
</div>
)
return (
<VList img={item.img}
handleClick={this.handleClick}
info={info}
/>
)
})
}
</ul>
</li>
</ul>
</div>
<div className="no-more">
-没有更多了-
</div>
</div>
);
}
}
export default LimitFree
\ No newline at end of file
.limit-free {
background: #F9F9FB;
.banner {
img {
width: 100%;
}
}
.course-list {
border-top: 1px solid transparent;
padding: 0 12px;
background: #fff;
}
.courses li:nth-last-child(1){
margin-bottom: 0;
}
.v-list-base-item {
padding: 0;
margin-bottom: 18px;
}
h2 {
display: flex;
align-items: center;
margin: 18px 0;
img {
width: 12px;
height: 12px;
margin-right: 6px;
}
span {
font-size: 16px;
color: #333;
}
}
.iconfont {
font-size: 12px;
margin-right: 4px;
}
.info {
//position: relative;
//width: 100%;
display: flex;
flex-wrap: wrap;
align-items: flex-start;
font-size: 12px;
color: #999;
.red {
color: #FF2121;
font-size: 15px;
}
.origin-price {
color: #999;
font-size: 12px;
text-decoration: line-through;
}
button {
width: 68px;
height: 24px;
border-radius: 3px;
background: #09f;
border: none;
outline: 0;
font-size: 13px;
color: #fff;
line-height: 24px;
}
.bottom {
//position: absolute;
//left: 0;
//bottom: 0;
//width: 100%;
align-self: flex-end;
}
}
.no-more {
width: 375px;
height: 82px;
line-height: 82px;
background: #F7F9FC;
font-size: 14px;
color: #AAA;
text-align: center;
}
}
\ No newline at end of file
import React, {Component} from 'react';
import React, { Component } from 'react';
import './index.scss';
import {HeaderBar, VList} from '../../common'
import { http } from "@/utils";
import {Link} from 'react-router-dom'
import {Toast} from 'antd-mobile'
import {connect} from "react-redux"
import {getCourses} from './../detail/actions';
import { HeaderBar, VList } from '../../common'
import { http, dateCountDown } from "@/utils";
import { Link } from 'react-router-dom'
import { Toast } from 'antd-mobile'
import { connect } from "react-redux"
import Loading from '@/common/Loading'
class Purchased extends Component {
constructor(props) {
super(props)
this.state = {
data: [],
isLoading: true
}
constructor(props) {
super(props)
this.state = {
data: [],
isLoading: true
}
}
componentDidMount() {
this.getList()
}
componentDidMount() {
this.getList()
this.limitFreeCountDown()
}
// 获取订单
getList = () => {
http.get(`${API.home}/m/my/courses`,).then((res) => {
if (res.data.code === 200) {
this.setState({
data: res.data.data,
isLoading: false
})
} else {
Toast.info(res.data.msg, 2);
}
// 获取订单
getList = () => {
http.get(`${API.home}/m/my/courses`,).then((res) => {
if (res.data.code === 200) {
this.setState({
data: res.data.data,
isLoading: false
})
}
} else {
Toast.info(res.data.msg, 2);
}
})
}
toCourseDetail = (id) => {
const { dispatch, history } = this.props;
// dispatch(getCourses(id, () => {
history.push(`/detail?id=${id}`)
// }));
}
toCourseDetail = (id) => {
const {dispatch, history} = this.props;
// dispatch(getCourses(id, () => {
history.push(`/detail?id=${id}`)
// }));
}
limitFreeCountDown = timestamp => {
//todo 联调
const later = new Date(timestamp)
const earlier = Date.now()
return dateCountDown(later, earlier)
}
render() {
const {user} = this.props
const uid = user && user.data && user.data.uid
return (
<div className='purchased-box'>
<HeaderBar arrow={true} title='已购课程' cart={false} toHref='/my' />
<Loading isLoading={this.state.isLoading}>
{
this.state.data && this.state.data.length > 0 ?
<div className="purchased-body">
<div className='tip'>加群请备注您的学号:{uid}</div>
{
this.state.data.map((item, index) => {
const Info = (
<div className="info">
<p className='title' onClick={() => this.toCourseDetail(item.course_id)}>
{/* <Link to={`/detail?id=${item.course_id}`}> */}
{item.course_title}
{/* </Link> */}
</p>
<p className='contact text-overflow-2'>{item.simpledescription}</p>
render() {
const {user} = this.props
const uid = user && user.data && user.data.uid
return (
<div className='purchased-box'>
<HeaderBar arrow={true} title='已购课程' cart={false} toHref='/my'/>
<Loading isLoading={this.state.isLoading}>
{
this.state.data && this.state.data.length > 0 ?
<div className="purchased-body">
<div className='tip'>加群请备注您的学号:{uid}</div>
{
this.state.data.map((item, index) => {
const Info = (
<div className="info">
<p className='title' onClick={() => this.toCourseDetail(item.course_id)}>
{item.course_title}
</p>
<p className='contact text-overflow-2'>{item.simpledescription}</p>
{
item.is_aist &&
<div className='des'>助教微信:{item.assist_weixin}</div>
}
{
!item.is_aist && item.contact_type == 1 && item.course_qq &&
<div className='des'>QQ群:{item.course_qq}</div>
}
{
!item.is_aist && item.contact_type == 2 && item.course_qq &&
<div className='des'>班主任微信:{item.course_qq}</div>
}
</div>
)
const status = (
item.is_aist && <span className='status'>返现</span>
)
const courseExpire = (
item.course_expire && item.course_expire!='' &&
<span className='course-expire'>{item.course_expire}</span>
)
return (
<VList
key={index}
img={item.image_name}
id={item.course_id}
info={Info}
status={status}
courseExpire={courseExpire}
toDetail={this.toCourseDetail}
/>
)
})
}
</div>
: <div className="cart-tip">
<p className='cart-mess'>您还没有课程哦,快去逛逛吧~</p>
<Link to='/classify'>去逛逛</Link>
</div>
}
</Loading>
{
item.is_aist &&
<div className='des'>助教微信:{item.assist_weixin}</div>
}
{
!item.is_aist && item.contact_type == 1 && item.course_qq &&
<div className='des'>QQ群:{item.course_qq}</div>
}
{
!item.is_aist && item.contact_type == 2 && item.course_qq &&
<div className='des'>班主任微信:{item.course_qq}</div>
}
</div>
)
const status = (
// item.is_aist && <span className='status'>返现</span>
<span className='limit-free-status'>{'*'}{'*'}{'*'}分后过期</span>
)
const courseExpire = (
item.course_expire && item.course_expire != '' &&
<span className='course-expire'>{item.course_expire}</span>
)
return (
<VList
key={index}
img={item.image_name}
id={item.course_id}
info={Info}
status={status}
courseExpire={courseExpire}
toDetail={this.toCourseDetail}
/>
)
})
}
</div>
: <div className="cart-tip">
<p className='cart-mess'>您还没有课程哦,快去逛逛吧~</p>
<Link to='/classify'>去逛逛</Link>
</div>
}
</Loading>
</div>
)
}
</div>
)
}
}
export default connect(
state => ({user: state.user}),
null
state => ({user: state.user}),
null
)(Purchased)
html, body, #root {
height: 100%!important;
height: 100% !important;
}
.purchased-box {
width: 100%;
height: 100%;
//background-color: $bg_f5f5f5;
.purchased-box {
width: 100%;
height: 100%;
//background-color: $bg_f5f5f5;
.tip {
width: 100%;
height: 30px;
line-height: 30px;
font-size: 12px;
color: $color_333;
text-align: center;
background-color: $bg_FFF4CE;
margin-bottom: 10px;
}
.purchased-body {
background-color: $bg_fff;
.tip {
width: 100%;
height: 30px;
line-height: 30px;
font-size: 12px;
color: $color_333;
text-align: center;
background-color: $bg_FFF4CE;
margin-bottom: 10px;
}
.purchased-body {
background-color: $bg_fff;
}
.v-list-item {
background-color: #fff;
.content {
padding-bottom: 10px;
border-bottom: 1px solid #e7eaf1;
.cover {
flex: inherit;
width: 42.2%;
img {
width: 100%;
}
}
}
.v-list-item {
background-color: #fff;
.content {
padding-bottom: 10px;
border-bottom: 1px solid #e7eaf1;
.cover {
flex: inherit;
width: 42.2%;
.info {
width: 52.3%;
position: relative;
display: block;
img {
width: 100%;
}
}
}
.title {
font-size: 16px;
color: $color_333;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
height: 16px;
line-height: 16px;
}
.contact {
font-size: 14px;
color: $color_666;
margin-top: 14px;
}
.info {
width: 52.3%;
position: relative;
display: block;
.title {
font-size: 16px;
color: $color_333;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
height: 16px;
line-height: 16px;
}
.contact {
font-size: 14px;
color: $color_666;
margin-top: 14px;
}
.des {
position: absolute;
bottom: 5px;
color: $active;
font-size: 14px;
height: 14px;
line-height: 14px;
}
}
.des {
position: absolute;
bottom: 5px;
color: $active;
font-size: 14px;
height: 14px;
line-height: 14px;
}
}
}
.cart-tip {
color: #555;
margin-top: 140px;
text-align: center;
.iconfridge {
font-size: 21px;
}
.cart-mess {
font-size: 12px;
color: $color_666;
}
.cart-tip {
color: #555;
margin-top: 140px;
text-align: center;
a {
display: inline-block;
width: 130px;
height: 30px;
border: 1px solid $bg_active;
border-radius: 15px;
font-size: 16px;
margin-top: 30px;
color: $active;
text-align: center;
line-height: 28px;
}
.iconfridge {
font-size: 21px;
}
.status {
position: absolute;
top: 0;
right: 0;
padding: 2px 6px;
border-radius: 11px 0 0 11px;
font-size: 14px;
color: #fff;
background: linear-gradient(to bottom, #FF4000, #FD7700);
.cart-mess {
font-size: 12px;
color: $color_666;
}
.course-expire{
display: inline-block;
text-align: center;
position: absolute;
bottom: 10px;
left: 0;
width:92px;
height:20px;
line-height: 21px;
background-color: #FF3A3A;
border-radius:0 10px 10px 0;
color: #fff;
font-size: 12px;
a {
display: inline-block;
width: 130px;
height: 30px;
border: 1px solid $bg_active;
border-radius: 15px;
font-size: 16px;
margin-top: 30px;
color: $active;
text-align: center;
line-height: 28px;
}
}
.status {
position: absolute;
top: 0;
right: 0;
padding: 2px 6px;
border-radius: 11px 0 0 11px;
font-size: 14px;
color: #fff;
background: linear-gradient(to bottom, #FF4000, #FD7700);
}
.limit-free-status {
position: absolute;
right: 0;
top: 8px;
width: 112px;
height: 20px;
background: #FF0000;
border-radius: 10px 0 0 10px;
line-height: 20px;
color: #fff;
text-align: center;
font-size: 11px;
}
.course-expire {
display: inline-block;
text-align: center;
position: absolute;
bottom: 10px;
left: 0;
width: 92px;
height: 20px;
line-height: 21px;
background-color: #FF3A3A;
border-radius: 0 10px 10px 0;
color: #fff;
font-size: 12px;
}
}
\ No newline at end of file
......@@ -299,4 +299,10 @@ export default [
exact: true,
component: loadable(() => import('@/components/college/courseList'))
},
//限时免费落地页
{
path:'/free',
exact: true,
component: loadable(() => import(/*limit-free*/'@/components/limit-free'))
}
]
import jsCookie from "js-cookie";
import {
differenceInDays,
differenceInHours,
differenceInMinutes,
differenceInSeconds
} from 'date-fns'
export const getParam = (key, str) => {
const _s = str ? str : location.href;
const re = new RegExp(`(?:\\?|#|&)(${key})=([^=&#\\?]+)`, 'ig');
let found;
return (found = re.exec(_s)) ? found[2] : null;
const _s = str ? str : location.href;
const re = new RegExp(`(?:\\?|#|&)(${key})=([^=&#\\?]+)`, 'ig');
let found;
return (found = re.exec(_s)) ? found[2] : null;
}
const html = content => ({__html: htmlDecode(content)})
const html = content => ({
__html: htmlDecode(content)
})
const htmlDecode = content => {
let e = document.createElement('div');
e.innerHTML = content;
return e.childNodes.length === 0 ? "" : e.childNodes[0].nodeValue;
let e = document.createElement('div');
e.innerHTML = content;
return e.childNodes.length === 0 ? "" : e.childNodes[0].nodeValue;
}
//加载网易易盾辅助函数
function getTimestamp(msec) {
msec = !msec && msec !== 0 ? msec : 1
return parseInt((new Date()).valueOf() / msec, 10)
msec = !msec && msec !== 0 ? msec : 1
return parseInt((new Date()).valueOf() / msec, 10)
}
function loadScript(src, cb) {
var head = document.head || document.getElementsByTagName('head')[0]
var script = document.createElement('script')
var head = document.head || document.getElementsByTagName('head')[0]
var script = document.createElement('script')
cb = cb || function () {
}
cb = cb || function () {
}
script.type = 'text/javascript'
script.src = src
script.type = 'text/javascript'
script.src = src
if (!('onload' in script)) {
script.onreadystatechange = function () {
if (this.readyState !== 'complete' && this.readyState !== 'loaded') return
this.onreadystatechange = null
cb(script)
}
if (!('onload' in script)) {
script.onreadystatechange = function () {
if (this.readyState !== 'complete' && this.readyState !== 'loaded') return
this.onreadystatechange = null
cb(script)
}
}
script.onload = function () {
this.onload = null
cb(script)
}
script.onload = function () {
this.onload = null
cb(script)
}
head.appendChild(script)
head.appendChild(script)
}
function initCaptcha(cb) {
if (window.initNECaptcha) {
cb()
} else {
const url = '//cstaticdun.126.net/load.min.js' + '?t=' + getTimestamp(1 * 60 * 1000)
loadScript(url, cb)
}
if (window.initNECaptcha) {
cb()
} else {
const url = '//cstaticdun.126.net/load.min.js' + '?t=' + getTimestamp(1 * 60 * 1000)
loadScript(url, cb)
}
}
export const is_weixin = () => {
var ua = window.navigator.userAgent.toLowerCase();
if (ua.match(/MicroMessenger/i) == 'micromessenger') {
return true;
}
return false;
var ua = window.navigator.userAgent.toLowerCase();
if (ua.match(/MicroMessenger/i) == 'micromessenger') {
return true;
}
return false;
}
function validateTel(tel) {
return /^1[3-9](\d{9})$/.test(tel)
return /^1[3-9](\d{9})$/.test(tel)
}
function validateEmail(email) {
var re = /^(([^<>()\[\]\\.,;:\s@"]+(\.[^<>()\[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/;
return re.test(String(email).toLowerCase());
var re = /^(([^<>()\[\]\\.,;:\s@"]+(\.[^<>()\[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/;
return re.test(String(email).toLowerCase());
}
const browser = (function () {
const ua = navigator.userAgent
return {
isWeixin: /MicroMessenger/i.test(ua),
isAndroid: /Android/i.test(ua),
isIOS: /\(i[^;]+;( U;)? CPU.+Mac OS X/i.test(ua),
isIPad: /iPad/i.test(ua),
isAndroidApp: /Android/i.test(ua) && getParam('version'),
isIOSApp: /iPhone/i.test(ua) && getParam('version')
}
const ua = navigator.userAgent
return {
isWeixin: /MicroMessenger/i.test(ua),
isAndroid: /Android/i.test(ua),
isIOS: /\(i[^;]+;( U;)? CPU.+Mac OS X/i.test(ua),
isIPad: /iPad/i.test(ua),
isAndroidApp: /Android/i.test(ua) && getParam('version'),
isIOSApp: /iPhone/i.test(ua) && getParam('version')
}
})()
const isLogin = (function () {
return jsCookie.get('uid') && jsCookie.get('token')
return jsCookie.get('uid') && jsCookie.get('token')
})()
const dateCountDown = (later, earlier) => {
const d = differenceInDays(later, earlier)
const h = differenceInHours(later, earlier) % 24
const m = differenceInMinutes(later, earlier) % 60
const s = differenceInSeconds(later, earlier) % 60
return {
d,
h,
m,
s
}
}
export {default as http} from './http'
export {default as wxShare} from './wechat/share'
export {html, initCaptcha, validateTel, validateEmail, browser, isLogin}
export {default as SendMessageToApp} from './app'
export {
default as http
}
from './http'
export {
default as wxShare
}
from './wechat/share'
export {
html,
initCaptcha,
validateTel,
validateEmail,
browser,
isLogin,
dateCountDown
}
export {
default as SendMessageToApp
}
from './app'
\ 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