Commit f5e7c74e by xuzhenghua

list

parents 420a47da dbfb701d
src/
\ No newline at end of file
......@@ -4046,6 +4046,11 @@
}
}
},
"date-fns": {
"version": "1.30.1",
"resolved": "https://registry.npmjs.org/date-fns/-/date-fns-1.30.1.tgz",
"integrity": "sha512-hBSVCvSmWC+QypYObzwGOd9wqdDpOt+0wl0KbU+R+uuZBS1jN8VsD1ss3irQDknRj5NvxiTF6oj/nDRnN/UQNw=="
},
"date-now": {
"version": "0.1.4",
"resolved": "https://registry.npmjs.org/date-now/-/date-now-0.1.4.tgz",
......
......@@ -17,6 +17,7 @@
"bfj": "6.1.1",
"case-sensitive-paths-webpack-plugin": "2.2.0",
"css-loader": "1.0.0",
"date-fns": "^1.30.1",
"dotenv": "6.0.0",
"dotenv-expand": "4.2.0",
"eslint": "5.12.0",
......
......@@ -7,6 +7,7 @@
img {
width: 100%;
height: 119px;
min-height: 119px;
}
.course-title {
......
......@@ -4,11 +4,11 @@ import './index.scss'
const VList = (props) => {
console.log(props)
return (
<li className='v-list-item' onClick={e=>props.handleClick(props.courseInfo.course_id)}>
<li className='v-list-item' onClick={e=>props.handleClick(props.id)}>
<div className="content">
<div className="cover">
{props.status}
<img src={props.courseInfo.image_name} alt=""/>
<img src={props.img} alt=""/>
</div>
{props.info}
</div>
......
......@@ -9,7 +9,7 @@
border-bottom: 1px solid $sp_e7eaf1;
.cover {
flex: 1 0 auto;
flex: 0 0 auto;
margin-right: 16px;
position: relative;
img {
......
......@@ -134,7 +134,7 @@ class Preferential extends Component {
</div>
)
return (
<VList handleClick={this.handleClick} key={index} courseInfo={item} status={status}
<VList handleClick={this.handleClick} key={index} img={item.image_name} id={item.course_id} status={status}
info={Info}></VList>
)
})}
......
import React from 'react'
import React, { PureComponent } from 'react'
import { Course, Tag } from '../../../common'
import { api } from '@/utils'
import './free-courses.scss'
const mockData = [
{
tagText: '机器学习',
tagType: 1,
title: '16年度最火课程TOP10',
src: 'https://julyedu-img-public.oss-cn-beijing.aliyuncs.com/Public/Image/4c5ccac604.jpg',
},
{
tagText: '机器学习',
tagType: 1,
title: '16年度最火课程TOP10',
src: 'https://julyedu-img-public.oss-cn-beijing.aliyuncs.com/Public/Image/4c5ccac604.jpg',
},
{
tagText: '机器学习',
tagType: 1,
title: '16年度最火课程TOP10',
src: 'https://julyedu-img-public.oss-cn-beijing.aliyuncs.com/Public/Image/4c5ccac604.jpg',
},
{
tagText: '机器学习',
tagType: 1,
title: '16年度最火课程TOP10',
src: 'https://julyedu-img-public.oss-cn-beijing.aliyuncs.com/Public/Image/4c5ccac604.jpg',
},
{
tagText: '机器学习',
tagType: 1,
title: '16年度最火课程TOP10',
src: 'https://julyedu-img-public.oss-cn-beijing.aliyuncs.com/Public/Image/4c5ccac604.jpg',
},
{
tagText: '机器学习',
tagType: 1,
title: '16年度最火课程TOP10',
src: 'https://julyedu-img-public.oss-cn-beijing.aliyuncs.com/Public/Image/4c5ccac604.jpg',
},
{
tagText: '机器学习',
tagType: 1,
title: '16年度最火课程TOP10',
src: 'https://julyedu-img-public.oss-cn-beijing.aliyuncs.com/Public/Image/4c5ccac604.jpg',
},
{
tagText: '机器学习',
tagType: 1,
title: '16年度最火课程TOP10',
src: 'https://julyedu-img-public.oss-cn-beijing.aliyuncs.com/Public/Image/4c5ccac604.jpg',
},
{
tagText: '机器学习',
tagType: 1,
title: '16年度最火课程TOP10',
src: 'https://julyedu-img-public.oss-cn-beijing.aliyuncs.com/Public/Image/4c5ccac604.jpg',
},
{
tagText: '机器学习',
tagType: 1,
title: '16年度最火课程TOP10',
src: 'https://julyedu-img-public.oss-cn-beijing.aliyuncs.com/Public/Image/4c5ccac604.jpg',
},
{
tagText: '机器学习',
tagType: 1,
title: '16年度最火课程TOP10',
src: 'https://julyedu-img-public.oss-cn-beijing.aliyuncs.com/Public/Image/4c5ccac604.jpg',
},
{
tagText: '机器学习',
tagType: 1,
title: '16年度最火课程TOP10',
src: 'https://julyedu-img-public.oss-cn-beijing.aliyuncs.com/Public/Image/4c5ccac604.jpg',
},
]
const Bottom = (props) => (
<div className='bottom'>
<Tag className={props.className}>{props.tagText}</Tag>
<Tag className={props.className}>{props.text}</Tag>
<span>{props.audience}人观看</span>
</div>
)
class FreeCourse extends PureComponent {
state = {
courses: [],
live: [],
page: 1,
num: 10
}
componentDidMount() {
this.getFreeCourses()
.then(res => {
if (res.data.code == 200) {
this.setState({
courses: res.data.data,
})
} else {
console.log(res.data.msg)
}
})
this.getFreeLive()
.then(res => {
if (res.data.code == 200) {
this.setState({
live: res.data.data
})
}
})
}
getFreeCourses = () => {
return api.get(`/m/free_course/${this.state.page}/${this.state.num}`)
}
const FreeCourse = (props) => {
return (
<ul className='free-courses'>
{
mockData.map((item, index) => (
<Course
data={item}
top={
<Tag className={'tag-starting top'}>即将开始</Tag>
}
bottom={
<Bottom audience={232} className={'tag-category'} tagText={item.tagText}></Bottom>
}
key={index}
>
</Course>
))
}
</ul>
)
getFreeLive = () => {
return api.get(`/m/live/free_list`)
}
render() {
return (
<ul className='free-courses'>
{
this.state.courses.map((item, index) => (
<Course
data={{
src: item.logo,
title: item.video_course_name
}}
bottom={
<Bottom audience={item.lessons} className={'tag-category'} text={item.category}/>
}
key={index}
>
</Course>
))
}
{/*{
this.state.live.map((item,index) => (
<Course
data={{
src: item.live_img,
title: item.live_title
}}
top={
<Tag className={'tag-starting top'}>即将开始</Tag>
}
bottom={
<Bottom audience={item.lessons} className={'tag-category'} text={item.category}/>
}
key={item.live_id}
/>
))
}*/}
</ul>
)
}
}
export default FreeCourse
\ No newline at end of file
import { api } from '@/utils'
export const RECEIVE_MY_COURSES = 'RECEIVE_MY_COURSES'
export const receiveMyCourses = payload => ({
type: RECEIVE_MY_COURSES,
payload
})
export const getMyCourses = payload => dispatch => {
return api.get(`/m/my_course/${payload.page}/${payload.num}`)
.then(res => {
dispatch(receiveMyCourses(res.data))
})
}
const NUM_INTERVAL = 10
export const fetchCoursesListIfNeeded = payload => (dispatch, getState) => {
const {shouldFetch, currentPage, currentNum} = getState().myCourses
if(!shouldFetch){
dispatch(getMyCourses)
}
}
export const INVALIDATE_COURSEDATA = 'INVALIDATE_COURSEDATA'
export const invalidateCourseDate = () => ({
type: INVALIDATE_COURSEDATA
})
import React, { PureComponent } from "react"
import { VList } from '../../../common'
import { VList } from '@/common'
import './my-courses.scss'
import { api } from '@/utils'
const mockData = [
{
title: '三月面试求职班',
imgUrl: 'https://julyedu-img-public.oss-cn-beijing.aliyuncs.com/Public/Image/4c5ccac604.jpg',
contact: 'QQ群:449141326',
time: '03月12日',
record: '学习到第2课2分33秒'
},
{
title: '三月面试求职班',
imgUrl: 'https://julyedu-img-public.oss-cn-beijing.aliyuncs.com/Public/Image/4c5ccac604.jpg',
contact: 'QQ群:449141326',
time: '03月12日',
record: '学习到第2课2分33秒'
},
{
title: '三月面试求职班',
imgUrl: 'https://julyedu-img-public.oss-cn-beijing.aliyuncs.com/Public/Image/4c5ccac604.jpg',
contact: 'QQ群:449141326',
time: '03月12日',
record: '学习到第2课2分33秒'
},
{
title: '三月面试求职班',
imgUrl: 'https://julyedu-img-public.oss-cn-beijing.aliyuncs.com/Public/Image/4c5ccac604.jpg',
contact: 'QQ群:449141326',
time: '03月12日',
record: '学习到第2课2分33秒'
},
{
title: '三月面试求职班',
imgUrl: 'https://julyedu-img-public.oss-cn-beijing.aliyuncs.com/Public/Image/4c5ccac604.jpg',
contact: 'QQ群:449141326',
time: '03月12日',
record: '学习到第2课2分33秒'
},
]
import { isToday, format } from "date-fns"
import { connect } from "react-redux"
import { getMyCourses } from "./actions"
function getStudyTime(seconds) {
return {
hour: Math.floor(seconds / (60 * 60)),
min: Math.floor(seconds / 60) % 60,
sec: seconds % 60
}
}
function AddCourse(props) {
......@@ -50,7 +22,39 @@ function AddCourse(props) {
)
}
export default class MyCourses extends PureComponent {
function Record({record: {seconds, lesson_name}}) {
let re = /第[\s\S]+?课/,
result = ''
if (lesson_name) {
let matchResult = re.exec(lesson_name)
result += (matchResult && matchResult[0]) ? matchResult[0] : ''
}
if (seconds) {
let studyTime = getStudyTime(seconds)
let hour = studyTime.hour ? String(studyTime.hour).padStart(2, '0') + ':' : '',
min = studyTime.min ? String(studyTime.min).padStart(2, '0') + ':' : '',
sec = studyTime.sec ? String(studyTime.sec).padStart(2, '0') : ''
result += hour + min + sec
}
return (
<span className={'record'}>
{
result.length ? `学习到${result}` : null
}
</span>
)
}
class MyCourses extends PureComponent {
state = {
addVisible: false
}
handleClick = () => {
console.log(1);
}
......@@ -59,43 +63,52 @@ export default class MyCourses extends PureComponent {
}
componentDidMount() {
api.get('/m/free_course/1/10')
.then(res => {
console.log(res)
})
this.props.getMyCourses({page: 1, num: 10});
}
render() {
if (mockData.length !== 0) {
let {data} = this.props.courseData
if (data && data.length !== 0) {
return (
<>
<ul>
{
mockData.map((item, index) => {
data.map((item, index) => {
let date = new Date(item.ago * 1000)
let time = isToday(date) ? format(date, 'HH时mm分') : format(date, 'MM月DD日')
const Info = (
<div className="info">
<p className='title'>{item.title}</p>
<p className='contact'>{item.contact}</p>
<p className='title'>{item.course_title}</p>
<p className='contact'>QQ群:{item.course_qq || 449141326}</p>
<p className='des'>
<span className='time'>{item.time}</span>
<span className='record'>{item.record}</span>
<span className='time'>{time}</span>
<Record record={item}/>
</p>
</div>
)
return (
<VList handleClick={this.handleClick} {...item} key={index} info={Info}></VList>
<VList img={item.image_name}
handleClick={this.handleClick}
{...item}
key={index}
info={Info}/>
)
})
}
</ul>
<AddCourse addCourseClick={this.addCourseClick}/>
{
this.state.addVisible ?
<AddCourse addCourseClick={this.addCourseClick}/>
: null
}
</>
)
} else {
return (
<div className="empty">
<p><i className='iconfont iconfish'></i></p>
<p><i className='iconfont iconfish'/></p>
<p className='empty-prompt'>还是咸鱼一条,快去翻身~</p>
<p>
<button>去选课</button>
......@@ -105,4 +118,12 @@ export default class MyCourses extends PureComponent {
}
}
}
\ No newline at end of file
}
const mapStateToProps = state => ({
courseData: state.myCourses.courseData
})
const mapDispatchToProps = {getMyCourses}
export default connect(mapStateToProps, mapDispatchToProps)(MyCourses)
\ No newline at end of file
.info {
display: flex;
flex-wrap: wrap;
width: 55%;
.title {
font-size: 15px;
font-weight: 400;
width: 100%;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
.contact {
......@@ -13,9 +18,10 @@
}
.des {
align-self: center;
color: $color_999;
font-size: 11px;
align-self: flex-end;
line-height: 1;
.time {
margin-right: 10px;
......@@ -48,6 +54,7 @@
align-items: center;
padding-top: 140px;
background: $bg_f5f5f5;
.iconfish {
width: 20px;
height: 20px;
......@@ -59,11 +66,12 @@
font-size: $font_12;
color: $color_666;
}
button{
width:131px;
height:30px;
border:1px solid $active;
border-radius:15px;
button {
width: 131px;
height: 30px;
border: 1px solid $active;
border-radius: 15px;
background: transparent;
color: $active;
font-size: $font_16;
......
import {
RECEIVE_MY_COURSES,
INVALIDATE_COURSEDATA
} from './actions'
const initialState = {
shouldFetch: false,
courseData: {},
currentPage: 1,
currentNum: 10
}
export default function myCourses(state = initialState, action) {
switch (action.type) {
case RECEIVE_MY_COURSES:
return Object.assign(
{},
state,
{courseData: action.payload})
case INVALIDATE_COURSEDATA:
return Object.assign(
{},
state,
{shouldFetch: true})
default:
return state
}
}
\ No newline at end of file
......@@ -10,6 +10,7 @@ $tabFontSize: 15px;
.tab {
height: $tabHeight;
max-height: $tabHeight;
line-height: $tabHeight;
text-align: center;
background: #F7F9FC;
......
import { combineReducers } from 'redux';
import searchReducer from '@/components/search/store/reducer';
import myCourses from '@/components/study/myCourses/reducers'
const reducer = combineReducers({
searchReducer
searchReducer,
myCourses
});
export default reducer;
\ No newline at end of file
......@@ -6,10 +6,7 @@ export const BASE_URL = process.env.NODE_ENV === 'development' ? '/api': 'https:
const instance = axios.create({
baseURL: BASE_URL,
transformRequest: [
(data) => {
return qs.stringify(data)
}
(data) => qs.stringify(data)
]
})
......
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