Full Code of jixianu/EasyFun for AI

master 027f79c3a43d cached
68 files
77.2 KB
24.4k tokens
69 symbols
1 requests
Download .txt
Repository: jixianu/EasyFun
Branch: master
Commit: 027f79c3a43d
Files: 68
Total size: 77.2 KB

Directory structure:
gitextract_as64i4d8/

├── .babelrc
├── .gitattributes
├── .gitignore
├── README.md
├── docs/
│   └── EasyFun.xmind
├── package.json
├── src/
│   ├── common/
│   │   ├── fetch.js
│   │   └── mock.js
│   ├── components/
│   │   ├── Book/
│   │   │   ├── BookColumn.js
│   │   │   └── BookList.js
│   │   ├── ColumnHeader.js
│   │   ├── Footer.js
│   │   ├── Header.js
│   │   ├── ListLoadMore.js
│   │   ├── Loading.js
│   │   ├── Login/
│   │   │   ├── Login.js
│   │   │   ├── LoginForm.js
│   │   │   └── Register.js
│   │   ├── Movie/
│   │   │   ├── MovieAbout.js
│   │   │   ├── MovieActor.js
│   │   │   ├── MovieBanner.js
│   │   │   ├── MovieColumn.js
│   │   │   ├── MovieIntro.js
│   │   │   ├── MovieItem.js
│   │   │   ├── MovieList.js
│   │   │   └── MovieMenu.js
│   │   ├── Music/
│   │   │   ├── MusicColumn.js
│   │   │   └── MusicList.js
│   │   ├── Pages.js
│   │   ├── Spot/
│   │   │   ├── NewsList.js
│   │   │   ├── NewsListBlock.js
│   │   │   ├── SpotColumn.js
│   │   │   └── TopListBlock.js
│   │   └── TopList.js
│   ├── config/
│   │   ├── Route-Config.js
│   │   └── index.js
│   ├── containers/
│   │   ├── AppContainer.js
│   │   ├── BookContainer.js
│   │   ├── BookDetailContainer.js
│   │   ├── HomeContainer.js
│   │   ├── MovieContainer.js
│   │   ├── MovieDetailContainer.js
│   │   ├── MusicContainer.js
│   │   ├── MusicDetailContainer.js
│   │   ├── NotFoundPage.js
│   │   ├── SpotContainer.js
│   │   └── SpotDetailContainer.js
│   ├── index.html
│   ├── index.js
│   ├── style/
│   │   ├── App.less
│   │   ├── BookList.less
│   │   ├── ColumnHeader.less
│   │   ├── Home.less
│   │   ├── ListLoadMore.less
│   │   ├── Login.less
│   │   ├── MovieColumn.less
│   │   ├── MovieDetail.less
│   │   ├── MovieItem.less
│   │   ├── MovieMenu.less
│   │   ├── Music.less
│   │   ├── NewsList.less
│   │   ├── Pages.less
│   │   ├── Spot.less
│   │   ├── TopList.less
│   │   └── base.less
│   └── template/
│       └── template.html
├── webpack.dev.config.js
└── webpack.pub.config.js

================================================
FILE CONTENTS
================================================

================================================
FILE: .babelrc
================================================
{
  "presets": [
    "es2015",
    "react",
    "stage-0"
  ],
  "plugins": [["import", { "libraryName": "antd", "style": true }]]
}

================================================
FILE: .gitattributes
================================================
# Auto detect text files and perform LF normalization
* text=auto

# Custom for Visual Studio
*.cs     diff=csharp

# Standard to msysgit
*.doc	 diff=astextplain
*.DOC	 diff=astextplain
*.docx diff=astextplain
*.DOCX diff=astextplain
*.dot  diff=astextplain
*.DOT  diff=astextplain
*.pdf  diff=astextplain
*.PDF	 diff=astextplain
*.rtf	 diff=astextplain
*.RTF	 diff=astextplain


================================================
FILE: .gitignore
================================================
node_modules

.idea
dist

npm-debug.log
yarn-error.log



================================================
FILE: README.md
================================================
## 简趣
一个简单趣味的pc-react站

###技术栈
- React
- React-Router
- ES6
- Less
- Antd
- Mock.js
- Webpack
    
###运行
在目录中,运行指令

    npm install

开发版
    
    yarn run dev

发布版

    yarn run pro

###历程(各种偷懒啊)

2.24
配置webpack与包管理  
2.25
配置webpack开发热更新
4.6
使用stage-0编程,这样可以省去bind(this)
使用聚合数据API与localStorage做用户登录,接口只能接受username-aaa
4.21
完成电影详情页,首页
5.21
router的异步加载

###挖坑埋坑

1. 公共的base,其他css引用不每次都要引用
2. 豆瓣的API访问次数,30次/min
3. 异步读取数据时,返回数据之前切换router会使页面报waring,setState nothing 用给路由一个状态this.mouted
4. fetch时mock的数据需要放在服务器环境才能拦截http请求,未解决--需要配置node后台环境
5. 组件样式问题,需要在渲染组件上引入,不应在容器组件上那应用样式,会导致再次使用时还需引样式
6. fetch错误的catch怎么能统一返回一个数据组合?给一个state做判断,能不能统一返回一个DOM节点--不能
7. 组件的大小样式是px像素,而当二次使用时不可适配,应使用百分比
8. webpack打包无法处理jsx中的img标签引用,使用require()则会被编译
9. react-router@4.x.x渲染是需要按照react-router-dom,没有hashHistory方法,推荐使用browserHistory,只有react-router@3.x.x才有hashHistory

###预览
![](http://i.imgur.com/6aPjIX4.jpg)
![](http://i.imgur.com/7FQl7Q4.jpg)



================================================
FILE: package.json
================================================
{
  "name": "EasyFun",
  "version": "1.0.0",
  "description": "A project using react es6 webpack antd..",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1",
    "dev": "webpack-dev-server --config webpack.dev.config.js --devtool eval --progress --colors --hot --inline --content-base src",
    "pub": " rimraf dist/* && webpack --config webpack.pub.config.js  -p"
  },
  "author": "xiaomeng",
  "license": "MIT",
  "devDependencies": {
    "autoprefixer-loader": "^3.2.0",
    "babel-core": "^6.21.0",
    "babel-loader": "^6.2.10",
    "babel-plugin-import": "^1.1.1",
    "babel-preset-es2015": "^6.18.0",
    "babel-preset-react": "^6.16.0",
    "babel-preset-stage-0": "^6.22.0",
    "css-loader": "^0.26.1",
    "es6-promise": "^4.1.0",
    "extract-text-webpack-plugin": "^1.0.1",
    "fetch-jsonp": "^1.0.6",
    "file-loader": "^0.9.0",
    "html-webpack-plugin": "^2.28.0",
    "less": "^2.7.2",
    "less-loader": "^2.2.3",
    "mockjs": "^1.0.1-beta3",
    "open-browser-webpack-plugin": "0.0.3",
    "react-hot-loader": "^1.3.1",
    "rimraf": "^2.6.1",
    "style-loader": "^0.13.1",
    "url-loader": "^0.5.7",
    "webpack": "^1.14.0",
    "webpack-dev-server": "^1.16.2",
    "yarn": "^0.21.3"
  },
  "dependencies": {
    "antd": "^2.7.2",
    "react": "^15.4.2",
    "react-dom": "^15.4.2",
    "react-router": "^3.0.2"
  }
}


================================================
FILE: src/common/fetch.js
================================================
import fetchJsonp from 'fetch-jsonp'
import * as config from '../config'
require('es6-promise').polyfill();
// 获取电影列表
export function fetch_movie(opt) {
  if (!opt) {
    return false;
  }
  let REQUEST_PATH = `${config.SERVER_PATH}movie/${opt.type}`;
  if (opt.type !== 'us_box') {
    REQUEST_PATH += `?start=${opt.start}&count=${opt.count}`
  }
  const result = fetchJsonp(REQUEST_PATH, {
    timeout: 3000,
  });

  return result.then(response=> {
    return response.json();
  }).catch(err=>
    console.log('parsing failed', err)
  );
}

// 获取电影详情
export function fetch_movieDetail(opt) {
  if (!opt) {
    return false;
  }
  const REQUEST_PATH = `${config.SERVER_PATH}movie/subject/${opt.id}`;
  const result = fetchJsonp(REQUEST_PATH, {
    timeout: 3000,
  });

  return result.then(response=> {
    return response.json();
  }).catch(err=>
    console.log('parsing failed', err)
  );
}

// 登录注册
export function fetch_login(opt) {
  if (!opt) {
    return false;
  }
  let params = '';
  for (let [key, value] of Object.entries(opt)) {
    params += `&${key}=${value}`;
    localStorage.setItem(key, value);
  }
  params = params.substring(1);
  let LOGIN_PATH = `${config.LOGIN_PATH}?${params}`;
  return fetch(LOGIN_PATH, {method: 'GET'})
    .then(response => {
      return response.json()
    })
    .catch(err=>
      console.log('parsing failed', err)
    )
}

// 获取新闻热点
export function fetch_spot(opt) {
  return fetch(`http://newsapi.gugujiankong.com/Handler.ashx?action=getnews&type=${opt.type}&count=${opt.count}`,
    {method: 'GET'})
    .then(response=> {
      return response.json();
    })
}


================================================
FILE: src/common/mock.js
================================================
import Mock from 'mockjs'
const {Random} = Mock

export const comments = Mock.mock({
  'commentList|5': [{
    'id': '@natural',
    'time': '@datetime(16-MM-dd HH:mm:ss)',
    'name': '@cname',
    'content': '@cparagraph',
    'url': Random.image('50x50', Random.color(), '#FFF', Random.word(3, 5))
  }]
});

export const commentsMore = Mock.mock({
  'commentList|5': [{
    'id': '@natural',
    'time': '@datetime(16-MM-dd HH:mm:ss)',
    'name': '@cname',
    'content': '@cparagraph',
    'url': Random.image('50x50', Random.color(), '#FFF', Random.word(3, 5))
  }]
});

export const messages = Mock.mock({
  'messageList|5-8': [{
    'id': '@natural',
    'title': '@ctitle(5,10)',
    'name': '@name',
    'url': Random.image('40x40', Random.color(), '#FFF', Random.word(3, 5))
  }]
});

export const correlations = Mock.mock({
  'correlationList|5-8': [{
    'id': '@natural',
    'title': '@ctitle(6,10)',
    'name': '@name',
    'url': Random.image('40x40', Random.color(), '#FFF', Random.word(3, 5))
  }]
});

export const musicTop = Mock.mock({
  'musicList|10':[{
    'uniquekey' : '@natural',
    'title': '@ctitle(3,6)'
  }]
})


================================================
FILE: src/components/Book/BookColumn.js
================================================
import React, {Component} from 'react'
import BookList from './BookList'
import ColumnHeader from '../ColumnHeader'

export default  class MusicColumn extends Component {
  render() {
    return (
      <div>
        <ColumnHeader
          title='热门图书'
          isMore={true}
          id='book'
          target='/book'
        />
        <BookList />
      </div>
    )
  }
}




================================================
FILE: src/components/Book/BookList.js
================================================
import React from 'react'

const BookList = () => {
  return (
    <div>
      <ul className="list-col list-summary">
        <li>
          <div className="cover">
            <a href="javascript:;">
              <img src="https://img1.doubanio.com/spic/s29331058.jpg" alt="世界的凛冬"/>
            </a>
          </div>
          <div className="info">
            <h4 className="title">
              <a href="javascript:;">世界的凛冬</a>
            </h4>
            <p className="entry-star-small">
                <span className=" star-img">
                </span>
              <span className="average-rating">
                  9.3
                </span>
            </p>
            <p className="author">
              作者:[英] 肯·福莱特
            </p>
            <p className="book-list-classification">
              历史&nbsp;/&nbsp;肯·福莱特&nbsp;/&nbsp;英国文学
            </p>
            <p className="reviews">
              肯仿佛为读者建造了一个尽量真实的试验场,让他的人物在其中经历各种苦难历程,使人性得以多维的展现。
              (<a href="https://book.douban.com/review/8398946/?icn=index-topchart-subject">宝木笑评论</a>)
            </p>
          </div>
        </li>
        <li>
          <div className="cover">
            <a href="javascript:;">
              <img src="https://img3.doubanio.com/spic/s29276401.jpg" alt="好好学习"/>
            </a>
          </div>
          <div className="info">
            <h4 className="title">
              <a href="javascript:;">好好学习</a>
            </h4>
            <p className="entry-star-small">
                <span className=" star-img">
                </span>
              <span className="average-rating">
                  8.4
                </span>
            </p>
            <p className="author">
              作者:成甲
            </p>
            <p className="book-list-classification">
              知识管理&nbsp;/&nbsp;方法论&nbsp;/&nbsp;思维
            </p>
            <p className="extra-info">
            </p>
            <p className="reviews">
              临界知识是不存在的,临界后的智识状态却是存在的。
              (<a href="javascript:;">静修评论</a>)
            </p>
          </div>
        </li>
        <li>
          <div className="cover">
            <a href="javascript:;">
              <img src="https://img1.doubanio.com/spic/s29343377.jpg" alt="散步去"/>
            </a>
          </div>
          <div className="info">
            <h4 className="title">
              <a href="javascript:;">散步去</a>
            </h4>
            <p className="entry-star-small">
                <span className=" star-img">
                </span>
              <span className="average-rating">
                  8.9
                </span>
            </p>
            <p className="author">
              作者:[日] 谷口治郎
            </p>
            <p className="book-list-classification">
              日本&nbsp;/&nbsp;谷口治郎&nbsp;/&nbsp;漫画
            </p>
            <p className="extra-info">
            </p>
            <p className="reviews">
              某种程度上或许可以说,谷口治郎的《散步去》正是以漫画的形式为载体,传承着一种“禅”的精神。
              (<a href="javascript:;">宝木笑评论</a>)
            </p>
          </div>
        </li>
        <li>
          <div className="cover">
            <a href="javascript:;">
              <img src="https://img3.doubanio.com/spic/s29334990.jpg" alt="地理学与生活(全彩插图第11版)"/>
            </a>
          </div>
          <div className="info">
            <h4 className="title">
              <a href="javascript:;">地理学与生活</a>
            </h4>
            <p className="entry-star-small">
                <span className=" star-img">
                </span>
              <span className="average-rating">
                  9.5
                </span>
            </p>
            <p className="author">
              作者:[美] 阿瑟·格蒂斯&nbsp;/&nbsp;朱迪丝·格蒂斯&nbsp;/&nbsp;杰尔姆·D. 费尔曼
            </p>
            <p className="book-list-classification">
              地理学&nbsp;/&nbsp;科普&nbsp;/&nbsp;大学堂
            </p>
            <p className="extra-info">
            </p>
            <p className="reviews">
              尽管我们被城市的钢筋丛林所束缚,但有空时不妨翻开书卷,通过地理学,去看看那绚丽缤纷的花花世界。
              (<a href="javascript:;">墙头马上Hao评论</a>)
            </p>
          </div>
        </li>
        <li>
          <div className="cover">
            <a href="javascript:;">
              <img src="https://img3.doubanio.com/spic/s29247833.jpg" alt="被占的宅子"/>
            </a>
          </div>
          <div className="info">
            <h4 className="title">
              <a href="javascript:;">被占的宅子</a>
            </h4>
            <p className="entry-star-small">
                <span className=" star-img">
                </span>
              <span className="average-rating">
                  8.7
                </span>
            </p>
            <p className="author">
              作者:[阿根廷] 胡利奥·科塔萨尔
            </p>
            <p className="book-list-classification">
              短篇小说&nbsp;/&nbsp;胡里奥·科塔萨尔&nbsp;/&nbsp;拉美文学
            </p>
            <p className="extra-info">
            </p>
            <p className="reviews">
              故事里的人与人之间,人与物件、动物、植物之间生鲜活色的喧嚷交互,始终传递着一种浅浅淡淡却挥之不去的寂寞。
              (<a href="javascript:;">流念水评论</a>)
            </p>
          </div>
        </li>
        <li>
          <div className="cover">
            <a href="javascript:;">
              <img src="https://img1.doubanio.com/spic/s29372139.jpg" alt="百鬼夜行 阳"/>
            </a>
          </div>
          <div className="info">
            <h4 className="title">
              <a href="javascript:;">百鬼夜行 阳</a>
            </h4>
            <p className="entry-star-small">
                <span className=" star-img">
                </span>
              <span className="average-rating">
                  8.2
                </span>
            </p>
            <p className="author">
              作者:[日] 京极夏彦
            </p>
            <p className="book-list-classification">
              怪谈&nbsp;/&nbsp;日本文学&nbsp;/&nbsp;京极夏彦
            </p>
            <p className="extra-info">
            </p>
            <p className="reviews">
              人的虚妄幻想欲求逃避麻木软弱怪异愤怒堕落,如鬼魅一般穿梭,而无法走出来的人,就会陷入自己的心魔所制造的迷宫,徘徊不得出。
              (<a href="javascript:;">不确定性原理K评论</a>)
            </p>
          </div>
        </li>
        <li>
          <div className="cover">
            <a href="javascript:;">
              <img src="https://img1.doubanio.com/spic/s29362568.jpg" alt="白先勇细说红楼梦"/>
            </a>
          </div>
          <div className="info">
            <h4 className="title">
              <a href="javascript:;">白先勇细说红楼梦</a>
            </h4>
            <p className="entry-star-small">
                <span className=" star-img">
                </span>
              <span className="average-rating">
                  7.5
                </span>
            </p>
            <p className="author">
              作者:白先勇
            </p>
            <p className="book-list-classification">
              红楼梦&nbsp;/&nbsp;白先勇&nbsp;/&nbsp;经典
            </p>
            <p className="extra-info">
            </p>
            <p className="reviews">
              白先生这本偏重文学技巧的解析,把每一章节里的线索拆开来,草灰蛇线。
              (<a href="javascript:;">素手纤纤评论</a>)
            </p>
          </div>
        </li>
        <li>
          <div className="cover">
            <a href="javascript:;">
              <img src="https://img1.doubanio.com/spic/s29385647.jpg" alt="地下铁道"/>
            </a>
          </div>
          <div className="info">
            <h4 className="title">
              <a href="javascript:;">地下铁道</a>
            </h4>
            <p className="entry-star-small">
                <span className=" star-img">
                </span>
              <span className="average-rating">
                  8.1
                </span>
            </p>
            <p className="author">
              作者:[美] 科尔森·怀特黑德(Colson Whitehead)
            </p>
            <p className="book-list-classification">
              小说&nbsp;/&nbsp;美国&nbsp;/&nbsp;科尔森·怀特黑德
            </p>
            <p className="extra-info">
            </p>
            <p className="reviews">
              美国可以是一间间展示苦难的囚室,也可以是博物馆一个个展室,更可以是呼啸驰过的地铁车站的车站风景。
              (<a href="javascript:;">藤原琉璃君评论</a>)
            </p>
          </div>
        </li>
        <li>
          <div className="cover">
            <a href="javascript:;">
              <img src="https://img3.doubanio.com/spic/s29219172.jpg" alt="北京的城墙与城门"/>
            </a>
          </div>
          <div className="info">
            <h4 className="title">
              <a href="javascript:;">北京的城墙与城门</a>
            </h4>
            <p className="entry-star-small">
                <span className=" star-img">
                </span>
              <span className="average-rating">
                  9.0
                </span>
            </p>
            <p className="author">
              作者:[瑞典] 喜仁龙(Osvald Sirén)
            </p>
            <p className="book-list-classification">
              建筑&nbsp;/&nbsp;历史&nbsp;/&nbsp;北京
            </p>
            <p className="extra-info">
            </p>
            <p className="reviews">
              历史建筑是城市文化最重要的承载,失去时,更能感受到历史的厚重和沉重。
              (<a href="javascript:;">墙头马上Hao评论</a>)
            </p>
          </div>
        </li>
        <li>
          <div className="cover">
            <a href="javascript:;">
              <img src="https://img3.doubanio.com/spic/s29247833.jpg" alt="被占的宅子"/>
            </a>
          </div>
          <div className="info">
            <h4 className="title">
              <a href="javascript:;">被占的宅子</a>
            </h4>
            <p className="entry-star-small">
                <span className=" star-img">
                </span>
              <span className="average-rating">
                  8.7
                </span>
            </p>
            <p className="author">
              作者:[阿根廷] 胡利奥·科塔萨尔
            </p>
            <p className="book-list-classification">
              短篇小说&nbsp;/&nbsp;胡里奥·科塔萨尔&nbsp;/&nbsp;拉美文学
            </p>
            <p className="extra-info">
            </p>
            <p className="reviews">
              故事里的人与人之间,人与物件、动物、植物之间生鲜活色的喧嚷交互,始终传递着一种浅浅淡淡却挥之不去的寂寞。
              (<a href="javascript:;">流念水评论</a>)
            </p>
          </div>
        </li>
        <li>
          <div className="cover">
            <a href="javascript:;">
              <img src="https://img3.doubanio.com/spic/s29372251.jpg" alt="午夜起来听寂静"/>
            </a>
          </div>
          <div className="info">
            <h4 className="title">
              <a href="javascript:;">午夜起来听寂静</a>
            </h4>
            <p className="entry-star-small">
                <span className="star-img">
                </span>
              <span className="average-rating">
                  8.5
                </span>
              <span className="ml8">新上榜</span>
            </p>
            <p className="author">
              作者:周云蓬
            </p>
            <p className="book-list-classification">
              周云蓬&nbsp;/&nbsp;诗歌&nbsp;/&nbsp;人生
            </p>
            <p className="extra-info">
            </p>
            <p className="reviews">
              他用自己的方式对这个世界作出一次又一次评价,他用自己内心的温情来看待这个世界的种种方面。
              (<a href="javascript:;">遥远的星空评论</a>)
            </p>
          </div>
        </li>
        <li>
          <div className="cover">
            <a href="javascript:;">
              <img src="https://img3.doubanio.com/spic/s29276401.jpg" alt="好好学习"/>
            </a>
          </div>
          <div className="info">
            <h4 className="title">
              <a href="javascript:;">好好学习</a>
            </h4>
            <p className="entry-star-small">
                <span className=" star-img">
                </span>
              <span className="average-rating">
                  8.4
                </span>
            </p>
            <p className="author">
              作者:成甲
            </p>
            <p className="book-list-classification">
              知识管理&nbsp;/&nbsp;方法论&nbsp;/&nbsp;思维
            </p>
            <p className="extra-info">
            </p>
            <p className="reviews">
              临界知识是不存在的,临界后的智识状态却是存在的。
              (<a href="javascript:;">静修评论</a>)
            </p>
          </div>
        </li>
      </ul>
    </div>
  )
}

export default BookList


================================================
FILE: src/components/ColumnHeader.js
================================================
import React from 'react'
import {Link} from 'react-router'
import Pages from './Pages'

const ColumnHeader = ({title, id , target, total, onChange, current, isMore})=> {
  return (
    <div className='column_header'>
      <span className='column_title' id={id}>
        <Link to={target}> {title} </Link>
      </span>
      <span className='column_more'>
        {!isMore && <Pages current= {current} total={total} onChange={onChange}/>}
      </span>
    </div>
  )
}

export default ColumnHeader

================================================
FILE: src/components/Footer.js
================================================
import React from 'react'
import {Layout} from 'antd'

const {Footer} = Layout

const Foot = () => {
  return (
    <Footer className='wrap tc'>
      EasyFun ©2017 Created by xiaomeng.
      Thanks for douban's Data OAuth2.0.
    </Footer>
  )
}

export default Foot


================================================
FILE: src/components/Header.js
================================================
import React from 'react'
import {Link, IndexLink} from 'react-router'
import {Layout, Row, Col} from 'antd'
import Login from './Login/Login'

const {Header} = Layout

const Head = () => {
  return (
    <Header className='wrap'>
      <Row>
        <Col span={6}>
          <a href='/' className='logo'/>
        </Col>
        <Col span={12} offset={2}>
          <ul className='header_tab'>
            <li><IndexLink to='/' activeClassName='header_curPage'>首页</IndexLink></li>
            <li><Link to='/movie' activeClassName='header_curPage'>电影</Link></li>
            <li><Link to='/spot' activeClassName='header_curPage'>热点</Link></li>
            <li><Link to='/music' activeClassName='header_curPage'>音乐</Link></li>
            <li><Link to='/book' activeClassName='header_curPage'>书籍</Link></li>
          </ul>
        </Col>
        <Col span={4}>
          <Login />
        </Col>
      </Row>
    </Header>
  )
}

export default Head


================================================
FILE: src/components/ListLoadMore.js
================================================
import React, {Component} from 'react'
import {Button} from 'antd'

const ListLoadMore = ({isLoading, handleClick, count}) => {
  return (
    <div className='list_load'>
      {count > 0 ?
        <Button loading={isLoading} onClick={handleClick}>
          加载更多...
        </Button>
        :
        <p>没有更多了</p>
      }
    </div>
  )
}

export default ListLoadMore


================================================
FILE: src/components/Loading.js
================================================
import React, {Component} from 'react'
import {Spin} from 'antd'

const Loading = ()=> {
  return (
    <div className='loading'>
      <Spin />
    </div>
  )
}

export default Loading


================================================
FILE: src/components/Login/Login.js
================================================
import React, {Component} from 'react'
import {Modal, Icon, Button, message} from 'antd'
import LoginForm from './LoginForm'
import Register from './Register'


export default class Login extends Component {
  state = {
    action: 'login',
    visible: false,
    confirmLoading: false,
    isLogin: false
  }
  componentDidMount() {
    if (localStorage.string) {
      this.setState({
        isLogin: true
      })
    }
  }

  showModal = () => {
    this.setState({
      visible: true
    });
  }

  handleCancel = () => {
    this.setState({
      visible: false
    });
  }

  handleRegiste = () => {
    this.setState({
      action: 'register'
    });
  }

  handleRegisterDone = () => {
    this.setState({
      visible: false,
      isLogin: true
    })
  }

  handleBack = () => {
    this.setState({
      action: 'login'
    });
  }

  logout = () => {
    this.setState({
      isLogin: false,
      action: 'login'
    })
  }

  loginDone = () => {
    this.setState({
      isLogin: true,
      visible: false
    });
    message.success("登录成功!");
  }

  render() {
    return (
      <div className="login">
        <div>
          {this.state.isLogin ?
            <Button onClick={this.logout}>
              <Icon type="user"
                    className='login_icon'
              />
              {localStorage.string} 注 销
            </Button>
            :
            <Button onClick={this.showModal}>
              <Icon type="user"
                    className='login_icon'
              />
              登录
            </Button>
          }
        </div>
        <Modal title={ this.state.action === 'register' ?
          <div style={{position: 'relative'}}>
            <span
              className='modal_back'
              onClick={this.handleBack}
            >
              <Icon type="arrow-left"/>
            </span>
            注册
          </div> : '登录'
        }
               visible={this.state.visible}
               footer={null}
               onCancel={this.handleCancel}
        >
          { this.state.action === 'register' ?
            <Register handleRegisterDone={this.handleRegisterDone} action={this.state.action}/>
            :
            <LoginForm isRegiste={this.handleRegiste} loginDone={this.loginDone} action={this.state.action}/> }
        </Modal>
      </div>
    );
  }
}


================================================
FILE: src/components/Login/LoginForm.js
================================================
import React, {Component} from 'react'
import {Form, Icon, Input, Button, message} from 'antd';
const FormItem = Form.Item;

class LoginForm extends Component {

  handleSubmit = (e) => {
    e.preventDefault();
    // 获取表单的值
    this.props.form.validateFields((err, values) => {
      if (!err && values.userName === localStorage.getItem('string') && values.password === localStorage.getItem('password')) {
          this.props.loginDone();
        // API接收登录,但不会校验
        // fetch_login(Object.assign({}, {action: 'login'}, formData), this.callback);
      } else {
        message.error('登录失败!');
      }
    });
  }

  render() {
    const {getFieldDecorator} = this.props.form;
    return (
      <Form onSubmit={this.handleSubmit} className="login-form">
        <FormItem>
          {getFieldDecorator('userName', {
            rules: [{required: true, message: '请输入用户名!'}],
          })(
            <Input prefix={<Icon type="user" style={{fontSize: 13}}/>} placeholder="用户名"/>
          )}
        </FormItem>
        <FormItem>
          {getFieldDecorator('password', {
            rules: [{required: true, message: '请输入密码!'}],
          })(
            <Input prefix={<Icon type="lock" style={{fontSize: 13}}/>} type="password" placeholder="密码"/>
          )}
        </FormItem>
        <FormItem>
          <Button type="primary" htmlType="submit" className="login-form-button">
            登 录
          </Button>
          或 <a onClick={this.props.isRegiste}>现在注册!</a>
        </FormItem>
      </Form>
    );
  }
}

export default LoginForm = Form.create({})(LoginForm)


================================================
FILE: src/components/Login/Register.js
================================================
import React, {Component} from 'react'
import {Form, Input, Button, Radio, InputNumber, message} from 'antd';
import {fetch_login} from '../../common/fetch'
const FormItem = Form.Item;
const RadioGroup = Radio.Group;

class RegistrationForm extends Component {
  state = {
    confirmDirty: false,
    isSubmitting: false
  };
  // 表单提交动作
  handleSubmit = (e) => {
    e.preventDefault();
    this.setState({
      isSubmitting: true
    });
    // 但校验完后,如果校验不通过的菜单域不在可见范围内,则自动滚动进可见范围
    this.props.form.validateFieldsAndScroll((err, values) => {
      if (!err) {
        fetch_login(Object.assign({}, {action: this.props.action}, values))
          .then(() => this.callback());
      }
    });
  }

  callback = () => {
    setTimeout(()=> {
      message.success("注册成功!");
      this.setState({
        isSubmitting: false
      });
      this.props.handleRegisterDone();
    }, 1500);
  }

  handleConfirmBlur = (e) => {
    const value = e.target.value;
    this.setState({confirmDirty: this.state.confirmDirty || !!value});
  }

  checkPassword = (rule, value, callback) => {
    const form = this.props.form;
    if (value && value !== form.getFieldValue('password')) {
      callback('两次密码输入不一致!');
    } else {
      callback();
    }
  }

  checkConfirm = (rule, value, callback) => {
    const form = this.props.form;
    if (value && this.state.confirmDirty) {
      form.validateFields(['confirm'], {force: true});
    }
    callback();
  }

  render() {
    // 用于和表单进行双向绑定
    const {getFieldDecorator} = this.props.form;
    const formItemLayout = {
      labelCol: {
        xs: {span: 24},
        sm: {span: 6},
      },
      wrapperCol: {
        xs: {span: 24},
        sm: {span: 14},
      },
    };
    const tailFormItemLayout = {
      wrapperCol: {
        xs: {
          span: 24,
          offset: 0,
        },
        sm: {
          span: 14,
          offset: 6,
        },
      },
    };
    return (
      <Form onSubmit={this.handleSubmit}>
        <FormItem
          {...formItemLayout}
          label="用户名"
          hasFeedback
        >
          {getFieldDecorator('string', {
            rules: [{
              type: 'string', message: '请输入正确的用户名!',
            }, {
              required: true, message: '请输入你的用户名!',
            }],
          })(
            <Input />
          )}
        </FormItem>
        <FormItem
          {...formItemLayout}
          label="密码"
          hasFeedback
        >
          {getFieldDecorator('password', {
            rules: [{
              required: true, message: '请输入密码!',
            }, {
              validator: this.checkConfirm,
            }],
          })(
            <Input type="password"/>
          )}
        </FormItem>
        <FormItem
          {...formItemLayout}
          label="确认密码"
          hasFeedback
        >
          {getFieldDecorator('confirm', {
            rules: [{
              required: true, message: '请再次确认密码!',
            }, {
              validator: this.checkPassword,
            }]
          })(
            <Input type="password" onBlur={this.handleConfirmBlur}/>
          )}
        </FormItem>
        <FormItem
          {...formItemLayout}
          label="性别"
        >
          {getFieldDecorator('sex', {
            initialValue: 1
          })(
            <RadioGroup>
              <Radio value={1}>男</Radio>
              <Radio value={2}>女</Radio>
              <Radio value={3}>保密</Radio>
            </RadioGroup>
          )}
        </FormItem>
        <FormItem
          {...formItemLayout}
          label="年龄"
        >
          {getFieldDecorator('age', {
            initialValue: 18
          })(
            <InputNumber min={1} max={999}/>
          )}
        </FormItem>
        <FormItem
          {...tailFormItemLayout}
        >
          <Button type="primary"
                  htmlType="submit"
                  size="large"
                  className='login-form-button'
                  loading={this.state.isSubmitting}>提 交
          </Button>
        </FormItem>
      </Form>
    );
  }
}

export default RegistrationForm = Form.create({})(RegistrationForm)


================================================
FILE: src/components/Movie/MovieAbout.js
================================================
import React from 'react'
import {Card, Row, Col} from 'antd'
import {messages, correlations} from '../../common/mock'

const MovieAbout = () => {

  const messageList = messages.messageList.map(item=> (
    <div key={item.id}>
      <Row>
        <Col span={6}>
          <img src={item.url}/>
        </Col>
        <Col span={17} offset={1}>
          <p>{item.title}</p>
          <p>{item.name}</p>
        </Col>
      </Row>
    </div>
  ));

  const correlationList = correlations.correlationList.map(item=> (
    <div key={item.id}>
      <Row>
        <Col span={6}>
          <img src={item.url}/>
        </Col>
        <Col span={16} offset={2}>
          <p>{item.title}</p>
          <p>{item.name}</p>
        </Col>
      </Row>
    </div>
  ));

  return (
    <Col span={5} offset={1} className='movie_about'>
      <Card title="相关电影" style={{marginBottom: 20}}>
        {correlationList}
      </Card>
      <Card title="电影资讯">
        {messageList}
      </Card>
    </Col>
  )
}

export default MovieAbout


================================================
FILE: src/components/Movie/MovieActor.js
================================================
import React from 'react'
import {Card, Icon} from 'antd'
import Loading from '../Loading'

const MovieActors = ({directors, casts, isLoading}) => {
  let actorList;
  if (!isLoading) {
    actorList = casts.map((item, index)=>(
        <li key={item.id}>
          {index == 0 ? <p>主演</p> : <p></p>}
          <a href={item.alt}>
            <img src={item.avatars.large}/>
          </a>
          <p>{item.name}</p>
        </li>
      )
    );
  }
  return (
    <Card title="演职人员" extra={<a href="javascript:;">更多<Icon type='right'/></a>}>
      {isLoading ?
        <Loading />
        :
        <ul className='actor'>
          <li>
            <p>导演</p>
            <a href={directors[0].alt}>
              <img src={directors[0].avatars.large}/>
            </a>
            <p>{directors[0].name}</p>
          </li>
          {actorList}
        </ul>
      }
    </Card>
  )
}

export default MovieActors


================================================
FILE: src/components/Movie/MovieBanner.js
================================================
import React, {Component} from 'react'
import {Rate} from 'antd'
import Loading from '../Loading'

const MovieBanner = ({isLoading, data}) => {
  if (isLoading) {
    return (
      <Loading />
    )
  }

  const directorList = data.directors.map((item, index) => {
    if (index === data.directors.length - 1) {
      return item.name;
    } else {
      return item.name + '、';
    }
  });

  const actorList = data.casts.map((item, index) => {
    if (index === data.casts.length - 1) {
      return item.name;
    } else {
      return item.name + '、';
    }
  });

  return (
    <div className='movie_banner'>
      <div className='movie_introduce'>
        <div className='movie_poster'>
          <img src={data.images.large}/>
        </div>
        <div className='movie_info'>
          <h1>{data.title}</h1>
          <h4>原名: {data.original_title}</h4>
          <p>导演: {directorList}</p>
          <p>主演:{actorList}</p>
          <p>国家:{data.countries.join('、')}</p>
          <p>系列:{data.genres.join('、')}</p>
          <p>年代:{data.year}</p>
          <p>短评数:{data.comments_count}</p>
          <p>评分人数:{data.ratings_count}</p>
        </div>
        <div className='movie_content'>
          <div className='movie_gate'>
            {data.rating.average.toFixed(1)}
          </div>
          <Rate allowHalf defaultValue={data.rating.stars / 10} disabled/>
        </div>
      </div>
    </div>
  )
}

export default MovieBanner


================================================
FILE: src/components/Movie/MovieColumn.js
================================================
import React, {Component} from 'react'
import ColumnHeader from '../ColumnHeader'
import MovieList from './MovieList'
import Loading from '../Loading'
import Pages from '../Pages'
import {fetch_movie} from '../../common/fetch'
import * as config from '../../config'

export default class MovieColumn extends Component {
  state = {
    isLoading: false,
    MoviesData: null,
    current: 1
  }

  componentDidMount() {
    this.setState({
      isLoading: true
    });

    fetch_movie({
      start: config.DEFAULT_START,
      count: this.props.count || 4,
      type: this.props.type
    }).then(data=> {
      this.resolve(data);
    }).catch(err=> {
      console.log('parsing failed', err);
    })
  }

  componentWillUnmount() {
    // 这里使用组件属性
    this.unmount = true;
  }

  resolve = data => {
    if (data && !this.unmount) {
      this.setState({
        MoviesData: data.subjects,
        isLoading: false
      })
    }
  }

  pageChange = page => {
    this.setState({
      current: page
    })
    fetch_movie({
      start: (page - 1) * config.DEFAULT_COUNT,
      count: this.props.count || 4,
      type: this.props.type
    }).then(data=> {
      this.resolve(data)
    }).catch(err=> {
      console.log('parsing failed', err);
    })
  }

  render() {
    const {type, isMore, total, title, id} = this.props;
    const {MoviesData, isLoading, current} = this.state;
    return (
      <div>
        <ColumnHeader
          title={title}
          id={id}
          isMore={isMore}
          target='/movie'
          total={total}
          onChange={this.pageChange}
          current={current}
        />
        { isLoading ? <Loading /> :
          <div className='movie_column'>
            <MovieList
              type={type}
              MoviesData={MoviesData}
              current={current}
            />
          </div>
        }
      </div>
    )
  }
}

================================================
FILE: src/components/Movie/MovieIntro.js
================================================
import React, {Component} from 'react'
import {Card, Col} from 'antd'
import {comments, commentsMore} from '../../common/mock'
import MovieActor from './MovieActor'
import ListLoadMore from '../ListLoadMore'
import Loading from '../Loading'

export default class MovieIntro extends Component {
  state = {
    commentList: comments.commentList,
    count: 1,
    iconLoading: false
  }
  handleClick = ()=> {
    this.setState({
      iconLoading: true
    });
    setTimeout(()=> {
      this.setState({
        count: this.state.count > 0 ? this.state.count - 1 : 0,
        iconLoading: false,
        commentList: [...this.state.commentList, ...commentsMore.commentList]
      });
    }, 1000);
  }

  render() {
    let commentList = this.state.commentList.map((item)=>(
        <div className='movie_comment' key={item.id}>
          <div className='movie_commentator'>
            <img src={item.url}/>
            <span>{item.name}</span>
            <span className='movie_commentdate'>{item.time}</span>
          </div>
          <p>{item.content}</p>
        </div>
      )
    );
    return (
      <Col span={18}>
        <Card title="影片简介" className='movie_intro'>
          {this.props.isLoading ? <Loading /> : this.props.data.summary}
        </Card>
        <MovieActor
          directors={this.props.isLoading ? null : this.props.data.directors}
          casts={this.props.isLoading ? null : this.props.data.casts}
          isLoading={this.props.isLoading}
        />
        <Card title="评论">
          {commentList}
          <ListLoadMore
            isLoading={this.state.iconLoading}
            handleClick={this.handleClick}
            count={this.state.count}
          />
        </Card>
      </Col>
    )
  }
}


================================================
FILE: src/components/Movie/MovieItem.js
================================================
import React, {Component} from 'react'
import {Link} from 'react-router'
import {Col} from 'antd'
import * as config from '../../config'

const MovieItem = ({imgUrl, title, rating, genre, id}) => {
  // 返回JSX结构
  return (
    <Col span={24 / config.DEFAULT_COUNT} className='movie_item'>
      <div>
        <div className='movie_img'>
          <Link to={'movie/' + id}>
            <img src={imgUrl}/>
          </Link>
        </div>
        <div className='movie_info'>
          <div className='movie_title'><Link to={'movie/' + id}>{title}</Link></div>
          {rating == '0' ?
            <div className='movie_genre'>{genre}</div>
            :
            <div className='movie_score'>{rating}</div>
          }
        </div>
      </div>
    </Col>
  );
}

export default MovieItem


================================================
FILE: src/components/Movie/MovieList.js
================================================
import React, {Component, PropTypes} from 'react'
import MovieItem from './MovieItem'
import {Row} from 'antd'

export default class MovieList extends Component {
  render() {
    let itemList = null;
    const {MoviesData, type, current} = this.props;
    // 判断是否有数据
    if (MoviesData) {
      // 北美榜数据格式不同,进行判断
      if (type === 'us_box') {
        itemList = MoviesData.map(item => (
          <MovieItem
            key={item.subject.id}
            id={item.subject.id}
            imgUrl={item.subject.images.large}
            title={item.subject.title}
            rating={item.subject.rating.average}
          />
        ));
        let endlength = current * 4 < itemList.length ? current * 4 : itemList.length;
        itemList = itemList.slice((current - 1) * 4, endlength);
      } else {
        itemList = MoviesData.map(item => (
          <MovieItem
            key={item.id}
            id={item.id}
            imgUrl={item.images.large}
            title={item.title}
            rating={item.rating.average}
            genre={item.genres[0]}
          />
        ));
      }
    }

    return (
      // Item间距
      <Row gutter={16}>
        {itemList}
      </Row>
    );
  }
}


================================================
FILE: src/components/Movie/MovieMenu.js
================================================
import React from 'react'
import {Anchor} from 'antd'

const {Link} = Anchor

const MovieMenu = () => {
  return (
    <Anchor className='movie_menu'>
      <Link href="#hotShowing" title="正在热映"/>
      <Link href="#comingSoon" title="即将上映"/>
      <Link href="#Top25" title="Top25"/>
      <Link href="#usBox" title="北美票房榜"/>
    </Anchor>
  );
}

export default MovieMenu

================================================
FILE: src/components/Music/MusicColumn.js
================================================
import React, {Component} from 'react'
import {Row, Col} from 'antd'
import MusicList from './MusicList'
import TopList from '../TopList'
import {musicTop} from '../../common/mock'
import ColumnHeader from '../ColumnHeader'

export default  class MusicColumn extends Component {
  render() {
    return (
      <div>
        <ColumnHeader
          title='流行音乐'
          isMore={true}
          id='mosic'
          target='/music'
        />
        <Row>
          <Col span={17}>
            <MusicList />
          </Col>
          <Col span={7} className="topList">
            <TopList data={musicTop.musicList} title='新歌榜'/>
          </Col>
        </Row>
      </div>
    )
  }
}

================================================
FILE: src/components/Music/MusicList.js
================================================
import React, {Component} from 'react'

const MusicList = ()=> {
  return (
    <ul className="m-cvrlst">
      <li>
        <div className="u-cover">
          <img src="http://p1.music.126.net/FnJPqo6IjQPLdPBmAlDRVA==/18823639069381202.jpg?param=140y140"/>
          <a title="〖民谣〗一个字的心情" href="javascript:;" className="msk"/>
          <div className="bottom">
            <a className="icon-play" title="播放" href="javascript:;"/>
            <span className="icon-headset"/>
            <span className="nb">45万</span>
          </div>
        </div>
        <p className="dec">
          <a title="〖民谣〗一个字的心情" className="tit s-fc0" href="javascript:;">
            〖民谣〗一个字的心情
          </a>
        </p>
      </li>
      <li>
        <div className="u-cover">
          <img src="http://p1.music.126.net/sMghA527zlusVXO6WKQJXg==/18777459581036895.jpg?param=140y140"/>
          <a title="Trip-Hop | 致迷致幻 神游天外 ✈︎" href="javascript:;" className="msk"/>
          <div className="bottom">
            <a className="icon-play" title="播放" href="javascript:;"/>
            <span className="icon-headset"/>
            <span className="nb">21万</span>
          </div>
        </div>
        <p className="dec">
          <a title="Trip-Hop | 致迷致幻 神游天外 ✈︎" className="tit s-fc0" href="javascript:;">
            Trip-Hop | 致迷致幻 神游天外 ✈︎
          </a>
        </p>
      </li>
      <li>
        <div className="u-cover">
          <img src="http://p1.music.126.net/ffjwjBt6vyWRUtSeKqpvDQ==/18552059697196685.jpg?param=140y140"/>
          <a title="2016年度欧美单曲播放排行榜" href="javascript:;" className="msk"/>
          <div className="bottom">
            <a className="icon-play" title="播放" href="javascript:;" />
            <span className="icon-headset"/>
            <span className="nb">279万</span>
          </div>
        </div>
        <p className="dec">
          <a title="2016年度欧美单曲播放排行榜" className="tit s-fc0" href="javascript:;">
            2016年度欧美单曲播放排行榜
          </a>
        </p>
      </li>
      <li>
        <div className="u-cover">
          <img src="http://p1.music.126.net/N0IrEA6V1RrS_W0brRn8OQ==/19182079858269301.jpg?param=140y140"/>
          <a title="【星缘星语】No.162-以人民的名义选择望远镜" href="javascript:;" className="msk"/>
          <div className="bottom">
            <a className="icon-play" title="播放" href="javascript:;" />
            <span className="icon-headset"/>
            <span className="nb">1380</span>
          </div>
        </div>
        <p className="dec">
          <a title="【星缘星语】No.162-以人民的名义选择望远镜" className="tit s-fc0" href="javascript:;">
            <i className="u-icn u-icn-53"/>
            【星缘星语】No.162-以人民的名义选择望远镜
          </a>
        </p>
      </li>
      <li>
        <div className="u-cover">
          <img src="http://p1.music.126.net/WVJ-w_orhIBawXWj8DwZDw==/2945591651012211.jpg?param=140y140"/>
          <i className="u-jp u-icn2 u-icn2-jp3"/>
          <a title="浓情欧洲,清新小语种" href="javascript:;" className="msk"/>
          <div className="bottom">
            <a className="icon-play" title="播放" href="javascript:;"/>
            <span className="icon-headset"/>
            <span className="nb">110万</span>
          </div>
        </div>
        <p className="dec">
          <a title="浓情欧洲,清新小语种" className="tit s-fc0" href="javascript:;">
            浓情欧洲,清新小语种
          </a>
        </p>
      </li>
      <li>
        <div className="u-cover">
          <img src="http://p1.music.126.net/cXpnOBoApRI_wmjIHN2L2g==/19008357021081982.jpg?param=140y140"/>
          <a title="那些以玩笑说出口的话,往往是最真的表达" href="javascript:;" className="msk"/>
          <div className="bottom">
            <a className="icon-play" title="播放" href="javascript:;"/>
            <span className="icon-headset"/>
            <span className="nb">6668</span>
          </div>
        </div>
        <p className="dec">
          <a title="那些以玩笑说出口的话,往往是最真的表达" className="tit s-fc0" href="javascript:;">
            <i className="u-icn u-icn-53"/>
            那些以玩笑说出口的话,往往是最真的表达
          </a>
        </p>
      </li>
      <li>
        <div className="u-cover">
          <img src="http://p1.music.126.net/HuZsFzvhKIlxLoV4MuLvrw==/109951162892180012.jpg?param=140y140"/>
          <a title="那些惊艳嗨翻天的华语现场(LIVE)" href="javascript:;" className="msk"/>
          <div className="bottom">
            <a className="icon-play" title="播放" href="javascript:;"/>
            <span className="icon-headset"/>
            <span className="nb">350万</span>
          </div>
        </div>
        <p className="dec">
          <a title="那些惊艳嗨翻天的华语现场(LIVE)" className="tit s-fc0" href="javascript:;">
            那些惊艳嗨翻天的华语现场(LIVE)
          </a>
        </p>
      </li>
      <li>
        <div className="u-cover">
          <img src="http://p1.music.126.net/xQT5ZDdXydxSHmisgzJsVQ==/19241453486166701.jpg?param=140y140"/>
          <a title="(翻)旅行的意义-2011录音" href="javascript:;" className="msk" />
          <div className="bottom">
            <a className="icon-play" title="播放" href="javascript:;"/>
            <span className="icon-headset"/>
            <span className="nb">55万</span>
          </div>
        </div>
        <p className="dec">
          <a title="(翻)旅行的意义-2011录音" className="tit s-fc0" href="javascript:;">
            <i className="u-icn u-icn-53"/>
            (翻)旅行的意义-2011录音
          </a>
        </p>
      </li>
    </ul>
  );
}

export default MusicList

================================================
FILE: src/components/Pages.js
================================================
import React, { Component } from 'react'
import { Pagination } from 'antd'

const Pages = ({current, total, onChange, defaultPageSize, id}) => {
  return (
    <div className="Pages" id= {id}>
      <Pagination
        current= {current}
        total={total}
        defaultPageSize={defaultPageSize || 4}
        onChange={onChange}
        simple
      />
    </div>
  )
}

export default Pages


================================================
FILE: src/components/Spot/NewsList.js
================================================
import React from 'react';
import {Link} from 'react-router'

const NewsList = ({newsData}) => {
  if (!newsData) {
    return <h3>没有数据</h3>;
  }
  const newsList = newsData.map((newsItem, index) => (
    <li key={newsItem.uniquekey}>
      <Link to={`spot/${newsItem.uniquekey}`}>
        <img src={newsItem.thumbnail_pic_s} alt={newsItem.title}/>
        {newsItem.title}
      </Link>
    </li>
  ));
  return (
    <div className='newsList'>
      <ul>
        {newsList}
      </ul>
    </div>
  );
}

export default NewsList

================================================
FILE: src/components/Spot/NewsListBlock.js
================================================
import React, {Component} from 'react'
import {fetch_spot} from '../../common/fetch'
import NewsList from './NewsList'
import Loading from '../Loading'

export default class NewsListBlock extends Component {
  state = {
    newsData: null,
    isLoading: false
  }

  componentDidMount() {
    this.setState({
      isLoading: true
    });
    fetch_spot({
      type: this.props.type,
      count: this.props.count
    })
      .then(
        data=> {
          this.setState({
            newsData: data,
            isLoading: false
          })
        }
      )
      .catch(err=>console.log('parsing failed', err))
  }

  render() {
    const {isLoading} = this.state;

    return (
      <div>
        {isLoading ? <Loading /> : <NewsList newsData={this.state.newsData}/>}
      </div>
    )
  }
}

================================================
FILE: src/components/Spot/SpotColumn.js
================================================
import React, {Component} from 'react'
import {Row, Col, Carousel, Tabs} from 'antd'
import NewsListBlock from './NewsListBlock'
import TopListBlock from './TopListBlock'
import ColumnHeader from '../ColumnHeader'

const {TabPane} = Tabs

const SpotColumn = ()=> {
  return (
    <div className='spot_news'>
      <ColumnHeader
        title='热点新闻'
        isMore={true}
        id='spot'
        target='/spot'
      />
      <Row gutter={10}>
        <Col span={8}>
          <Carousel autoplay className='carousel'>
            <div><img src={require("../../image/news_carousel_1.jpg")} alt='平壤居民罕见用韩国品牌相机拍照'/></div>
            <div><img src={require("../../image/news_carousel_2.jpg")} alt='土耳其公投成功海外公民有喜有悲'/></div>
            <div><img src={require("../../image/news_carousel_3.jpg")} alt='镜头记录雄安新区街头即景'/></div>
            <div><img src={require("../../image/news_carousel_4.jpg")} alt='长沙现微型古籍疑是科举作弊用书'/></div>
          </Carousel>
        </Col>
        <Col span={10}>
          <Tabs defaultActiveKey="1">
            <TabPane tab="国内" key="1">
              <NewsListBlock
                type='guonei'
                count={5}
              />
            </TabPane>
            <TabPane tab="国际" key="2">
              <NewsListBlock
                type='guoji'
                count={5}
              />
            </TabPane>
            <TabPane tab="娱乐" key="3">
              <NewsListBlock
                type='yule'
                count={5}
              />
            </TabPane>
            <TabPane tab="体育" key="4">
              <NewsListBlock
                type='tiyu'
                count={5}
              />
            </TabPane>
            <TabPane tab="军事" key="5">
              <NewsListBlock
                type='junshi'
                count={5}
              />
            </TabPane>
            <TabPane tab="社会" key="6">
              <NewsListBlock
                type='shehui'
                count={5}
              />
            </TabPane>
          </Tabs>
        </Col>
        <Col span={6}>
          <TopListBlock />
        </Col>
      </Row>
    </div>
  );
}

export default SpotColumn


================================================
FILE: src/components/Spot/TopListBlock.js
================================================
import React, {Component} from 'react';
import {Link} from 'react-router'
import TopList from '../TopList'
import Loading from '../Loading'
import {fetch_spot} from '../../common/fetch'

export default class TopListBlock extends Component {
  state = {
    newsData: null,
    isLoading: false
  }

  componentDidMount() {
    this.setState({
      isLoading: true
    });
    fetch_spot({
      type: 'top',
      count: 10
    })
      .then(
        data=> {
          this.setState({
            newsData: data,
            isLoading: false
          })
        }
      )
      .catch(err=>console.log('parsing failed', err))
  }

  render() {
    const {isLoading} = this.state;
    return (
      <div className="topList">
        {isLoading ? <Loading /> : <TopList data={this.state.newsData} title='热点头条' link='spot'/>}
      </div>
    )
  }
}


================================================
FILE: src/components/TopList.js
================================================
import React from 'react';
import {Link} from 'react-router'

const TopList = ({data, title, link}) => {
  if (!data) {
    return <h3>没有数据</h3>;
  }
  const topList = data.map((item, index) => (
    <li key={item.uniquekey}>
      <Link to={`${link}/${item.uniquekey}`}>
        <span>{index+1}</span>
        {item.title}
      </Link>
    </li>
  ));
  return (
    <ul>
      <li><h3>{title}</h3></li>
      {topList}
    </ul>);
}

export default TopList

================================================
FILE: src/config/Route-Config.js
================================================
import React from 'react'
import {Router, Route,  IndexRoute, Redirect, hashHistory} from 'react-router'
import AppContainer from '../containers/AppContainer'
import HomeContainer from '../containers/HomeContainer'

const BookContainer = (location, cb) => {
  require.ensure([], require => {
    cb(null, require('../containers/BookContainer').default)
  },'BookContainer')
}

const BookDetailContainer = (location, cb) => {
  require.ensure([], require => {
    cb(null, require('../containers/BookDetailContainer').default)
  },'BookDetailContainer')
}

const MovieContainer = (location, cb) => {
  require.ensure([], require => {
    cb(null, require('../containers/MovieContainer').default)
  },'MovieContainer')
}

const MovieDetailContainer = (location, cb) => {
  require.ensure([], require => {
    cb(null, require('../containers/MovieDetailContainer').default)
  },'MovieDetailContainer')
}

const MusicContainer = (location, cb) => {
  require.ensure([], require => {
    cb(null, require('../containers/MusicContainer').default)
  },'MusicContainer')
}

const MusicDetailContainer = (location, cb) => {
  require.ensure([], require => {
    cb(null, require('../containers/MusicDetailContainer').default)
  },'MusicDetailContainer')
}

const SpotContainer = (location, cb) => {
  require.ensure([], require => {
    cb(null, require('../containers/SpotContainer').default)
  },'SpotContainer')
}

const SpotDetailContainer = (location, cb) => {
  require.ensure([], require => {
    cb(null, require('../containers/SpotDetailContainer').default)
  },'SpotDetailContainer')
}

const NotFoundPage = (location, cb) => {
  require.ensure([], require => {
    cb(null, require('../containers/NotFoundPage').default)
  },'NotFoundPage')
}

/*const HomeContainer = (location, cb) => {
  require.ensure([], require => {
    cb(null, require('../containers/HomeContainer').default)
  },'HomeContainer')
}*/

const RootRoter = (
  <Router history={ hashHistory }>
    <Route path="/" component={ AppContainer }>
      <IndexRoute  component={ HomeContainer }/>
      <Route path="index"  component={ HomeContainer }/>
      <Route path="movie" getComponent={MovieContainer} />
      <Route path="movie/:id" getComponent={ MovieDetailContainer }/>
      <Route path="book" getComponent={ BookContainer }/>
      <Route path="book/:id" getComponent={ BookDetailContainer }/>
      <Route path="spot" getComponent={ SpotContainer }/>
      <Route path="spot/:id" getComponent={ SpotDetailContainer }/>
      <Route path="music" getComponent={ MusicContainer  }
             onLeave={ ()=>console.log('离开了music页面')  }
             onEnter={ ()=>console.log('进入了music页面') }/>
      <Route path="music/:id" getComponent={ MusicDetailContainer }/>
    </Route>
    <Route path="404" getComponent={ NotFoundPage }/>
    <Redirect from='*' to='404'/>
  </Router>
)
export default RootRoter



================================================
FILE: src/config/index.js
================================================
 export const SERVER_PATH = 'https://api.douban.com/v2/';
 export const LOGIN_PATH = 'http://newsapi.gugujiankong.com/Handler.ashx';
 export const DEFAULT_COUNT = 4;
 export const DEFAULT_START = 0;


================================================
FILE: src/containers/AppContainer.js
================================================
import React, {Component} from 'react'
import Header from '../components/Header'
import Footer from '../components/Footer'

export default class AppContainer extends Component {
  render() {
    return (
      <div>
        <Header />
        <div className='wrap center'>
          {this.props.children}
        </div>
        <Footer />
      </div>
    )
  }
}


================================================
FILE: src/containers/BookContainer.js
================================================
import React, { Component } from 'react'

export default class BookContainer extends Component {
  constructor(props){
    super(props);
    this.state = {};
  }

  componentDidMount() {
  }

  render() {
    return (
      <div>
         敬请期待...
      </div>
    )
  }
}


================================================
FILE: src/containers/BookDetailContainer.js
================================================
import React, { Component } from 'react'

export default class BookDetailContainer extends Component {
  constructor(props){
    super(props);
    this.state = {};
  }

  componentDidMount() {
  }

  render() {
    return (
      <div>
         BookDE
      </div>
    )
  }
}


================================================
FILE: src/containers/HomeContainer.js
================================================
import React, {Component} from 'react'
import {Carousel, Card, BackTop, Icon} from 'antd'
import MovieColumn from '../components/Movie/MovieColumn'
import SpotColumn from '../components/Spot/SpotColumn'
import MusicColumn from '../components/Music/MusicColumn'
import BookColumn from '../components/Book/BookColumn'

export default class HomeContainer extends Component {
  render() {
    return (
      <Card className='home'>
        <div className='carousel'>
          <Carousel autoplay>
            <div><img src={require("../image/movie_carousel_1.jpg")}/></div>
            <div><img src={require("../image/movie_carousel_2.jpg")}/></div>
            <div><img src={require("../image/movie_carousel_3.jpg")}/></div>
            <div><img src={require("../image/movie_carousel_4.jpg")}/></div>
          </Carousel>
        </div>
        <MovieColumn
          id='hotShowing'
          title='热门电影'
          type='in_theaters'
          total={8}
          noHead={true}
          count={5}
        />
        <SpotColumn/>
        <MusicColumn />
        <BookColumn />
        <BackTop>
          <div className="ant-back-top-inner">
            <Icon type="arrow-up"/>
          </div>
        </BackTop>
      </Card>
    )
  }
}


================================================
FILE: src/containers/MovieContainer.js
================================================
import React, { Component } from 'react'
import {Layout} from 'antd'
import MovieMenu from '../components/Movie/MovieMenu'
import MovieColumn from '../components/Movie/MovieColumn'

const {Content, Sider} = Layout

export default class MovieContainer extends Component {
  render() {
    return (
      <div>
        <Layout>
          <Sider>
            <MovieMenu />
          </Sider>
          <Content>
            <MovieColumn
              id='hotShowing'
              title='正在热映'
              type='in_theaters'
              total={30}
            />
            <MovieColumn
              id='comingSoon'
              title='即将上映'
              type='coming_soon'
              total={30}
            />
            <MovieColumn
              id='Top25'
              title='Top25'
              type='top250'
              total={25}
            />
            <MovieColumn
              id='usBox'
              title='北美票房榜'
              type='us_box'
              total={11}
            />
          </Content>
        </Layout>
      </div>
    )
  }
}


================================================
FILE: src/containers/MovieDetailContainer.js
================================================
import React, {Component} from 'react'
import {Layout, Rate, Card, Icon, Row, BackTop} from 'antd'
import MovieBanner from '../components/Movie/MovieBanner'
import MovieIntro from '../components/Movie/MovieIntro'
import MovieAbout from '../components/Movie/MovieAbout'
import {fetch_movieDetail} from '../common/fetch'

export default class MovieDetailContainer extends Component {
  state = {
    data: null,
    isLoading: true
  }

  componentDidMount() {
    fetch_movieDetail({
      id: this.props.params.id
    })
      .then(data=>{
        if (data && !this.unmount) {
          this.setState({
            data: data,
            isLoading: false
          })
        }
      })
      .catch(err=>
        console.log('parsing failed', err)
      )
  }

  componentWillUnmount() {
    this.unmount = true;
  }

  render() {
    return (
      <div className='movie_detail'>
        <MovieBanner
          isLoading={this.state.isLoading}
          data={this.state.data}
        />
        <Row>
          <MovieIntro
            isLoading={this.state.isLoading}
            data={this.state.data}
          />
          <MovieAbout />
        </Row>
        <BackTop>
          <div className="ant-back-top-inner">
            <Icon type="arrow-up"/>
          </div>
        </BackTop>
      </div>
    )
  }
}


================================================
FILE: src/containers/MusicContainer.js
================================================
import React, { Component } from 'react'

export default class MusicContainer extends Component {
  constructor(props){
    super(props);
    this.state = {};
  }

  componentDidMount() {
  }

  render() {
    return (
      <div>
         敬请期待...
      </div>
    )
  }
}


================================================
FILE: src/containers/MusicDetailContainer.js
================================================
import React, { Component } from 'react'

export default class MusicDetailContainer extends Component {
  constructor(props){
    super(props);
    this.state = {};
  }

  componentDidMount() {
  }

  render() {
    return (
      <div>
         MusicDE页面暂时不开发
      </div>
    )
  }
}


================================================
FILE: src/containers/NotFoundPage.js
================================================
import React, {Component} from 'react'

export default class SportContainer extends Component {
  render() {
    return (
      <div className='not_found'>
        <img src="../image/404.png"/>
      </div>
    )
  }
}

================================================
FILE: src/containers/SpotContainer.js
================================================
import React, { Component } from 'react'

export default class SpotContainer extends Component {
  constructor(props){
    super(props);
    this.state = {};
  }

  componentDidMount() {
  }

  render() {
    return (
      <div>
         敬请期待...
      </div>
    )
  }
}


================================================
FILE: src/containers/SpotDetailContainer.js
================================================
import React, { Component } from 'react'

export default class SpotDetailContainer extends Component {
  constructor(props){
    super(props);
    this.state = {};
  }

  componentDidMount() {
  }

  render() {
    return (
      <div>
         SportDE页面暂时不开发
      </div>
    )
  }
}


================================================
FILE: src/index.html
================================================
<!doctype html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport"
          content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge" >
    <link rel="shortcut icon" href="./favicon.ico" >
    <link rel="stylesheet" href="app.css">
    <title>简趣</title>
</head>
<body>
<div id="app"></div>
<script src="bundle.js"></script>
</body>
</html>

================================================
FILE: src/index.js
================================================
import React from 'react'
import ReactDOM from 'react-dom'

import RootRouter from './config/Route-Config'

import 'antd/dist/antd.less'
import './style/App'
import './style/base'
import './style/BookList'
import './style/ColumnHeader'
import './style/Home'
import './style/ListLoadMore'
import './style/Login'
import './style/MovieDetail'
import './style/MovieMenu'
import './style/Music'
import './style/NewsList'
import './style/Pages'
import './style/Spot'
import './style/TopList'
import './style/MovieItem'
import './style/MovieColumn'

ReactDOM.render(
  <div>
    {RootRouter}
  </div>,
  document.getElementById('app')
)


================================================
FILE: src/style/App.less
================================================
// 首页样式
.logo {
  display: block;
  line-height: 64px;
  height: 64px;
  background: url('../image/logo.png') left center no-repeat;
  background-position: 0 0;
}

.header_tab {
  float: right;
  line-height: 62px;
  li {
    a {
      display: block;
      font-size: 18px;
      text-align: center;
      height: 64px;
      &:hover {
        color: #f2bd00
      }
    }
    width: 80px;
    float: left;
    height: 62px;
  }
}

.header_curPage {
  color: #f2bd00;
  width: 80px;
  line-height: 64px;
  display: block;
  text-align: center;
  border-bottom: 2px solid #108ee9;
}

/*覆盖样式*/
.ant-layout-header.wrap {
  background-color: #fcfcfc;
  height: 64px;
  line-height: 64px;

  .ant-row {
    border-bottom: 1px solid #eee;
  }
}

.center {
  padding: 10px 50px 0px 50px;
  .ant-layout-content {
    padding: 0px 8px;
    border: 1px solid #eee;
    border-radius: 10px;
    background-color: #fff;
  }
  .ant-layout, .ant-layout-sider {
    overflow-x: hidden;
    overflow-y: hidden;
    background-color: #fcfcfc;
  }

  .ant-menu {
    text-align: center;
    margin-right: 10px;
    background-color: #fff;
  }

  .ant-menu-inline, .ant-menu-vertical {
    border: 1px solid #eee;
    border-radius: 10px;
    background-color: #fff;
  }

  //右侧中心显示区域
  .content {
    padding-left: 10px;
    border: 1px solid #eee;
    border-radius: 10px;
    background-color: #fff;
    overflow-x: hidden;
  }
}

.ant-modal-title{
  text-align: center;
  font-weight: normal;
}
// 卡片样式
.ant-card {
  margin: 20px 0px;
}

// backTop样式
.ant-back-top-inner {
  height: 40px;
  width: 40px;
  line-height: 40px;
  border-radius: 4px;
  background-color: #1088e9;
  color: #fff;
  text-align: center;
  font-size: 20px;
}

// 星星样式
.ant-rate {
  padding-left: 10px;
}

// 加载中样式
.loading {
  padding: 30px 50px;
  text-align: center;
}

.not_found {
  height: 300px;
  background-color: #FFF;
  text-align: center;
  img {
    padding-top: 50px;
    width: 300px;
  }
}

================================================
FILE: src/style/BookList.less
================================================
.list-summary {
  font-size: 0;
  margin-bottom: -30px;
  clear: both;
  li {
    width: 340px;
    height: 180px;
    float: left;
    margin-bottom: 30px;
    display: inline-block;
  }
  .cover {
    float: left;
    margin-right: 18px;
  }
  .title {
    font-size: 14px;
    height: auto;
    margin: 0;
    background: none;
  }
  .info {
    font-size: 12px;
    margin-right: 20px;
    height: 180px;
    p {
      margin: 0;
      word-wrap: break-word;
      .meta-label {
        display: inline-block;
        line-height: 1;
        color: #fff;
        padding: 2px 3px;
        background-color: #a1a1a1;
      }
    }
    .reviews {
      color: #666;
      clear: both;
      padding-top: 15px;
    }
    .star-img {
      color: #4dd197
    }
  }
  &:after {
    content: "";
    display: block;
    clear: both;
  }
}


================================================
FILE: src/style/ColumnHeader.less
================================================
//栏目
.column_header {
  border-bottom: 1px solid #eee;
  height: 36px;
  line-height: 30px;
  padding: 5px 10px 5px 0px;
  margin-bottom: 8px;
  .column_more {
    float: right;
    padding-right: 10px;
    color: #9DC;
  }
  .column_title {
    float: left;
    font-size: 18px;
    display: inline-block;
    a {
      color: #E8570C;
    }
  }
}


================================================
FILE: src/style/Home.less
================================================
.home {
  .ant-card-body {
    padding: 10px 20px;
  }
  .movie_item {
    width: 20%;
  }
  .carousel{
    padding-bottom: 10px;
    .slick-slide{
      img {
        width: 100%;
      }
    }
  }
  .column_header {
    margin-top:10px;
  }
  .ant-tabs-bar {
    margin-bottom: 8px;
  }
}

================================================
FILE: src/style/ListLoadMore.less
================================================
.list_load {
  padding-top: 10px;
  .ant-btn {
    width: 100%;
    text-align: center;
  }
  p {
    text-align: center;
    color:#e1e1e1;
  }
}

================================================
FILE: src/style/Login.less
================================================
.login {
  text-align: center;
  line-height: 64px;
  font-size: 14px;
  color: #0c0c0c;
  cursor: pointer;
}

.login_icon {
  font-size: 18px;
  color: #108ee9;
  margin-right: 5px;
}

.login-form {
  max-width: 300px;
  margin: 0 auto;
}

.login-form-forgot {
  float: right;
}

.login-form-button {
  width: 100%;
}

.modal_back {
  display: block;
  position: absolute;
  left: 0;
  top: -2px;
  cursor: pointer;
  color: #aaa;
  transition: color 0.3s;
  &:hover {
    color: #000
  }
}



================================================
FILE: src/style/MovieColumn.less
================================================
.movie_column {
  .ant-row {
    border-bottom: 1px solid #eee;
    padding-bottom: 8px;
  }
}

================================================
FILE: src/style/MovieDetail.less
================================================
.movie_detail {
  .movie_intro {
    font-size: 14px;
  }
  .movie_banner {
    height: 350px;
    background-image: url("../image/banner.jpg");
    background-repeat: no-repeat;
    background-size: cover;
    padding: 26px 10px 0px 100px;
  }

  .movie_introduce {
    height: 260px;
  }

  .movie_poster {
    width: 220px;
    height: 300px;
    float: left;
    img {
      width: 100%;
      height: 100%;
    }
  }

  .movie_info {
    width: 400px;
    padding-left: 50px;
    color: #FFF;
    float: left;
    h4 {
      margin-bottom: 15px;
    }
    p {
      padding: 8px 0px;
    }
  }

  .movie_content {
    width: 200px;
    padding-left: 50px;
    padding-top: 50px;
    text-align: center;
    color: #FFF;
    float: left;
  }

  .movie_gate {
    font-size: 50px;
    font-family: sans-serif;
    color: #108ee9;
    padding: 20px;
    text-align: center;
  }

  .actor {
    :last-child {
      margin-right: 0px;
    }
    li {
      float: left;
      margin-right: 20px;
      p {
        text-align: center;
        height: 20px;
      }
      a {
        display: inline-block;
        width: 128px;
        height: 170px;
        img {
          width: 100%;
          height: 100%;
        }
      }
    }
  }

  .movie_comment {
    border-bottom: 1px solid #eee;
    padding: 10px 0px;
    .movie_commentator {
      width: 100%;
      float: left;
      margin-bottom: 10px;
      border-bottom: 1px solid #eee;
      padding-bottom: 5px;
      line-height: 36px;
      img {
        width: 30px;
        height: 30px;
        border-radius: 15px;
        margin-right: 10px;
      }
    }
    .movie_commentdate {
      float: right;
    }
    p {
      padding-left: 5px;
      padding-top: 5px;
    }
  }

  .movie_about {
    .ant-card-body {
      div {
        cursor: pointer;
        height: 50px;
        p:last-child {
          font-size: 10px;
          color: #4fd2be;
        }
      }
    }
  }
}


================================================
FILE: src/style/MovieItem.less
================================================
.movie_item {
  &> div{
    margin: 0 5px;
  }
  .movie_img {
    height: 280px;
    img {
      width: 100%;
      height: 100%;
    }
  }
  .movie_info {
    height: 20px;
    margin-top: 8px;
    .movie_title {
      height: 20px;
      width: 85%;
      font-size: 16px;
      line-height: 20px;
      font-weight: bold;
      float: left;
      overflow: hidden;
      text-overflow: ellipsis;
      white-space: nowrap;
    }
    .movie_score {
      height: 20px;
      line-height: 20px;
      font-size: 18px;
      float: right;
      text-align: right;
      color: #108ee9;
      width: 15%;
    }
    .movie_genre {
      .movie_score;
      font-size: 14px;
      color: #66CD00;
    }
  }
}

================================================
FILE: src/style/MovieMenu.less
================================================
.movie_menu {
  border: 1px solid #eee;
  margin-right: 10px;
  border-radius: 10px;
  .ant-anchor{
    text-align: center;
    .ant-anchor-ink{
      display: none;
    }
    .ant-anchor-link {
      line-height: 20px;
      font-size: 14px;
      padding:8px;
    }
  }
}

================================================
FILE: src/style/Music.less
================================================
.m-cvrlst {
  margin: 20px 0 0 -42px;
  li {
    width: 180px;
    height: 204px;
    float: left;
    display: inline-block;
    overflow: hidden;
    padding: 0 0 30px 42px;
    line-height: 1.4;
    div.u-cover {
      width: 140px;
      height: 140px;
      position: relative;
      display: block;
      img {
        display: block;
        width: 100%;
        height: 100%;
      }
      .msk {
        position: absolute;
        top: 0;
        left: 0;
        width: 100%;
        height: 100%;
        background-position: 0 0;
        background: url(../image/coverall.png) no-repeat;
      }
      .icon-play {
        display: inline-block;
        position: absolute;
        right: 10px;
        bottom: 5px;
        width: 16px;
        height: 17px;
        background: url(../image/iconall.png) no-repeat;
        background-position: 0 0;
        float: right;
      }
      .icon-headset {
        display: inline-block;
        float: left;
        width: 16px;
        height: 16px;
        margin: 7px 7px 7px 5px;
        background: url(../image/iconall.png) no-repeat;
        background-position: 0 -24px;
      }
      .nb {
        float: left;
        margin: 7px 0 0 0;
      }
      .bottom {
        position: absolute;
        bottom: 0;
        left: 0;
        width: 100%;
        height: 27px;
        background: url(../image/coverall.png) no-repeat;
        background-position: 0 -537px;
        color: #ccc;
      }
      p {
        margin: 8px 0 3px;
        width: 100%;
      }
    }
    .dec {
      margin: 8px 0 3px;
    }
    .tit {
      display: inline-block;
      max-width: 100%;
      vertical-align: middle;
      color: #000;
    }
  }
}



================================================
FILE: src/style/NewsList.less
================================================
.newsList {
  padding-left: 10px;
  ul > li {
    padding-top: 5px;
    border-bottom: 1px solid #eee;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    height: 70px;
    a {
      color: #595959;
    }
    img {
      width: 80px;
      height: 60px;
      margin-right: 5px;
    }
  }
}

================================================
FILE: src/style/Pages.less
================================================
.Pages {
  height: 24px;
  line-height: 24px;
  ul.ant-pagination {
    float: right;
  }
}

================================================
FILE: src/style/Spot.less
================================================
.spot_news {
  .carousel {
    width: 300px;
    height: 400px;
    padding-left: 20px;
    .slick-slide {
      img {
        width: 100%;
      }
    }
  }
}


================================================
FILE: src/style/TopList.less
================================================
.topList {
  padding-left: 10px;
  ul > li {
    border-bottom: 1px solid #eee;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    height: 36px;
    line-height: 36px;
    a {
      color: #595959;
    }
    span {
      display: inline-block;
      font-size: 20px;
      vertical-align: middle;
      margin-right: 8px;
    }
    h3 {
      text-align: center;
      color: #108ee9;
    }
  }
  ul > li:nth-child(4), li:nth-child(2), li:nth-child(3) {
    span {
      color: #ED1C24;
    }
  }
}

================================================
FILE: src/style/base.less
================================================
/* CSS Document */

/* css reset */
body, h1, h2, h3, h4, h5, h6, p, ul, ol, dl, dd, form, pre, input, textarea, select, th, td {
    margin: 0;
    padding: 0;
    font-family: "Microsoft Yahei";
}

h1, h2, h3, h4, h5, h6, tr, th, td, textarea {
    word-wrap: break-word;
    word-break: break-all;
}

body {
    font-size: 12px;
    background-color: @bgColor;
}

em {
    font-style: normal;
}

li {
    list-style: none;
}

a {
    text-decoration: none;
}

img {
    border: none;
    vertical-align: middle;
}

table {
    border-collapse: collapse;
}

th, td {
    padding: 0;
}

textarea {
    overflow: auto;
    resize: none;
}

/* end css reset */

/*public.css*/
.wrap {
    width: 1170px;
    margin: 0 auto;
}

.auto {
    margin: 0 auto;
}

.clear {
    zoom: 1;
}

.clear:after {
    content: "";
    display: block;
    clear: both;
}

.fl {
    float: left;
}

.fr {
    float: right;
}
// 间距
.pl5 {
    padding-left: 5px;
}

.pl10 {
    padding-left: 10px;
}

.pl15 {
    padding-left: 15px;
}

.pl20 {
    padding-left: 20px;
}

.pl30 {
    padding-left: 30px;
}

.pl40 {
    padding-left: 40px;
}

.pr5 {
    padding-right: 5px;
}

.pr10 {
    padding-right: 10px;
}

.pr20 {
    padding-right: 20px;
}

.pt5 {
    padding-top: 5px;
}

.pt10 {
    padding-top: 10px;
}

.pt20 {
    padding-top: 20px;
}

.pt30 {
    padding-top: 30px;
}

.pb5 {
    padding-bottom: 5px;
}

.pb10 {
    padding-bottom: 10px;
}

.pb20 {
    padding-bottom: 20px;
}

.pb30 {
    padding-bottom: 30px;
}

.ml5 {
    margin-left: 5px;
}

.ml10 {
    margin-left: 10px;
}

.ml15 {
    margin-left: 15px;
}

.ml20 {
    margin-left: 20px;
}

.ml30 {
    margin-left: 30px;
}

.ml40 {
    margin-left: 40px;
}

.mr5 {
    margin-right: 5px;
}

.mr10 {
    margin-right: 10px;
}

.mr15 {
    margin-right: 15px;
}

.mr20 {
    margin-right: 20px;
}

.mr30 {
    margin-right: 30px;
}

.mt3 {
    margin-top: 3px;
}

.mt5 {
    margin-top: 5px;
}

.mt8 {
    margin-top: 8px;
}

.mt10 {
    margin-top: 10px;
}

.mt15 {
    margin-top: 15px;
}

.mt20 {
    margin-top: 20px;
}

.mt30 {
    margin-top: 30px;
}

.mb5 {
    margin-bottom: 5px;
}

.mb10 {
    margin-bottom: 10px;
}

.mb15 {
    margin-bottom: 15px;
}

.mb20 {
    margin-bottom: 20px;
}

.mb40 {
    margin-bottom: 40px;
}

.mb50 {
    margin-bottom: 50px;
}
//字体
.fb {
    font-weight: bold;
}

.fz12 {
    font-size: 12px;
}

.fz14 {
    font-size: 14px;
}

.fz16 {
    font-size: 16px;
}

.fz18 {
    font-size: 18px;
}

.fz24 {
    font-size: 24px;
}
// 高度
.h20 {
    height: 20px;
}

.h28 {
    height: 28px;
}

.h64 {
    height: 64px;
}

.w45 {
    width: 45px;
}

.w50 {
    width: 50px;
}

.w60 {
    width: 60px;
}

.w70 {
    width: 70px;
}

.w84 {
    width: 84px;
}

.w80 {
    width: 80px;
}

.w90 {
    width: 90px;
}

.w100 {
    width: 100px;
}

.w106 {
    width: 106px;
}

.w115 {
    width: 115px;
}

.w120 {
    width: 120px;
}

.w125 {
    width: 125px;
}

.w140 {
    width: 140px;
}

.w150 {
    width: 150px;
}

.w157 {
    width: 157px;
}

.w190 {
    width: 190px;
}

.w200 {
    width: 200px;
}

.w230 {
    width: 230px;
}

.w250 {
    width: 250px;
}

.w280 {
    width: 280px;
}

.w300 {
    width: 300px;
}

.w308 {
    width: 308px;
}

.w350 {
    width: 350px;
}

.w370 {
    width: 370px;
}

.w400 {
    width: 400px;
}

.w420 {
    width: 420px;
}

.w440 {
    width: 440px;
}

.w485 {
    width: 485px;
}

.w530 {
    width: 530px;
}

.w550 {
    width: 550px;
}

.w580 {
    width: 580px;
}

.w650 {
    width: 650px;
}

.w680 {
    width: 680px;
}

.w700 {
    width: 700px;
}

.w720 {
    width: 720px;
}

.w750 {
    width: 750px;
}

.w950 {
    width: 950px;
}

.vm2 {
    vertical-align: -2px;
}

.vm3 {
    vertical-align: -3px;
}

.lh15 {
    line-height: 15px;
}

.lh18 {
    line-height: 18px;
}

.lh20 {
    line-height: 20px;
}

.lh23 {
    line-height: 23px;
}

.lh25 {
    line-height: 25px;
}

.lh28 {
    line-height: 28px;
}

.lh30 {
    line-height: 30px;
}

.pointer {
    cursor: pointer;
}

.tl {
    text-align: left;
}

.tc {
    text-align: center;
}

.tr {
    text-align: right;
}

.rel {
    position: relative;
}

.abs {
    position: absolute;
}

.fixd {
    position: fixed;
}

.vbh {
    visibility: hidden;
}

.nowrap {
    white-space: nowrap;
}

.wraps {
    word-wrap: break-word;
    word-break: break-all;
}

.omit {
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.fs {
    font-family: "Microsoft Yahei";
}

.ti2 {
    text-indent: 24px;
}

.vam {
    vertical-align: middle;
}

.normal {
    font-style: normal;
}

// 清除浮动
.fix {
    display: inline-table;
    display: block;
    height: 1%;
}

.fix:after {
    visibility: hidden;
    display: block;
    font-size: 0;
    content: " ";
    clear: both;
    height: 0;
}

// 边框线
.bdt {
    border-top: 1px solid @bdColor;
}
.bdb {
    border-bottom: 1px solid @bdColor;
}
.bdr {
    border-right: 1px solid @bdColor;
}
.bdl {
    border-left: 1px solid @bdColor;
}
.bd {
    border: 1px solid @bdColor;
}
// 块
.inblock {
    display: inline-block;
}

.hide {
    display: none;
}

.db {
    display: block;
}

// 当前
@current: #f2bd00;
// 主题色
@theme: #108ee9;
// 背景色
@bgColor: #fcfcfc;
// 边框色
@bdColor: #eee;
// 栏目头色
@columnColor: #E8570C;
// 更多字体色
@moreColor: #9DC;
// 电影类型
@genre: #66CD00;

================================================
FILE: src/template/template.html
================================================
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>简趣</title>
</head>
<body>
<div id="app"></div>
</body>
</html>

================================================
FILE: webpack.dev.config.js
================================================
var webpack = require('webpack');
var path = require('path');
var ExtractTextPlugin = require("extract-text-webpack-plugin"); // 打包css插件
var OpenBrowserPlugin = require('open-browser-webpack-plugin'); // 编译后自动打开浏览器

var ROOT_PATH = path.resolve(__dirname); // 项目跟路径
var APP_PATH = path.resolve(ROOT_PATH, 'src'); // 项目开发目录src
var APP_FILE = path.resolve(APP_PATH, 'index.js'); // 项目入口的index.js

module.exports = {
  entry: [
    'webpack/hot/dev-server',
    'webpack-dev-server/client?http://localhost:8080',
    APP_FILE
  ],
  output: {
    path: APP_PATH,
    filename: 'bundle.js'
  },
  // 可以在sources里调试
  devtool: "cheap-module-eval-source-map",
  module: {
    loaders: [
      {
        test: /\.css$/,
        loader: ExtractTextPlugin.extract('style', ['css', 'autoprefixer'])
      },
      {
        test: /\.less$/,
        loader: ExtractTextPlugin.extract('style', ['css', 'autoprefixer', 'less'])
      },
      {
        test: /\.js[x]?$/,
        exclude: /node_modules/,
        loaders: ['react-hot', 'babel?presets[]=es2015,presets[]=react,presets[]=stage-0']
      },
      {
        test: /\.(png|jpg)$/,
        loader: 'url-loader?limit=8192'
      },
      {
        test: /\.(woff|woff2|eot|ttf|svg)(\?.*$|$)/,
        loader: 'url'
      }
    ]
  }
  ,
// 其它解决方案配置
  resolve: {
    // 后缀
    extensions: ['', '.js', '.jsx', '.json', '.less']
  }
  ,
// 插件
  plugins: [
    new webpack.DefinePlugin({
      'process.env': {
        NODE_ENV: JSON.stringify('development') //定义生产环境
      }
    }),
    new OpenBrowserPlugin({url: 'http://localhost:8080/#/'}),
    new ExtractTextPlugin("app.css")
  ]
}
;

================================================
FILE: webpack.pub.config.js
================================================
var webpack = require("webpack");
var path = require('path');
var uglifyJsPlugin = webpack.optimize.UglifyJsPlugin;
var ExtractTextPlugin = require("extract-text-webpack-plugin");
var HtmlWebpackPlugin = require('html-webpack-plugin');

var ROOT_PATH = path.resolve(__dirname); // 项目跟路径
var APP_PATH = path.resolve(ROOT_PATH, 'src'); // 项目开发目录src
var APP_FILE = path.resolve(APP_PATH, 'index.js'); // 项目入口的index.js
var DIST_PATH = path.resolve(ROOT_PATH, 'dist'); // 项目打包输出路径

module.exports = {
  entry: {
    app: APP_FILE,
    venders: [
      'react',
      'react-dom',
      'react-router',
      // 'antd',这里直接会把所有antd打包
      'mockjs'
    ]
  },
  output: {
    path: DIST_PATH,
    //表示资源的发布地址,当配置过该属性后,打包文件中所有通过相对路径引用的资源都会被配置的路径所替换
    //publicPath: '/',
    filename: '[name].js',
    chunkFilename: 'js/[name].[chunkhash:5].min.js'
  },
  module: {
    loaders: [
      {
        test: /\.css$/,
        loader: ExtractTextPlugin.extract('style', ['css', 'autoprefixer'])
      },
      {
        test: /\.less$/,
        loader: ExtractTextPlugin.extract('style', ['css', 'autoprefixer', 'less'])
      },
      {
        test: /\.jsx?$/,
        exclude: /node_modules/,
        loaders: ['react-hot', 'babel?presets[]=es2015,presets[]=react,presets[]=stage-0']
      },
      {
        test: /\.(png|jpg)$/,
        loader: 'url-loader?limit=8192&name=image/[hash:8].[name].[ext]'
      },
      {
        test: /\.(woff|woff2|eot|ttf|svg)(\?.*$|$)/,
        loader: 'url'
      }
    ]
  },
  resolve: {
    extensions: ['', '.js', '.jsx', '.json', '.less']
  },
  plugins: [
    // new webpack.ProvidePlugin({ $: "jquery" }), // 这是将jquery变成全局变量,不用在自己文件require('jquery')了
    new webpack.DefinePlugin({
      'process.env': {
        NODE_ENV: JSON.stringify('production') //定义生产环境
      }
    }),
    new webpack.optimize.CommonsChunkPlugin('venders', 'venders.js'), // 这是妮第三方库打包生成的文件
    new uglifyJsPlugin({
      output: {
        comments: false, // remove all comments
      },
      compress: {
        warnings: false
      }
    }),
    new ExtractTextPlugin("[name].css"),
    new HtmlWebpackPlugin({
      template: './src/template/template.html', // html模板路径
      htmlWebpackPlugin: {
        files: {
          css: ["app.css"],
          js: ["bundle.js", "venders.js"]
        }
      },
      minify: {
        removeComments: true, // 移除HTML中的注释
        collapseWhitespace: true, // 删除空白符与换行符
        removeAttributeQuotes: true // 移除HTML中的属性引号
      },
      filename: 'index.html',
      favicon:'./src/favicon.ico', //favicon路径
    })
  ]
};
Download .txt
gitextract_as64i4d8/

├── .babelrc
├── .gitattributes
├── .gitignore
├── README.md
├── docs/
│   └── EasyFun.xmind
├── package.json
├── src/
│   ├── common/
│   │   ├── fetch.js
│   │   └── mock.js
│   ├── components/
│   │   ├── Book/
│   │   │   ├── BookColumn.js
│   │   │   └── BookList.js
│   │   ├── ColumnHeader.js
│   │   ├── Footer.js
│   │   ├── Header.js
│   │   ├── ListLoadMore.js
│   │   ├── Loading.js
│   │   ├── Login/
│   │   │   ├── Login.js
│   │   │   ├── LoginForm.js
│   │   │   └── Register.js
│   │   ├── Movie/
│   │   │   ├── MovieAbout.js
│   │   │   ├── MovieActor.js
│   │   │   ├── MovieBanner.js
│   │   │   ├── MovieColumn.js
│   │   │   ├── MovieIntro.js
│   │   │   ├── MovieItem.js
│   │   │   ├── MovieList.js
│   │   │   └── MovieMenu.js
│   │   ├── Music/
│   │   │   ├── MusicColumn.js
│   │   │   └── MusicList.js
│   │   ├── Pages.js
│   │   ├── Spot/
│   │   │   ├── NewsList.js
│   │   │   ├── NewsListBlock.js
│   │   │   ├── SpotColumn.js
│   │   │   └── TopListBlock.js
│   │   └── TopList.js
│   ├── config/
│   │   ├── Route-Config.js
│   │   └── index.js
│   ├── containers/
│   │   ├── AppContainer.js
│   │   ├── BookContainer.js
│   │   ├── BookDetailContainer.js
│   │   ├── HomeContainer.js
│   │   ├── MovieContainer.js
│   │   ├── MovieDetailContainer.js
│   │   ├── MusicContainer.js
│   │   ├── MusicDetailContainer.js
│   │   ├── NotFoundPage.js
│   │   ├── SpotContainer.js
│   │   └── SpotDetailContainer.js
│   ├── index.html
│   ├── index.js
│   ├── style/
│   │   ├── App.less
│   │   ├── BookList.less
│   │   ├── ColumnHeader.less
│   │   ├── Home.less
│   │   ├── ListLoadMore.less
│   │   ├── Login.less
│   │   ├── MovieColumn.less
│   │   ├── MovieDetail.less
│   │   ├── MovieItem.less
│   │   ├── MovieMenu.less
│   │   ├── Music.less
│   │   ├── NewsList.less
│   │   ├── Pages.less
│   │   ├── Spot.less
│   │   ├── TopList.less
│   │   └── base.less
│   └── template/
│       └── template.html
├── webpack.dev.config.js
└── webpack.pub.config.js
Download .txt
SYMBOL INDEX (69 symbols across 23 files)

FILE: src/common/fetch.js
  function fetch_movie (line 5) | function fetch_movie(opt) {
  function fetch_movieDetail (line 25) | function fetch_movieDetail(opt) {
  function fetch_login (line 42) | function fetch_login(opt) {
  function fetch_spot (line 63) | function fetch_spot(opt) {

FILE: src/components/Book/BookColumn.js
  class MusicColumn (line 5) | class MusicColumn extends Component {
    method render (line 6) | render() {

FILE: src/components/Login/Login.js
  class Login (line 7) | class Login extends Component {
    method componentDidMount (line 14) | componentDidMount() {
    method render (line 68) | render() {

FILE: src/components/Login/LoginForm.js
  class LoginForm (line 5) | class LoginForm extends Component {
    method render (line 21) | render() {

FILE: src/components/Login/Register.js
  class RegistrationForm (line 7) | class RegistrationForm extends Component {
    method render (line 59) | render() {

FILE: src/components/Movie/MovieColumn.js
  class MovieColumn (line 9) | class MovieColumn extends Component {
    method componentDidMount (line 16) | componentDidMount() {
    method componentWillUnmount (line 32) | componentWillUnmount() {
    method render (line 61) | render() {

FILE: src/components/Movie/MovieIntro.js
  class MovieIntro (line 8) | class MovieIntro extends Component {
    method render (line 27) | render() {

FILE: src/components/Movie/MovieList.js
  class MovieList (line 5) | class MovieList extends Component {
    method render (line 6) | render() {

FILE: src/components/Music/MusicColumn.js
  class MusicColumn (line 8) | class MusicColumn extends Component {
    method render (line 9) | render() {

FILE: src/components/Spot/NewsListBlock.js
  class NewsListBlock (line 6) | class NewsListBlock extends Component {
    method componentDidMount (line 12) | componentDidMount() {
    method render (line 31) | render() {

FILE: src/components/Spot/TopListBlock.js
  class TopListBlock (line 7) | class TopListBlock extends Component {
    method componentDidMount (line 13) | componentDidMount() {
    method render (line 32) | render() {

FILE: src/config/index.js
  constant SERVER_PATH (line 1) | const SERVER_PATH = 'https://api.douban.com/v2/';
  constant LOGIN_PATH (line 2) | const LOGIN_PATH = 'http://newsapi.gugujiankong.com/Handler.ashx';
  constant DEFAULT_COUNT (line 3) | const DEFAULT_COUNT = 4;
  constant DEFAULT_START (line 4) | const DEFAULT_START = 0;

FILE: src/containers/AppContainer.js
  class AppContainer (line 5) | class AppContainer extends Component {
    method render (line 6) | render() {

FILE: src/containers/BookContainer.js
  class BookContainer (line 3) | class BookContainer extends Component {
    method constructor (line 4) | constructor(props){
    method componentDidMount (line 9) | componentDidMount() {
    method render (line 12) | render() {

FILE: src/containers/BookDetailContainer.js
  class BookDetailContainer (line 3) | class BookDetailContainer extends Component {
    method constructor (line 4) | constructor(props){
    method componentDidMount (line 9) | componentDidMount() {
    method render (line 12) | render() {

FILE: src/containers/HomeContainer.js
  class HomeContainer (line 8) | class HomeContainer extends Component {
    method render (line 9) | render() {

FILE: src/containers/MovieContainer.js
  class MovieContainer (line 8) | class MovieContainer extends Component {
    method render (line 9) | render() {

FILE: src/containers/MovieDetailContainer.js
  class MovieDetailContainer (line 8) | class MovieDetailContainer extends Component {
    method componentDidMount (line 14) | componentDidMount() {
    method componentWillUnmount (line 31) | componentWillUnmount() {
    method render (line 35) | render() {

FILE: src/containers/MusicContainer.js
  class MusicContainer (line 3) | class MusicContainer extends Component {
    method constructor (line 4) | constructor(props){
    method componentDidMount (line 9) | componentDidMount() {
    method render (line 12) | render() {

FILE: src/containers/MusicDetailContainer.js
  class MusicDetailContainer (line 3) | class MusicDetailContainer extends Component {
    method constructor (line 4) | constructor(props){
    method componentDidMount (line 9) | componentDidMount() {
    method render (line 12) | render() {

FILE: src/containers/NotFoundPage.js
  class SportContainer (line 3) | class SportContainer extends Component {
    method render (line 4) | render() {

FILE: src/containers/SpotContainer.js
  class SpotContainer (line 3) | class SpotContainer extends Component {
    method constructor (line 4) | constructor(props){
    method componentDidMount (line 9) | componentDidMount() {
    method render (line 12) | render() {

FILE: src/containers/SpotDetailContainer.js
  class SpotDetailContainer (line 3) | class SpotDetailContainer extends Component {
    method constructor (line 4) | constructor(props){
    method componentDidMount (line 9) | componentDidMount() {
    method render (line 12) | render() {
Condensed preview — 68 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (92K chars).
[
  {
    "path": ".babelrc",
    "chars": 132,
    "preview": "{\n  \"presets\": [\n    \"es2015\",\n    \"react\",\n    \"stage-0\"\n  ],\n  \"plugins\": [[\"import\", { \"libraryName\": \"antd\", \"style\""
  },
  {
    "path": ".gitattributes",
    "chars": 378,
    "preview": "# Auto detect text files and perform LF normalization\n* text=auto\n\n# Custom for Visual Studio\n*.cs     diff=csharp\n\n# St"
  },
  {
    "path": ".gitignore",
    "chars": 56,
    "preview": "node_modules\n\n.idea\ndist\n\nnpm-debug.log\nyarn-error.log\n\n"
  },
  {
    "path": "README.md",
    "chars": 922,
    "preview": "## 简趣\n一个简单趣味的pc-react站\n\n###技术栈\n- React\n- React-Router\n- ES6\n- Less\n- Antd\n- Mock.js\n- Webpack\n    \n###运行\n在目录中,运行指令\n\n    "
  },
  {
    "path": "package.json",
    "chars": 1389,
    "preview": "{\n  \"name\": \"EasyFun\",\n  \"version\": \"1.0.0\",\n  \"description\": \"A project using react es6 webpack antd..\",\n  \"main\": \"ind"
  },
  {
    "path": "src/common/fetch.js",
    "chars": 1619,
    "preview": "import fetchJsonp from 'fetch-jsonp'\nimport * as config from '../config'\nrequire('es6-promise').polyfill();\n// 获取电影列表\nex"
  },
  {
    "path": "src/common/mock.js",
    "chars": 1145,
    "preview": "import Mock from 'mockjs'\nconst {Random} = Mock\n\nexport const comments = Mock.mock({\n  'commentList|5': [{\n    'id': '@n"
  },
  {
    "path": "src/components/Book/BookColumn.js",
    "chars": 382,
    "preview": "import React, {Component} from 'react'\nimport BookList from './BookList'\nimport ColumnHeader from '../ColumnHeader'\n\nexp"
  },
  {
    "path": "src/components/Book/BookList.js",
    "chars": 12378,
    "preview": "import React from 'react'\n\nconst BookList = () => {\n  return (\n    <div>\n      <ul className=\"list-col list-summary\">\n  "
  },
  {
    "path": "src/components/ColumnHeader.js",
    "chars": 500,
    "preview": "import React from 'react'\nimport {Link} from 'react-router'\nimport Pages from './Pages'\n\nconst ColumnHeader = ({title, i"
  },
  {
    "path": "src/components/Footer.js",
    "chars": 268,
    "preview": "import React from 'react'\nimport {Layout} from 'antd'\n\nconst {Footer} = Layout\n\nconst Foot = () => {\n  return (\n    <Foo"
  },
  {
    "path": "src/components/Header.js",
    "chars": 951,
    "preview": "import React from 'react'\nimport {Link, IndexLink} from 'react-router'\nimport {Layout, Row, Col} from 'antd'\nimport Logi"
  },
  {
    "path": "src/components/ListLoadMore.js",
    "chars": 370,
    "preview": "import React, {Component} from 'react'\nimport {Button} from 'antd'\n\nconst ListLoadMore = ({isLoading, handleClick, count"
  },
  {
    "path": "src/components/Loading.js",
    "chars": 186,
    "preview": "import React, {Component} from 'react'\nimport {Spin} from 'antd'\n\nconst Loading = ()=> {\n  return (\n    <div className='"
  },
  {
    "path": "src/components/Login/Login.js",
    "chars": 2352,
    "preview": "import React, {Component} from 'react'\nimport {Modal, Icon, Button, message} from 'antd'\nimport LoginForm from './LoginF"
  },
  {
    "path": "src/components/Login/LoginForm.js",
    "chars": 1589,
    "preview": "import React, {Component} from 'react'\nimport {Form, Icon, Input, Button, message} from 'antd';\nconst FormItem = Form.It"
  },
  {
    "path": "src/components/Login/Register.js",
    "chars": 4147,
    "preview": "import React, {Component} from 'react'\nimport {Form, Input, Button, Radio, InputNumber, message} from 'antd';\nimport {fe"
  },
  {
    "path": "src/components/Movie/MovieAbout.js",
    "chars": 1028,
    "preview": "import React from 'react'\nimport {Card, Row, Col} from 'antd'\nimport {messages, correlations} from '../../common/mock'\n\n"
  },
  {
    "path": "src/components/Movie/MovieActor.js",
    "chars": 918,
    "preview": "import React from 'react'\nimport {Card, Icon} from 'antd'\nimport Loading from '../Loading'\n\nconst MovieActors = ({direct"
  },
  {
    "path": "src/components/Movie/MovieBanner.js",
    "chars": 1446,
    "preview": "import React, {Component} from 'react'\nimport {Rate} from 'antd'\nimport Loading from '../Loading'\n\nconst MovieBanner = ("
  },
  {
    "path": "src/components/Movie/MovieColumn.js",
    "chars": 1893,
    "preview": "import React, {Component} from 'react'\nimport ColumnHeader from '../ColumnHeader'\nimport MovieList from './MovieList'\nim"
  },
  {
    "path": "src/components/Movie/MovieIntro.js",
    "chars": 1746,
    "preview": "import React, {Component} from 'react'\nimport {Card, Col} from 'antd'\nimport {comments, commentsMore} from '../../common"
  },
  {
    "path": "src/components/Movie/MovieItem.js",
    "chars": 795,
    "preview": "import React, {Component} from 'react'\nimport {Link} from 'react-router'\nimport {Col} from 'antd'\nimport * as config fro"
  },
  {
    "path": "src/components/Movie/MovieList.js",
    "chars": 1204,
    "preview": "import React, {Component, PropTypes} from 'react'\nimport MovieItem from './MovieItem'\nimport {Row} from 'antd'\n\nexport d"
  },
  {
    "path": "src/components/Movie/MovieMenu.js",
    "chars": 373,
    "preview": "import React from 'react'\nimport {Anchor} from 'antd'\n\nconst {Link} = Anchor\n\nconst MovieMenu = () => {\n  return (\n    <"
  },
  {
    "path": "src/components/Music/MusicColumn.js",
    "chars": 689,
    "preview": "import React, {Component} from 'react'\nimport {Row, Col} from 'antd'\nimport MusicList from './MusicList'\nimport TopList "
  },
  {
    "path": "src/components/Music/MusicList.js",
    "chars": 5420,
    "preview": "import React, {Component} from 'react'\n\nconst MusicList = ()=> {\n  return (\n    <ul className=\"m-cvrlst\">\n      <li>\n   "
  },
  {
    "path": "src/components/Pages.js",
    "chars": 398,
    "preview": "import React, { Component } from 'react'\nimport { Pagination } from 'antd'\n\nconst Pages = ({current, total, onChange, de"
  },
  {
    "path": "src/components/Spot/NewsList.js",
    "chars": 530,
    "preview": "import React from 'react';\nimport {Link} from 'react-router'\n\nconst NewsList = ({newsData}) => {\n  if (!newsData) {\n    "
  },
  {
    "path": "src/components/Spot/NewsListBlock.js",
    "chars": 804,
    "preview": "import React, {Component} from 'react'\nimport {fetch_spot} from '../../common/fetch'\nimport NewsList from './NewsList'\ni"
  },
  {
    "path": "src/components/Spot/SpotColumn.js",
    "chars": 2154,
    "preview": "import React, {Component} from 'react'\nimport {Row, Col, Carousel, Tabs} from 'antd'\nimport NewsListBlock from './NewsLi"
  },
  {
    "path": "src/components/Spot/TopListBlock.js",
    "chars": 853,
    "preview": "import React, {Component} from 'react';\nimport {Link} from 'react-router'\nimport TopList from '../TopList'\nimport Loadin"
  },
  {
    "path": "src/components/TopList.js",
    "chars": 459,
    "preview": "import React from 'react';\nimport {Link} from 'react-router'\n\nconst TopList = ({data, title, link}) => {\n  if (!data) {\n"
  },
  {
    "path": "src/config/Route-Config.js",
    "chars": 2884,
    "preview": "import React from 'react'\nimport {Router, Route,  IndexRoute, Redirect, hashHistory} from 'react-router'\nimport AppConta"
  },
  {
    "path": "src/config/index.js",
    "chars": 199,
    "preview": " export const SERVER_PATH = 'https://api.douban.com/v2/';\n export const LOGIN_PATH = 'http://newsapi.gugujiankong.com/Ha"
  },
  {
    "path": "src/containers/AppContainer.js",
    "chars": 364,
    "preview": "import React, {Component} from 'react'\nimport Header from '../components/Header'\nimport Footer from '../components/Foote"
  },
  {
    "path": "src/containers/BookContainer.js",
    "chars": 272,
    "preview": "import React, { Component } from 'react'\n\nexport default class BookContainer extends Component {\n  constructor(props){\n "
  },
  {
    "path": "src/containers/BookDetailContainer.js",
    "chars": 277,
    "preview": "import React, { Component } from 'react'\n\nexport default class BookDetailContainer extends Component {\n  constructor(pro"
  },
  {
    "path": "src/containers/HomeContainer.js",
    "chars": 1244,
    "preview": "import React, {Component} from 'react'\nimport {Carousel, Card, BackTop, Icon} from 'antd'\nimport MovieColumn from '../co"
  },
  {
    "path": "src/containers/MovieContainer.js",
    "chars": 1075,
    "preview": "import React, { Component } from 'react'\nimport {Layout} from 'antd'\nimport MovieMenu from '../components/Movie/MovieMen"
  },
  {
    "path": "src/containers/MovieDetailContainer.js",
    "chars": 1323,
    "preview": "import React, {Component} from 'react'\nimport {Layout, Rate, Card, Icon, Row, BackTop} from 'antd'\nimport MovieBanner fr"
  },
  {
    "path": "src/containers/MusicContainer.js",
    "chars": 273,
    "preview": "import React, { Component } from 'react'\n\nexport default class MusicContainer extends Component {\n  constructor(props){\n"
  },
  {
    "path": "src/containers/MusicDetailContainer.js",
    "chars": 286,
    "preview": "import React, { Component } from 'react'\n\nexport default class MusicDetailContainer extends Component {\n  constructor(pr"
  },
  {
    "path": "src/containers/NotFoundPage.js",
    "chars": 218,
    "preview": "import React, {Component} from 'react'\n\nexport default class SportContainer extends Component {\n  render() {\n    return "
  },
  {
    "path": "src/containers/SpotContainer.js",
    "chars": 272,
    "preview": "import React, { Component } from 'react'\n\nexport default class SpotContainer extends Component {\n  constructor(props){\n "
  },
  {
    "path": "src/containers/SpotDetailContainer.js",
    "chars": 285,
    "preview": "import React, { Component } from 'react'\n\nexport default class SpotDetailContainer extends Component {\n  constructor(pro"
  },
  {
    "path": "src/index.html",
    "chars": 470,
    "preview": "<!doctype html>\n<html lang=\"en\">\n<head>\n    <meta charset=\"UTF-8\">\n    <meta name=\"viewport\"\n          content=\"width=de"
  },
  {
    "path": "src/index.js",
    "chars": 630,
    "preview": "import React from 'react'\nimport ReactDOM from 'react-dom'\n\nimport RootRouter from './config/Route-Config'\n\nimport 'antd"
  },
  {
    "path": "src/style/App.less",
    "chars": 1965,
    "preview": "// 首页样式\n.logo {\n  display: block;\n  line-height: 64px;\n  height: 64px;\n  background: url('../image/logo.png') left cente"
  },
  {
    "path": "src/style/BookList.less",
    "chars": 837,
    "preview": ".list-summary {\n  font-size: 0;\n  margin-bottom: -30px;\n  clear: both;\n  li {\n    width: 340px;\n    height: 180px;\n    f"
  },
  {
    "path": "src/style/ColumnHeader.less",
    "chars": 349,
    "preview": "//栏目\n.column_header {\n  border-bottom: 1px solid #eee;\n  height: 36px;\n  line-height: 30px;\n  padding: 5px 10px 5px 0px;"
  },
  {
    "path": "src/style/Home.less",
    "chars": 290,
    "preview": ".home {\n  .ant-card-body {\n    padding: 10px 20px;\n  }\n  .movie_item {\n    width: 20%;\n  }\n  .carousel{\n    padding-bott"
  },
  {
    "path": "src/style/ListLoadMore.less",
    "chars": 146,
    "preview": ".list_load {\n  padding-top: 10px;\n  .ant-btn {\n    width: 100%;\n    text-align: center;\n  }\n  p {\n    text-align: center"
  },
  {
    "path": "src/style/Login.less",
    "chars": 493,
    "preview": ".login {\n  text-align: center;\n  line-height: 64px;\n  font-size: 14px;\n  color: #0c0c0c;\n  cursor: pointer;\n}\n\n.login_ic"
  },
  {
    "path": "src/style/MovieColumn.less",
    "chars": 94,
    "preview": ".movie_column {\n  .ant-row {\n    border-bottom: 1px solid #eee;\n    padding-bottom: 8px;\n  }\n}"
  },
  {
    "path": "src/style/MovieDetail.less",
    "chars": 1943,
    "preview": ".movie_detail {\n  .movie_intro {\n    font-size: 14px;\n  }\n  .movie_banner {\n    height: 350px;\n    background-image: url"
  },
  {
    "path": "src/style/MovieItem.less",
    "chars": 705,
    "preview": ".movie_item {\n  &> div{\n    margin: 0 5px;\n  }\n  .movie_img {\n    height: 280px;\n    img {\n      width: 100%;\n      heig"
  },
  {
    "path": "src/style/MovieMenu.less",
    "chars": 273,
    "preview": ".movie_menu {\n  border: 1px solid #eee;\n  margin-right: 10px;\n  border-radius: 10px;\n  .ant-anchor{\n    text-align: cent"
  },
  {
    "path": "src/style/Music.less",
    "chars": 1702,
    "preview": ".m-cvrlst {\n  margin: 20px 0 0 -42px;\n  li {\n    width: 180px;\n    height: 204px;\n    float: left;\n    display: inline-b"
  },
  {
    "path": "src/style/NewsList.less",
    "chars": 318,
    "preview": ".newsList {\n  padding-left: 10px;\n  ul > li {\n    padding-top: 5px;\n    border-bottom: 1px solid #eee;\n    overflow: hid"
  },
  {
    "path": "src/style/Pages.less",
    "chars": 91,
    "preview": ".Pages {\n  height: 24px;\n  line-height: 24px;\n  ul.ant-pagination {\n    float: right;\n  }\n}"
  },
  {
    "path": "src/style/Spot.less",
    "chars": 160,
    "preview": ".spot_news {\n  .carousel {\n    width: 300px;\n    height: 400px;\n    padding-left: 20px;\n    .slick-slide {\n      img {\n "
  },
  {
    "path": "src/style/TopList.less",
    "chars": 527,
    "preview": ".topList {\n  padding-left: 10px;\n  ul > li {\n    border-bottom: 1px solid #eee;\n    overflow: hidden;\n    text-overflow:"
  },
  {
    "path": "src/style/base.less",
    "chars": 5310,
    "preview": "/* CSS Document */\n\n/* css reset */\nbody, h1, h2, h3, h4, h5, h6, p, ul, ol, dl, dd, form, pre, input, textarea, select,"
  },
  {
    "path": "src/template/template.html",
    "chars": 140,
    "preview": "<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n    <meta charset=\"UTF-8\">\n    <title>简趣</title>\n</head>\n<body>\n<div id=\"app\"></"
  },
  {
    "path": "webpack.dev.config.js",
    "chars": 1632,
    "preview": "var webpack = require('webpack');\nvar path = require('path');\nvar ExtractTextPlugin = require(\"extract-text-webpack-plug"
  },
  {
    "path": "webpack.pub.config.js",
    "chars": 2578,
    "preview": "var webpack = require(\"webpack\");\nvar path = require('path');\nvar uglifyJsPlugin = webpack.optimize.UglifyJsPlugin;\nvar "
  }
]

// ... and 1 more files (download for full content)

About this extraction

This page contains the full source code of the jixianu/EasyFun GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 68 files (77.2 KB), approximately 24.4k tokens, and a symbol index with 69 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.

Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.

Copied to clipboard!