Full Code of hicoldcat/TimeCat for AI

master d5975543023f cached
61 files
93.8 KB
31.2k tokens
23 symbols
1 requests
Download .txt
Repository: hicoldcat/TimeCat
Branch: master
Commit: d5975543023f
Files: 61
Total size: 93.8 KB

Directory structure:
gitextract_np9uns0u/

├── .babelrc
├── .editorconfig
├── .gitignore
├── README.md
├── api/
│   ├── apiroutes.js
│   └── mockdata/
│       ├── daily.json
│       ├── detail.json
│       ├── essay.json
│       ├── home.json
│       ├── personal.json
│       ├── travels.json
│       └── vocality.json
├── build/
│   ├── build.js
│   ├── check-versions.js
│   ├── dev-client.js
│   ├── dev-server.js
│   ├── utils.js
│   ├── vue-loader.conf.js
│   ├── webpack.base.conf.js
│   ├── webpack.dev.conf.js
│   └── webpack.prod.conf.js
├── config/
│   ├── dev.env.js
│   ├── index.js
│   └── prod.env.js
├── index.html
├── package.json
├── src/
│   ├── App.vue
│   ├── assets/
│   │   └── less/
│   │       ├── icon.less
│   │       ├── index.less
│   │       └── mixin.less
│   ├── components/
│   │   ├── article/
│   │   │   └── Article.vue
│   │   ├── bottombar/
│   │   │   └── BottomBar.vue
│   │   ├── detailheader/
│   │   │   └── DetailHeader.vue
│   │   ├── header/
│   │   │   └── Header.vue
│   │   ├── info/
│   │   │   └── Info.vue
│   │   ├── infodetail/
│   │   │   └── InfoDetail.vue
│   │   ├── music/
│   │   │   └── Music.vue
│   │   ├── musicbar/
│   │   │   └── MusicBar.vue
│   │   ├── picbox/
│   │   │   └── PicBox.vue
│   │   ├── player/
│   │   │   └── Player.vue
│   │   ├── slidebar/
│   │   │   └── SlideBar.vue
│   │   ├── switchbutton/
│   │   │   └── SwitchButton.vue
│   │   └── trip/
│   │       └── Trip.vue
│   ├── main.js
│   ├── pages/
│   │   ├── choosetheme/
│   │   │   └── ChooseTheme.vue
│   │   ├── daily/
│   │   │   └── Daily.vue
│   │   ├── detail/
│   │   │   └── Detail.vue
│   │   ├── essay/
│   │   │   └── Essay.vue
│   │   ├── home/
│   │   │   └── Home.vue
│   │   ├── personal/
│   │   │   └── Personal.vue
│   │   ├── travels/
│   │   │   └── Travels.vue
│   │   └── vocality/
│   │       └── Vocality.vue
│   ├── router/
│   │   └── routes.js
│   └── store/
│       ├── actions.js
│       ├── getters.js
│       ├── index.js
│       ├── mutation-types.js
│       ├── mutations.js
│       └── state.js
└── static/
    ├── .gitkeep
    └── css/
        └── reset.css

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

================================================
FILE: .babelrc
================================================
{
  "presets": [
    ["es2015", { "modules": false }],
    "stage-2"
  ],
  "plugins": ["transform-runtime"],
  "comments": false,
  "env": {
    "test": {
      "plugins": [ "istanbul" ]
    }
  }
}


================================================
FILE: .editorconfig
================================================
root = true

[*]
charset = utf-8
indent_style = space
indent_size = 2
end_of_line = lf
insert_final_newline = true
trim_trailing_whitespace = true


================================================
FILE: .gitignore
================================================
.DS_Store
node_modules/
dist/
resource/
npm-debug.log

================================================
FILE: README.md
================================================
TimeCat
=======

> 【此处留白】 - 图片社交分享App

技术栈
------

前端:Vue2 + Vuex + Vue-Router2 + Axios + Webpack + ES6/7 + Less + ElementUI

传送门
------

如果你正在学习React,这里有一个关于React的[Demo](https://github.com/hicoldcat/CornerCat)。

项目安装
--------

```bash

# clone或者download项目
git clone https://github.com/hicoldcat/TimeCat.git

# 进入项目文件夹
cd TimeCat

# 安装依赖
npm install

```

项目运行
--------

```bash
# serve with hot reload at localhost:8080
npm run dev
```

项目编译打包
------------

```bash
# build for production with minification
npm run build

```

项目结构
--------

```
|-- api                            // 项目接口定义
|
|-- build                            // webpack配置文件
|
|-- config                           // 项目配置文件
|
|-- dist                            // 项目打包文件
|
|-- timecat                          // 上线项目文件,放在服务器即可正常访问
|
|-- screenshots                      // 项目截图
|
|-- src                              // 源码目录
|   |-- assets                       // 项目公共资源
|   |-- components                   // 组件库
|   |-- pages                        // 项目页面模块
|   |-- router                       // 路由文件
|   |-- service                      // Mock数据
|   |-- store                        // vuex的状态管理
|   |-- style                        // 各种样式文件
|   |-- App.vue                      // 页面入口文件
|   |-- main.js                      // 程序入口文件,加载各种公共组件
|
|-- static                          //一些静态资源,不会被webpack编译
|
|-- .babelrc                         // ES6语法编译配置
|-- .editorconfig                    // 代码编写规格
|-- .gitignore                       // 忽略的文件
|-- favicon.ico                      // 页面左上角小图标
|-- index.html                       // 入口html文件
|-- package.json                     // 项目及工具的依赖配置文件
|-- README.md                        // 说明

```

项目说明
--------

> 项目是做一个基于vue全家桶的移动端图片分享app的Demo

项目风格
--------

> 简约 文艺 清新

项目截图
--------

#### *【片刻留白】---每日分享模块[daily]*

![](https://github.com/hicoldcat/TimeCat/blob/master/screenshots/daily.jpg?raw=true)

#### *【回声留白】---音乐分享模块[vocality]*

![](https://github.com/hicoldcat/TimeCat/blob/master/screenshots/vocality.jpg?raw=true)

#### *【字符留白】---随笔分享模块[essay]*

![](https://github.com/hicoldcat/TimeCat/blob/master/screenshots/essay.jpg?raw=true)

#### *【半步留白】---游记分享模块[travels]*

![](https://github.com/hicoldcat/TimeCat/blob/master/screenshots/travels.jpg?raw=true)

贡献
----

> 本人前端小菜鸟一枚,如果有任何的问题,欢迎给我提issue
>
> 如果此项目对你有帮助,可以给个star哦


================================================
FILE: api/apiroutes.js
================================================
// Mock data by hicoldcat

var express = require('express')
var apiRoutes = express.Router();

var home = require('./mockdata/home.json');
var daily = require('./mockdata/daily.json');
var vocality = require('./mockdata/vocality.json');
var travels = require('./mockdata/travels.json');
var essay = require('./mockdata/essay.json');
var personal = require('./mockdata/personal.json');
var detail = require('./mockdata/detail.json');


apiRoutes.get('/home', function (req, res) {
	res.json(home);
});


apiRoutes.get('/daily', function (req, res) {
	res.json(daily);
});

apiRoutes.get('/vocality', function (req, res) {
	res.json(vocality);
});

apiRoutes.get('/travels', function (req, res) {
	res.json(travels);
});


apiRoutes.get('/essay', function (req, res) {
	res.json(essay);
});

apiRoutes.get('/personal', function (req, res) {
	res.json(personal);
});

apiRoutes.get('/detail', function (req, res) {
	res.json(detail);
});

module.exports = apiRoutes;


================================================
FILE: api/mockdata/daily.json
================================================
{
  "errno": 0,
  "data": [
    {
      "id":1001,
      "userid":"u9001",
      "nickname": "李留白",
      "avatar": "http://p1.wmpic.me/article/2017/03/06/1488780213_usvFXYIl.jpg",
      "pic": "http://p3.wmpic.me/article/2015/12/15/1450149335_QCivaWCX.jpg",
      "desc": "一花一世界,一鸟一天堂",
      "themeid": "info",
      "module": "daily",
      "createtime":"1475164800000"
    },
    {
      "id":1002,
      "userid":"u9002",
      "nickname": "扫地僧",
      "avatar": "http://p1.wmpic.me/article/2017/03/06/1488768546_bdCSPuMc_215x185.jpg",
      "pic": "http://p3.wmpic.me/article/2015/12/15/1450149335_WNRvtyWH.jpg",
      "desc": "执子之手,与子偕老",
      "themeid": "info",
      "module": "daily",
      "createtime":"1485914400000"
    },
    {
      "id":1003,
      "userid":"u9003",
      "nickname": "李留白",
      "avatar": "http://p2.wmpic.me/article/2017/03/03/1488509527_rGNZPsMi.jpg",
      "pic": "http://p3.wmpic.me/article/2017/03/07/1488868988_oeWjKIyl.jpg",
      "desc": "一花一世界,一鸟一天堂",
      "themeid": "info",
      "module": "daily",
      "createtime":"1490055600000"
    },
    {
      "id":1004,
      "userid":"u9004",
      "nickname": "李留白",
      "avatar": "http://p2.wmpic.me/article/2017/03/03/1488509527_gniRuexr.jpg",
      "pic": "http://p3.wmpic.me/article/2017/03/07/1488868988_vXAUAxGN.jpg",
      "desc": "一花一世界,一鸟一天堂",
      "themeid": "info",
      "module": "daily",
      "createtime":"1493055500000"
    },
    {
      "id":1005,
      "userid":"u9005",
      "nickname": "李留白",
      "avatar": "http://p3.wmpic.me/article/2017/03/01/1488338945_iJTjMZEi.jpg",
      "pic": "http://p3.wmpic.me/article/2017/02/17/1487312780_KLVpntpo.jpg",
      "desc": "一花一世界,一鸟一天堂",
      "themeid": "info",
      "module": "daily",
      "createtime":"1493355700000"
    },
    {
      "id":1006,
      "userid":"u9006",
      "nickname": "李留白",
      "avatar": "http://p3.wmpic.me/article/2017/03/01/1488338945_xCOozyoD.jpg",
      "pic": "http://p3.wmpic.me/article/2017/02/17/1487312780_NxltIlts.jpg",
      "desc": "一花一世界,一鸟一天堂",
      "themeid": "info",
      "module": "daily",
      "createtime":"1493155740000"
    },
    {
      "id":1007,
      "userid":"u9007",
      "nickname": "李留白",
      "avatar": "http://p1.wmpic.me/article/2017/02/28/1488270792_LaBnPAaR_215x185.jpg",
      "pic": "http://p3.wmpic.me/article/2017/02/17/1487312780_KWdvxsti.jpg",
      "desc": "一花一世界,一鸟一天堂",
      "themeid": "info",
      "module": "daily",
      "createtime":"1493355640000"
    },
    {
      "id":1008,
      "userid":"u9008",
      "nickname": "李留白",
      "avatar": "http://p2.wmpic.me/article/2017/02/24/1487902738_XdBlzdRu_215x185.jpg",
      "pic": "http://p2.wmpic.me/article/2017/02/17/1487295910_vbjpzzCe.jpg",
      "desc": "一花一世界,一鸟一天堂",
      "themeid": "info",
      "module": "daily",
      "createtime":"1423455640000"
    },
    {
      "id":1009,
      "userid":"u9009",
      "nickname": "李留白",
      "avatar": "http://p3.wmpic.me/article/2017/03/01/1488338945_yYFHhlst.jpg",
      "pic": "http://p2.wmpic.me/article/2017/02/17/1487311390_xttfRbPJ_215x185.jpg",
      "desc": "一花一世界,一鸟一天堂",
      "themeid": "info",
      "module": "daily",
      "createtime":"1423355450000"
    },
    {
      "id":1010,
      "userid":"u9010",
      "nickname": "李留白",
      "avatar": "http://p2.wmpic.me/article/2017/02/22/1487730637_qHiHIzxH_215x185.jpg",
      "pic": "http://p3.wmpic.me/article/2017/02/16/1487224457_xxmNBhjW_215x185.jpg",
      "desc": "一花一世界,一鸟一天堂",
      "themeid": "info",
      "module": "daily",
      "createtime":"1465354670000"
    }
  ]
}


================================================
FILE: api/mockdata/detail.json
================================================
{
  "errno": 0,
  "data": {
    "id":1001,
    "userid":"u9001",
    "nickname": "李留白",
    "avatar": "http://p1.wmpic.me/article/2017/03/06/1488780213_usvFXYIl.jpg",
    "pic": "http://p3.wmpic.me/article/2015/12/15/1450149335_QCivaWCX.jpg",
    "desc": "一花一世界,一鸟一天堂",
    "themeid": "info",
    "module": "daily",
    "createtime":"1475164800000",
    "followcount": 920,
    "startcount":56,
    "comments":[
      {
        "reviewerid":"u333",
        "revieweravatar":"",
        "comment":"很喜欢!"
      },
      {
        "reviewerid":"u343",
        "revieweravatar":"",
        "comment":"不错哦,很有感触。。。"
      }
    ]
  }
}


================================================
FILE: api/mockdata/essay.json
================================================
{
  "errno": 0,
  "data": [
    {
      "id":1007,
      "userid":"u9007",
      "nickname": "李留白",
      "avatar": "http://p1.wmpic.me/article/2017/02/28/1488270792_LaBnPAaR_215x185.jpg",
      "pic": "http://p3.wmpic.me/article/2017/02/17/1487312780_KWdvxsti.jpg",
      "themeid": "article",
      "module": "essay",
      "title":"将灵魂的虔诚,植入一朵莲荷",
      "content":"",
      "createtime":"1493355640000"
    },
    {
      "id":1008,
      "userid":"u9008",
      "nickname": "李留白",
      "avatar": "http://p2.wmpic.me/article/2017/02/24/1487902738_XdBlzdRu_215x185.jpg",
      "pic": "http://p2.wmpic.me/article/2017/02/17/1487295910_vbjpzzCe.jpg",
      "themeid": "article",
      "module": "essay",
      "title":"等一场春暖花香",
      "content":"",
      "createtime":"1423455640000"
    },
    {
      "id":1001,
      "userid":"u9001",
      "nickname": "李留白",
      "avatar": "http://p1.wmpic.me/article/2017/03/06/1488780213_usvFXYIl.jpg",
      "pic": "http://p3.wmpic.me/article/2015/12/15/1450149335_QCivaWCX.jpg",
      "themeid": "article",
      "module": "essay",
      "title":"关系再好,也要距离",
      "content":"",
      "createtime":"1475164800000"
    },
    {
      "id":1002,
      "userid":"u9002",
      "nickname": "扫地僧",
      "avatar": "http://p1.wmpic.me/article/2017/03/06/1488768546_bdCSPuMc_215x185.jpg",
      "pic": "http://p3.wmpic.me/article/2015/12/15/1450149335_WNRvtyWH.jpg",
      "themeid": "article",
      "module": "essay",
      "title":"读你,在春天里",
      "content":"",
      "createtime":"1485914400000"
    },
    {
      "id":1003,
      "userid":"u9003",
      "nickname": "李留白",
      "avatar": "http://p2.wmpic.me/article/2017/03/03/1488509527_rGNZPsMi.jpg",
      "pic": "http://p3.wmpic.me/article/2017/03/07/1488868988_oeWjKIyl.jpg",
      "themeid": "article",
      "module": "essay",
      "title":"原来,你也在这里",
      "content":"",
      "createtime":"1490055600000"
    },
    {
      "id":1004,
      "userid":"u9004",
      "nickname": "李留白",
      "avatar": "http://p2.wmpic.me/article/2017/03/03/1488509527_gniRuexr.jpg",
      "pic": "http://p3.wmpic.me/article/2017/03/07/1488868988_vXAUAxGN.jpg",
      "themeid": "article",
      "module": "essay",
      "title":"人活一世,随遇而安",
      "content":"",
      "createtime":"1493055500000"
    },
    {
      "id":1005,
      "userid":"u9005",
      "nickname": "李留白",
      "avatar": "http://p3.wmpic.me/article/2017/03/01/1488338945_iJTjMZEi.jpg",
      "pic": "http://p3.wmpic.me/article/2017/02/17/1487312780_KLVpntpo.jpg",
      "themeid": "article",
      "module": "essay",
      "title":"淙淙郎木寺",
      "content":"",
      "createtime":"1493355700000"
    },
    {
      "id":1006,
      "userid":"u9006",
      "nickname": "李留白",
      "avatar": "http://p3.wmpic.me/article/2017/03/01/1488338945_xCOozyoD.jpg",
      "pic": "http://p3.wmpic.me/article/2017/02/17/1487312780_NxltIlts.jpg",
      "themeid": "article",
      "module": "essay",
      "title":"香染尘埃,坐禅时光",
      "content":"",
      "createtime":"1493155740000"
    },
    {
      "id":1009,
      "userid":"u9009",
      "nickname": "李留白",
      "avatar": "http://p3.wmpic.me/article/2017/03/01/1488338945_yYFHhlst.jpg",
      "pic": "http://p2.wmpic.me/article/2017/02/17/1487311390_xttfRbPJ_215x185.jpg",
      "themeid": "article",
      "module": "essay",
      "title":"纵然桃红十里,也比不上你的美丽",
      "content":"",
      "createtime":"1423355450000"
    },
    {
      "id":1010,
      "userid":"u9010",
      "nickname": "李留白",
      "avatar": "http://p2.wmpic.me/article/2017/02/22/1487730637_qHiHIzxH_215x185.jpg",
      "pic": "http://p3.wmpic.me/article/2017/02/16/1487224457_xxmNBhjW_215x185.jpg",
      "themeid": "article",
      "module": "essay",
      "title":"书一笺优美的清韵,沐浴春心",
      "content":"",
      "createtime":"1465354670000"
    }
  ]
}


================================================
FILE: api/mockdata/home.json
================================================
{
  "errno": 0,
  "data": [
    {
      "id":1001,
      "userid":"u9001",
      "nickname": "李留白",
      "avatar": "http://p1.wmpic.me/article/2017/03/06/1488780213_usvFXYIl.jpg",
      "pic": "http://p3.wmpic.me/article/2015/12/15/1450149335_QCivaWCX.jpg",
      "desc": "一花一世界,一鸟一天堂",
      "themeid": "info",
      "module": "daily",
      "createtime":"1475164800000"
    },
    {
      "id":1002,
      "userid":"u9002",
      "nickname": "扫地僧",
      "avatar": "http://p1.wmpic.me/article/2017/03/06/1488768546_bdCSPuMc_215x185.jpg",
      "pic": "http://p3.wmpic.me/article/2015/12/15/1450149335_WNRvtyWH.jpg",
      "desc": "执子之手,与子偕老",
      "themeid": "info",
      "module": "daily",
      "createtime":"1485914400000"
    },
    {
      "id":1003,
      "userid":"u9003",
      "nickname": "李留白",
      "avatar": "http://p2.wmpic.me/article/2017/03/03/1488509527_rGNZPsMi.jpg",
      "pic": "http://p3.wmpic.me/article/2017/03/07/1488868988_oeWjKIyl.jpg",
      "desc": "一花一世界,一鸟一天堂",
      "themeid": "info",
      "module": "daily",
      "createtime":"1490055600000"
    },
    {
      "id":1004,
      "userid":"u9004",
      "nickname": "李留白",
      "avatar": "http://p2.wmpic.me/article/2017/03/03/1488509527_gniRuexr.jpg",
      "pic": "http://p3.wmpic.me/article/2017/03/07/1488868988_vXAUAxGN.jpg",
      "desc": "一花一世界,一鸟一天堂",
      "themeid": "info",
      "module": "daily",
      "createtime":"1493055500000"
    },
    {
      "id":1005,
      "userid":"u9005",
      "nickname": "李留白",
      "avatar": "http://p3.wmpic.me/article/2017/03/01/1488338945_iJTjMZEi.jpg",
      "pic": "http://p3.wmpic.me/article/2017/02/17/1487312780_KLVpntpo.jpg",
      "desc": "一花一世界,一鸟一天堂",
      "themeid": "info",
      "module": "daily",
      "createtime":"1493355700000"
    },
    {
      "id":1006,
      "userid":"u9006",
      "nickname": "李留白",
      "avatar": "http://p3.wmpic.me/article/2017/03/01/1488338945_xCOozyoD.jpg",
      "pic": "http://p3.wmpic.me/article/2017/02/17/1487312780_NxltIlts.jpg",
      "desc": "一花一世界,一鸟一天堂",
      "themeid": "info",
      "module": "daily",
      "createtime":"1493155740000"
    },
    {
      "id":1007,
      "userid":"u9007",
      "nickname": "李留白",
      "avatar": "http://p1.wmpic.me/article/2017/02/28/1488270792_LaBnPAaR_215x185.jpg",
      "pic": "http://p3.wmpic.me/article/2017/02/17/1487312780_KWdvxsti.jpg",
      "desc": "一花一世界,一鸟一天堂",
      "themeid": "info",
      "module": "daily",
      "createtime":"1493355640000"
    },
    {
      "id":1008,
      "userid":"u9008",
      "nickname": "李留白",
      "avatar": "http://p2.wmpic.me/article/2017/02/24/1487902738_XdBlzdRu_215x185.jpg",
      "pic": "http://p2.wmpic.me/article/2017/02/17/1487295910_vbjpzzCe.jpg",
      "desc": "一花一世界,一鸟一天堂",
      "themeid": "info",
      "module": "daily",
      "createtime":"1423455640000"
    },
    {
      "id":1009,
      "userid":"u9009",
      "nickname": "李留白",
      "avatar": "http://p3.wmpic.me/article/2017/03/01/1488338945_yYFHhlst.jpg",
      "pic": "http://p2.wmpic.me/article/2017/02/17/1487311390_xttfRbPJ_215x185.jpg",
      "desc": "一花一世界,一鸟一天堂",
      "themeid": "info",
      "module": "daily",
      "createtime":"1423355450000"
    },
    {
      "id":1010,
      "userid":"u9010",
      "nickname": "李留白",
      "avatar": "http://p2.wmpic.me/article/2017/02/22/1487730637_qHiHIzxH_215x185.jpg",
      "pic": "http://p3.wmpic.me/article/2017/02/16/1487224457_xxmNBhjW_215x185.jpg",
      "desc": "一花一世界,一鸟一天堂",
      "themeid": "info",
      "module": "daily",
      "createtime":"1465354670000"
    }
  ]
}


================================================
FILE: api/mockdata/personal.json
================================================
{
  "errno": 0,
  "data": {
    "userid":"u9001",
    "nickname": "李留白",
    "avatar": "http://p1.wmpic.me/article/2017/03/06/1488780213_usvFXYIl.jpg",
    "followcount": 920,
    "isfollow": false,
    "contentlist": [
      {
        "id":1001,
        "userid":"u9001",
        "nickname": "李留白",
        "avatar": "http://p1.wmpic.me/article/2017/03/06/1488780213_usvFXYIl.jpg",
        "pic": "http://p3.wmpic.me/article/2015/12/15/1450149335_QCivaWCX.jpg",
        "desc": "一花一世界,一鸟一天堂",
        "themeid": "info",
        "module": "daily",
        "createtime":"1475164800000"
      },
      {
        "id":1003,
        "userid":"u9001",
        "nickname": "李留白",
        "avatar": "http://p1.wmpic.me/article/2017/03/06/1488780213_usvFXYIl.jpg",
        "pic": "http://p3.wmpic.me/article/2017/03/07/1488868988_oeWjKIyl.jpg",
        "musicurl":"http://fs.open.kugou.com/886bae70fad3b51b29b69b0886c91c5d/58c10e40/G094/M03/1D/01/PpQEAFi6f4OAPYPSAE5cJ7mN9yk814.mp3",
        "imgurl":"http://singerimg.kugou.com/uploadpic/softhead/100/20170106/20170106171217388.jpg",
        "singer":"张碧晨",
        "songname":"时间有泪",
        "themeid": "music",
        "module": "vocality",
        "createtime":"1490055600000"
      },
      {
        "id":1007,
        "userid":"u9001",
        "nickname": "李留白",
        "avatar": "http://p1.wmpic.me/article/2017/03/06/1488780213_usvFXYIl.jpg",
        "pic": "http://p3.wmpic.me/article/2017/02/17/1487312780_KWdvxsti.jpg",
        "themeid": "article",
        "module": "essay",
        "title":"将灵魂的虔诚,植入一朵莲荷",
        "content":"",
        "createtime":"1493355640000"
      },
      {
        "id":1005,
        "userid":"u9001",
        "nickname": "李留白",
        "avatar": "http://p1.wmpic.me/article/2017/03/06/1488780213_usvFXYIl.jpg",
        "pic": "http://p3.wmpic.me/article/2017/02/17/1487312780_KLVpntpo.jpg",
        "themeid": "trip",
        "module": "travels",
        "destination":"山东",
        "title":"雄山灵水圣人——我和齐鲁情未了",
        "content":"",
        "createtime":"1493355700000"
      }
    ]
  }
}


================================================
FILE: api/mockdata/travels.json
================================================
{
  "errno": 0,
  "data": [
    {
      "id":1005,
      "userid":"u9005",
      "nickname": "李留白",
      "avatar": "http://p3.wmpic.me/article/2017/03/01/1488338945_iJTjMZEi.jpg",
      "pic": "http://p3.wmpic.me/article/2017/02/17/1487312780_KLVpntpo.jpg",
      "themeid": "trip",
      "module": "travels",
      "destination":"山东",
      "title":"雄山灵水圣人——我和齐鲁情未了",
      "content":"",
      "createtime":"1493355700000"
    },
    {
      "id":1006,
      "userid":"u9006",
      "nickname": "李留白",
      "avatar": "http://p3.wmpic.me/article/2017/03/01/1488338945_xCOozyoD.jpg",
      "pic": "http://p3.wmpic.me/article/2017/02/17/1487312780_NxltIlts.jpg",
      "themeid": "trip",
      "module": "travels",
      "destination":"蔚县",
      "title":"暖泉--记忆中年的味道",
      "content":"",
      "createtime":"1493155740000"
    },
    {
      "id":1001,
      "userid":"u9001",
      "nickname": "李留白",
      "avatar": "http://p1.wmpic.me/article/2017/03/06/1488780213_usvFXYIl.jpg",
      "pic": "http://p3.wmpic.me/article/2015/12/15/1450149335_QCivaWCX.jpg",
      "themeid": "trip",
      "module": "travels",
      "destination":"牙买加",
      "title":"文青在路上之浅尝牙买加",
      "content":"",
      "createtime":"1475164800000"
    },
    {
      "id":1002,
      "userid":"u9002",
      "nickname": "扫地僧",
      "avatar": "http://p1.wmpic.me/article/2017/03/06/1488768546_bdCSPuMc_215x185.jpg",
      "pic": "http://p3.wmpic.me/article/2015/12/15/1450149335_WNRvtyWH.jpg",
      "themeid": "trip",
      "module": "travels",
      "destination":"塞尔维亚",
      "title":"小小的城,可爱的人——塞尔维亚十日行",
      "content":"",
      "createtime":"1485914400000"
    },
    {
      "id":1003,
      "userid":"u9003",
      "nickname": "李留白",
      "avatar": "http://p2.wmpic.me/article/2017/03/03/1488509527_rGNZPsMi.jpg",
      "pic": "http://p3.wmpic.me/article/2017/03/07/1488868988_oeWjKIyl.jpg",
      "themeid": "trip",
      "module": "travels",
      "destination":"黄姚古镇",
      "title":"我画中的八月黄姚-美丽桂林",
      "content":"",
      "createtime":"1490055600000"
    },
    {
      "id":1004,
      "userid":"u9004",
      "nickname": "李留白",
      "avatar": "http://p2.wmpic.me/article/2017/03/03/1488509527_gniRuexr.jpg",
      "pic": "http://p3.wmpic.me/article/2017/03/07/1488868988_vXAUAxGN.jpg",
      "themeid": "trip",
      "module": "travels",
      "destination":"色达",
      "title":"川西色达,感受信仰的力量",
      "content":"",
      "createtime":"1493055500000"
    },
    {
      "id":1007,
      "userid":"u9007",
      "nickname": "李留白",
      "avatar": "http://p1.wmpic.me/article/2017/02/28/1488270792_LaBnPAaR_215x185.jpg",
      "pic": "http://p3.wmpic.me/article/2017/02/17/1487312780_KWdvxsti.jpg",
      "themeid": "trip",
      "module": "travels",
      "destination":"北疆",
      "title":"醉美秋色,意外的北疆之旅",
      "content":"",
      "createtime":"1493355640000"
    },
    {
      "id":1008,
      "userid":"u9008",
      "nickname": "李留白",
      "avatar": "http://p2.wmpic.me/article/2017/02/24/1487902738_XdBlzdRu_215x185.jpg",
      "pic": "http://p2.wmpic.me/article/2017/02/17/1487295910_vbjpzzCe.jpg",
      "themeid": "trip",
      "module": "travels",
      "destination":"诸暨",
      "title":"江南风韵,吴越柔情——“小雁荡”之旅",
      "content":"",
      "createtime":"1423455640000"
    },
    {
      "id":1009,
      "userid":"u9009",
      "nickname": "李留白",
      "avatar": "http://p3.wmpic.me/article/2017/03/01/1488338945_yYFHhlst.jpg",
      "pic": "http://p2.wmpic.me/article/2017/02/17/1487311390_xttfRbPJ_215x185.jpg",
      "themeid": "trip",
      "module": "travels",
      "destination":"夏威夷",
      "title":"夏威夷的两周间",
      "content":"",
      "createtime":"1423355450000"
      },
    {
      "id":1010,
      "userid":"u9010",
      "nickname": "李留白",
      "avatar": "http://p2.wmpic.me/article/2017/02/22/1487730637_qHiHIzxH_215x185.jpg",
      "pic": "http://p3.wmpic.me/article/2017/02/16/1487224457_xxmNBhjW_215x185.jpg",
      "themeid": "trip",
      "module": "travels",
      "destination":"比利时",
      "title":"中灰度<梦>境",
      "content":"",
      "createtime":"1465354670000"
    }
  ]
}


================================================
FILE: api/mockdata/vocality.json
================================================
{
  "errno": 0,
  "data": [
    {
      "id":1003,
      "userid":"u9003",
      "nickname": "李留白",
      "avatar": "http://p2.wmpic.me/article/2017/03/03/1488509527_rGNZPsMi.jpg",
      "pic": "http://p3.wmpic.me/article/2017/03/07/1488868988_oeWjKIyl.jpg",
      "musicurl":"http://fs.web.kugou.com/5861fa7bc75848e1c25dc2dd3992b925/58ec7282/G100/M07/05/0F/pA0DAFjrZL-AIwSDAEw1sU-h2zs456.mp3",
      "imgurl":"http://singerimg.kugou.com/uploadpic/softhead/100/20170106/20170106171217388.jpg",
      "singer":"张碧晨",
      "songname":"时间有泪",
      "themeid": "music",
      "module": "vocality",
      "createtime":"1490055600000"
    },
    {
      "id":1004,
      "userid":"u9004",
      "nickname": "李留白",
      "avatar": "http://p2.wmpic.me/article/2017/03/03/1488509527_gniRuexr.jpg",
      "pic": "http://p3.wmpic.me/article/2017/03/07/1488868988_vXAUAxGN.jpg",
      "musicurl":"http://fs.web.kugou.com/e281277712237ea6bc3499537c58e4db/58ec7b6b/G098/M02/05/18/QpQEAFjpCxaAf0HvADE9Yam3Ii0483.mp3",
      "imgurl":"http://singerimg.kugou.com/uploadpic/softhead/100/20160530/20160530190530186681.jpg",
      "singer":"林志炫",
      "songname":"御龙铭千古",
      "themeid": "music",
      "module": "vocality",
      "createtime":"1493055500000"
    },
    {
      "id":1001,
      "userid":"u9001",
      "nickname": "李留白",
      "avatar": "http://p1.wmpic.me/article/2017/03/06/1488780213_usvFXYIl.jpg",
      "pic": "http://p3.wmpic.me/article/2015/12/15/1450149335_QCivaWCX.jpg",
      "musicurl":"http://fs.web.kugou.com/926581decfc5edfa2f096c051262fbc6/58ec8894/G095/M03/08/05/nw0DAFjrP4CAHLIHAEAp2xcEy1Y549.mp3",
      "singer":"汪峰",
      "imgurl":"http://singerimg.kugou.com/uploadpic/softhead/100/20160426/20160426113231414.jpg",
      "songname":"春天里",
      "themeid": "music",
      "module": "vocality",
      "createtime":"1475164800000"
    },
    {
      "id":1002,
      "userid":"u9002",
      "nickname": "扫地僧",
      "avatar": "http://p1.wmpic.me/article/2017/03/06/1488768546_bdCSPuMc_215x185.jpg",
      "pic": "http://p3.wmpic.me/article/2015/12/15/1450149335_WNRvtyWH.jpg",
      "musicurl":"http://fs.web.kugou.com/749aacc989055b2e8e6c55df111fa1a6/58ec87d7/G009/M03/13/01/qYYBAFUGA1yAad3PAD60rYvYluM565.mp3",
      "imgurl":"http://singerimg.kugou.com/uploadpic/softhead/100/20161019/20161019112334107316.jpg",
      "singer":"李健",
      "songname":"异乡人",
      "themeid": "music",
      "module": "vocality",
      "createtime":"1485914400000"
    },
    {
      "id":1005,
      "userid":"u9005",
      "nickname": "李留白",
      "avatar": "http://p3.wmpic.me/article/2017/03/01/1488338945_iJTjMZEi.jpg",
      "pic": "http://p3.wmpic.me/article/2017/02/17/1487312780_KLVpntpo.jpg",
      "musicurl":"http://fs.web.kugou.com/b66ab1469dff97bbc6d3ce47adfe68e8/58ec8549/G017/M02/0E/13/sYYBAFU-37OAIOb1AExmrKAXGks355.mp3",
      "imgurl":"http://singerimg.kugou.com/uploadpic/softhead/100/20160612/20160612182117928150.jpg",
      "singer":"狮子合唱团",
      "songname":"听不到",
      "themeid": "music",
      "module": "vocality",
      "createtime":"1493355700000"
    },
    {
      "id":1006,
      "userid":"u9006",
      "nickname": "李留白",
      "avatar": "http://p3.wmpic.me/article/2017/03/01/1488338945_xCOozyoD.jpg",
      "pic": "http://p3.wmpic.me/article/2017/02/17/1487312780_NxltIlts.jpg",
      "musicurl":"http://fs.web.kugou.com/bdf1e4d00a0886c5c518630787f02dd8/58ec8312/G004/M05/0E/1F/RA0DAFUIQ76AEBjdAEAbtXxbJ-8509.mp3",
      "imgurl":"http://singerimg.kugou.com/uploadpic/softhead/100/20170111/20170111104600449.jpg",
      "singer":"张杰",
      "songname":"突然想爱你",
      "themeid": "music",
      "module": "vocality",
      "createtime":"1493155740000"
    },
    {
      "id":1007,
      "userid":"u9007",
      "nickname": "李留白",
      "avatar": "http://p1.wmpic.me/article/2017/02/28/1488270792_LaBnPAaR_215x185.jpg",
      "pic": "http://p3.wmpic.me/article/2017/02/17/1487312780_KWdvxsti.jpg",
      "musicurl":"http://fs.web.kugou.com/b006b4f852277232535add4bc991bf43/58ec802d/G010/M06/1D/19/Sg0DAFT-or2ATCrnAD5UFkMtfIc093.mp3",
      "imgurl":"http://singerimg.kugou.com/uploadpic/softhead/100/20170109/20170109113028943.jpg",
      "singer":"林忆莲",
      "songname":"蓝莲花",
      "themeid": "music",
      "module": "vocality",
      "createtime":"1493355640000"
    },
    {
      "id":1008,
      "userid":"u9008",
      "nickname": "李留白",
      "avatar": "http://p2.wmpic.me/article/2017/02/24/1487902738_XdBlzdRu_215x185.jpg",
      "pic": "http://p2.wmpic.me/article/2017/02/17/1487295910_vbjpzzCe.jpg",
      "musicurl":"http://fs.web.kugou.com/48ac9675365729b8698bc20609be8fd5/58ec8bd0/G076/M05/0D/19/LJQEAFgus_KAYhqoAEvriAx1-oU493.mp3",
      "imgurl":"http://singerimg.kugou.com/uploadpic/softhead/100/20170110/20170110174433260.jpg",
      "singer":"迪玛希",
      "songname":"Daididau",
      "themeid": "music",
      "module": "vocality",
      "createtime":"1423455640000"
    },
    {
      "id":1009,
      "userid":"u9009",
      "nickname": "李留白",
      "avatar": "http://p3.wmpic.me/article/2017/03/01/1488338945_yYFHhlst.jpg",
      "pic": "http://p2.wmpic.me/article/2017/02/17/1487311390_xttfRbPJ_215x185.jpg",
      "musicurl":"http://fs.web.kugou.com/d0c03431e188e8f0fea18db79ff0a32b/58ec8bc7/G006/M08/1D/11/poYBAFT7leyAKNokAEvKUZ7OdkE931.mp3",
      "imgurl":"http://singerimg.kugou.com/uploadpic/softhead/100/20170110/20170110180849472.jpg",
      "singer":"袁娅维",
      "songname":"Golden",
      "themeid": "music",
      "module": "vocality",
      "createtime":"1423355450000"
    },
    {
      "id":1010,
      "userid":"u9010",
      "nickname": "李留白",
      "avatar": "http://p2.wmpic.me/article/2017/02/22/1487730637_qHiHIzxH_215x185.jpg",
      "pic": "http://p3.wmpic.me/article/2017/02/16/1487224457_xxmNBhjW_215x185.jpg",
      "musicurl":"http://fs.web.kugou.com/a966f8a16c42f0f4130959fb3613aa3b/58ec8c05/G001/M01/0D/19/QQ0DAFSO1ZWAH7LDADwtteZZTJ8250.mp3",
      "imgurl":"http://singerimg.kugou.com/uploadpic/softhead/100/20170205/20170205183509587.jpg",
      "singer":"赵雷",
      "songname":"成都",
      "themeid": "music",
      "module": "vocality",
      "createtime":"1465354670000"
    }
  ]
}


================================================
FILE: build/build.js
================================================
// https://github.com/shelljs/shelljs
require('./check-versions')()

process.env.NODE_ENV = 'production'

var ora = require('ora')
var path = require('path')
var chalk = require('chalk')
var shell = require('shelljs')
var webpack = require('webpack')
var config = require('../config')
var webpackConfig = require('./webpack.prod.conf')

var spinner = ora('building for production...')
spinner.start()

var assetsPath = path.join(config.build.assetsRoot, config.build.assetsSubDirectory)
shell.rm('-rf', assetsPath)
shell.mkdir('-p', assetsPath)
shell.config.silent = true
shell.cp('-R', 'static/*', assetsPath)
shell.config.silent = false

webpack(webpackConfig, function (err, stats) {
  spinner.stop()
  if (err) throw err
  process.stdout.write(stats.toString({
    colors: true,
    modules: false,
    children: false,
    chunks: false,
    chunkModules: false
  }) + '\n\n')

  console.log(chalk.cyan('  Build complete.\n'))
  console.log(chalk.yellow(
    '  Tip: built files are meant to be served over an HTTP server.\n' +
    '  Opening index.html over file:// won\'t work.\n'
  ))
})


================================================
FILE: build/check-versions.js
================================================
var chalk = require('chalk')
var semver = require('semver')
var packageConfig = require('../package.json')

function exec (cmd) {
  return require('child_process').execSync(cmd).toString().trim()
}

var versionRequirements = [
  {
    name: 'node',
    currentVersion: semver.clean(process.version),
    versionRequirement: packageConfig.engines.node
  },
  {
    name: 'npm',
    currentVersion: exec('npm --version'),
    versionRequirement: packageConfig.engines.npm
  }
]

module.exports = function () {
  var warnings = []
  for (var i = 0; i < versionRequirements.length; i++) {
    var mod = versionRequirements[i]
    if (!semver.satisfies(mod.currentVersion, mod.versionRequirement)) {
      warnings.push(mod.name + ': ' +
        chalk.red(mod.currentVersion) + ' should be ' +
        chalk.green(mod.versionRequirement)
      )
    }
  }

  if (warnings.length) {
    console.log('')
    console.log(chalk.yellow('To use this template, you must update following to modules:'))
    console.log()
    for (var i = 0; i < warnings.length; i++) {
      var warning = warnings[i]
      console.log('  ' + warning)
    }
    console.log()
    process.exit(1)
  }
}


================================================
FILE: build/dev-client.js
================================================
/* eslint-disable */
require('eventsource-polyfill')
var hotClient = require('webpack-hot-middleware/client?noInfo=true&reload=true')

hotClient.subscribe(function (event) {
  if (event.action === 'reload') {
    window.location.reload()
  }
})


================================================
FILE: build/dev-server.js
================================================
require('./check-versions')()

var config = require('../config')
if (!process.env.NODE_ENV) {
  process.env.NODE_ENV = JSON.parse(config.dev.env.NODE_ENV)
}

var opn = require('opn')
var path = require('path')
var express = require('express')
var webpack = require('webpack')
var proxyMiddleware = require('http-proxy-middleware')
var webpackConfig = require('./webpack.dev.conf')

// default port where dev server listens for incoming traffic
var port = process.env.PORT || config.dev.port
// automatically open browser, if not set will be false
var autoOpenBrowser = !!config.dev.autoOpenBrowser
// Define HTTP proxies to your custom API backend
// https://github.com/chimurai/http-proxy-middleware
var proxyTable = config.dev.proxyTable

var app = express()

var apiRoutes = require('../api/apiroutes.js')

app.use('/api', apiRoutes);

var compiler = webpack(webpackConfig)

var devMiddleware = require('webpack-dev-middleware')(compiler, {
  publicPath: webpackConfig.output.publicPath,
  quiet: true
})

var hotMiddleware = require('webpack-hot-middleware')(compiler, {
  log: () => {}
})
// force page reload when html-webpack-plugin template changes
compiler.plugin('compilation', function (compilation) {
  compilation.plugin('html-webpack-plugin-after-emit', function (data, cb) {
    hotMiddleware.publish({ action: 'reload' })
    cb()
  })
})

// proxy api requests
Object.keys(proxyTable).forEach(function (context) {
  var options = proxyTable[context]
  if (typeof options === 'string') {
    options = { target: options }
  }
  app.use(proxyMiddleware(options.filter || context, options))
})

// handle fallback for HTML5 history API
app.use(require('connect-history-api-fallback')())

// serve webpack bundle output
app.use(devMiddleware)

// enable hot-reload and state-preserving
// compilation error display
app.use(hotMiddleware)

// serve pure static assets
var staticPath = path.posix.join(config.dev.assetsPublicPath, config.dev.assetsSubDirectory)
app.use(staticPath, express.static('./static'))

var uri = 'http://localhost:' + port

devMiddleware.waitUntilValid(function () {
  console.log('> Listening at ' + uri + '\n')
})

module.exports = app.listen(port, function (err) {
  if (err) {
    console.log(err)
    return
  }

  // when env is testing, don't need open it
  if (autoOpenBrowser && process.env.NODE_ENV !== 'testing') {
    opn(uri)
  }
})


================================================
FILE: build/utils.js
================================================
var path = require('path')
var config = require('../config')
var ExtractTextPlugin = require('extract-text-webpack-plugin')

exports.assetsPath = function (_path) {
  var assetsSubDirectory = process.env.NODE_ENV === 'production'
    ? config.build.assetsSubDirectory
    : config.dev.assetsSubDirectory
  return path.posix.join(assetsSubDirectory, _path)
}

exports.cssLoaders = function (options) {
  options = options || {}
  // generate loader string to be used with extract text plugin
  function generateLoaders (loaders) {
    var sourceLoader = loaders.map(function (loader) {
      var extraParamChar
      if (/\?/.test(loader)) {
        loader = loader.replace(/\?/, '-loader?')
        extraParamChar = '&'
      } else {
        loader = loader + '-loader'
        extraParamChar = '?'
      }
      return loader + (options.sourceMap ? extraParamChar + 'sourceMap' : '')
    }).join('!')

    // Extract CSS when that option is specified
    // (which is the case during production build)
    if (options.extract) {
      return ExtractTextPlugin.extract({
        loader: sourceLoader,
        fallbackLoader: 'vue-style-loader'
      })
    } else {
      return ['vue-style-loader', sourceLoader].join('!')
    }
  }

  // http://vuejs.github.io/vue-loader/en/configurations/extract-css.html
  return {
    css: generateLoaders(['css']),
    postcss: generateLoaders(['css']),
    less: generateLoaders(['css', 'less']),
    sass: generateLoaders(['css', 'sass?indentedSyntax']),
    scss: generateLoaders(['css', 'sass']),
    stylus: generateLoaders(['css', 'stylus']),
    styl: generateLoaders(['css', 'stylus'])
  }
}

// Generate loaders for standalone style files (outside of .vue)
exports.styleLoaders = function (options) {
  var output = []
  var loaders = exports.cssLoaders(options)
  for (var extension in loaders) {
    var loader = loaders[extension]
    output.push({
      test: new RegExp('\\.' + extension + '$'),
      loader: loader
    })
  }
  return output
}


================================================
FILE: build/vue-loader.conf.js
================================================
var utils = require('./utils')
var config = require('../config')
var isProduction = process.env.NODE_ENV === 'production'

module.exports = {
  loaders: utils.cssLoaders({
    sourceMap: isProduction
      ? config.build.productionSourceMap
      : config.dev.cssSourceMap,
    extract: isProduction
  }),
  postcss: [
    require('autoprefixer')({
      browsers: ['last 2 versions']
    })
  ]
}


================================================
FILE: build/webpack.base.conf.js
================================================
var path = require('path')
var utils = require('./utils')
var config = require('../config')
var vueLoaderConfig = require('./vue-loader.conf')
var eslintFriendlyFormatter = require('eslint-friendly-formatter')

function resolve (dir) {
  return path.join(__dirname, '..', dir)
}

module.exports = {
  entry: {
    app: './src/main.js'
  },
  output: {
    path: config.build.assetsRoot,
    filename: '[name].js',
    publicPath: process.env.NODE_ENV === 'production'
      ? config.build.assetsPublicPath
      : config.dev.assetsPublicPath
  },
  resolve: {
    extensions: ['.js', '.vue', '.json'],
    modules: [
      resolve('src'),
      resolve('node_modules')
    ],
    alias: {
      'vue$': 'vue/dist/vue.common.js',
      'src': resolve('src'),
      'assets': resolve('src/assets'),
      'components': resolve('src/components'),
      'pages': resolve('src/pages')
    }
  },
  module: {
    rules: [
      {
        test: /\.vue$/,
        loader: 'vue-loader',
        options: vueLoaderConfig
      },
      {
        test: /\.js$/,
        loader: 'babel-loader',
        include: [resolve('src'), resolve('test')]
      },
      {
        test: /\.json$/,
        loader: 'json-loader'
      },
      {
        test: /\.(png|jpe?g|gif|svg)(\?.*)?$/,
        loader: 'url-loader',
        query: {
          limit: 10000,
          name: utils.assetsPath('img/[name].[hash:7].[ext]')
        }
      },
      {
        test: /\.(woff2?|eot|ttf|otf)(\?.*)?$/,
        loader: 'url-loader',
        query: {
          limit: 10000,
          name: utils.assetsPath('fonts/[name].[hash:7].[ext]')
        }
      }
    ]
  }
}


================================================
FILE: build/webpack.dev.conf.js
================================================
var utils = require('./utils')
var webpack = require('webpack')
var config = require('../config')
var merge = require('webpack-merge')
var baseWebpackConfig = require('./webpack.base.conf')
var HtmlWebpackPlugin = require('html-webpack-plugin')
var FriendlyErrorsPlugin = require('friendly-errors-webpack-plugin')

// add hot-reload related code to entry chunks
Object.keys(baseWebpackConfig.entry).forEach(function (name) {
  baseWebpackConfig.entry[name] = ['./build/dev-client'].concat(baseWebpackConfig.entry[name])
})

module.exports = merge(baseWebpackConfig, {
  module: {
    rules: utils.styleLoaders({ sourceMap: config.dev.cssSourceMap })
  },
  // cheap-module-eval-source-map is faster for development
  devtool: '#cheap-module-eval-source-map',
  plugins: [
    new webpack.DefinePlugin({
      'process.env': config.dev.env
    }),
    // https://github.com/glenjamin/webpack-hot-middleware#installation--usage
    new webpack.HotModuleReplacementPlugin(),
    new webpack.NoEmitOnErrorsPlugin(),
    // https://github.com/ampedandwired/html-webpack-plugin
    new HtmlWebpackPlugin({
      filename: 'index.html',
      template: 'index.html',
      inject: true
    }),
    new FriendlyErrorsPlugin()
  ]
})


================================================
FILE: build/webpack.prod.conf.js
================================================
var path = require('path')
var utils = require('./utils')
var webpack = require('webpack')
var config = require('../config')
var merge = require('webpack-merge')
var baseWebpackConfig = require('./webpack.base.conf')
var HtmlWebpackPlugin = require('html-webpack-plugin')
var ExtractTextPlugin = require('extract-text-webpack-plugin')
var env = config.build.env

var webpackConfig = merge(baseWebpackConfig, {
  module: {
    rules: utils.styleLoaders({
      sourceMap: config.build.productionSourceMap,
      extract: true
    })
  },
  devtool: config.build.productionSourceMap ? '#source-map' : false,
  output: {
    path: config.build.assetsRoot,
    filename: utils.assetsPath('js/[name].[chunkhash].js'),
    chunkFilename: utils.assetsPath('js/[id].[chunkhash].js')
  },
  plugins: [
    // http://vuejs.github.io/vue-loader/en/workflow/production.html
    new webpack.DefinePlugin({
      'process.env': env
    }),
    new webpack.optimize.UglifyJsPlugin({
      compress: {
        warnings: false
      }
    }),
    // extract css into its own file
    new ExtractTextPlugin(utils.assetsPath('css/[name].[contenthash].css')),
    // generate dist index.html with correct asset hash for caching.
    // you can customize output by editing /index.html
    // see https://github.com/ampedandwired/html-webpack-plugin
    new HtmlWebpackPlugin({
      filename: config.build.index,
      template: 'index.html',
      inject: true,
      minify: {
        removeComments: true,
        collapseWhitespace: true,
        removeAttributeQuotes: true
        // more options:
        // https://github.com/kangax/html-minifier#options-quick-reference
      },
      // necessary to consistently work with multiple chunks via CommonsChunkPlugin
      chunksSortMode: 'dependency'
    }),
    // split vendor js into its own file
    new webpack.optimize.CommonsChunkPlugin({
      name: 'vendor',
      minChunks: function (module, count) {
        // any required modules inside node_modules are extracted to vendor
        return (
          module.resource &&
          /\.js$/.test(module.resource) &&
          module.resource.indexOf(
            path.join(__dirname, '../node_modules')
          ) === 0
        )
      }
    }),
    // extract webpack runtime and module manifest to its own file in order to
    // prevent vendor hash from being updated whenever app bundle is updated
    new webpack.optimize.CommonsChunkPlugin({
      name: 'manifest',
      chunks: ['vendor']
    })
  ]
})

if (config.build.productionGzip) {
  var CompressionWebpackPlugin = require('compression-webpack-plugin')

  webpackConfig.plugins.push(
    new CompressionWebpackPlugin({
      asset: '[path].gz[query]',
      algorithm: 'gzip',
      test: new RegExp(
        '\\.(' +
        config.build.productionGzipExtensions.join('|') +
        ')$'
      ),
      threshold: 10240,
      minRatio: 0.8
    })
  )
}

if (config.build.bundleAnalyzerReport) {
  var BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin
  webpackConfig.plugins.push(new BundleAnalyzerPlugin())
}

module.exports = webpackConfig


================================================
FILE: config/dev.env.js
================================================
var merge = require('webpack-merge')
var prodEnv = require('./prod.env')

module.exports = merge(prodEnv, {
  NODE_ENV: '"development"'
})


================================================
FILE: config/index.js
================================================
// see http://vuejs-templates.github.io/webpack for documentation.
var path = require('path')

module.exports = {
  build: {
    env: require('./prod.env'),
    index: path.resolve(__dirname, '../dist/index.html'),
    assetsRoot: path.resolve(__dirname, '../dist'),
    assetsSubDirectory: 'static',
    assetsPublicPath: '/',
    productionSourceMap: true,
    // Gzip off by default as many popular static hosts such as
    // Surge or Netlify already gzip all static assets for you.
    // Before setting to `true`, make sure to:
    // npm install --save-dev compression-webpack-plugin
    productionGzip: false,
    productionGzipExtensions: ['js', 'css'],
    // Run the build command with an extra argument to
    // View the bundle analyzer report after build finishes:
    // `npm run build --report`
    // Set to `true` or `false` to always turn it on or off
    bundleAnalyzerReport: process.env.npm_config_report
  },
  dev: {
    env: require('./dev.env'),
    port: 8090,
    autoOpenBrowser: true,
    assetsSubDirectory: 'static',
    assetsPublicPath: '/',
    proxyTable: {},
    // CSS Sourcemaps off by default because relative paths are "buggy"
    // with this option, according to the CSS-Loader README
    // (https://github.com/webpack/css-loader#sourcemaps)
    // In our experience, they generally work as expected,
    // just be aware of this issue when enabling this option.
    cssSourceMap: false
  }
}


================================================
FILE: config/prod.env.js
================================================
module.exports = {
  NODE_ENV: '"production"'
}


================================================
FILE: index.html
================================================
<!DOCTYPE html>
<html>

<head>
	<meta charset="utf-8">
	<title>timecat</title>
	<meta name="viewport" content="width=device-width,initial-scale=1.0,maximum-scale=1.0,minimum-scale=1.0,user-scalable=no">
	<link rel="stylesheet" href="./static/css/reset.css">
</head>

<body>
	<div id="app"></div>
</body>

</html>


================================================
FILE: package.json
================================================
{
  "name": "timecat",
  "version": "1.0.0",
  "description": "时光留白-图片分享App",
  "author": "hicoldcat <1351290389@qq.com>",
  "private": true,
  "scripts": {
    "dev": "node build/dev-server.js",
    "build": "node build/build.js"
  },
  "dependencies": {
    "axios": "^0.15.3",
    "element-ui": "^1.2.5",
    "vue": "^2.1.10",
    "vue-router": "^2.2.0",
    "vuex": "^2.1.1"
  },
  "devDependencies": {
    "autoprefixer": "^6.7.2",
    "babel-core": "^6.22.1",
    "babel-loader": "^6.2.10",
    "babel-plugin-transform-runtime": "^6.22.0",
    "babel-preset-es2015": "^6.22.0",
    "babel-preset-stage-2": "^6.22.0",
    "babel-register": "^6.22.0",
    "chalk": "^1.1.3",
    "connect-history-api-fallback": "^1.3.0",
    "css-loader": "^0.26.1",
    "eslint-friendly-formatter": "^2.0.7",
    "eventsource-polyfill": "^0.9.6",
    "express": "^4.14.1",
    "extract-text-webpack-plugin": "^2.0.0-rc.2",
    "file-loader": "^0.10.0",
    "friendly-errors-webpack-plugin": "^1.1.3",
    "function-bind": "^1.1.0",
    "html-webpack-plugin": "^2.28.0",
    "http-proxy-middleware": "^0.17.3",
    "json-loader": "^0.5.4",
    "less": "^2.7.2",
    "less-loader": "^2.2.3",
    "opn": "^4.0.2",
    "ora": "^1.1.0",
    "semver": "^5.3.0",
    "shelljs": "^0.7.6",
    "url-loader": "^0.5.7",
    "vue-loader": "^10.3.0",
    "vue-style-loader": "^2.0.0",
    "vue-template-compiler": "^2.1.10",
    "webpack": "^2.2.1",
    "webpack-bundle-analyzer": "^2.2.1",
    "webpack-dev-middleware": "^1.10.0",
    "webpack-hot-middleware": "^2.16.1",
    "webpack-merge": "^2.6.1"
  },
  "engines": {
    "node": ">= 4.0.0",
    "npm": ">= 3.0.0"
  }
}


================================================
FILE: src/App.vue
================================================
<template>
	<div class="app">
		<v-header v-show="!isDetailHeader"></v-header>
		<detail-header :nickname="detailHeaderNickName"  v-show="isDetailHeader"></detail-header>
		<router-view class="content"></router-view>
		<slide-bar></slide-bar>
	</div>
</template>

<script>
import { mapGetters, mapActions } from 'vuex'

import Header from 'components/header/Header.vue'
import DetailHeader from 'components/detailheader/DetailHeader.vue'
import SlideBar from 'components/slidebar/SlideBar.vue'

	export default {
		data () {
			return {
				nickname: ''
			}
		},
		computed: mapGetters({
			isDetailHeader: 'isDetailHeader',
			detailHeaderNickName: 'detailHeaderNickName'
	  }),
		components: {
	    "v-header": Header,
			"slide-bar": SlideBar,
			"detail-header": DetailHeader,
	  }
	}
</script>

<style lang="less">
	.app{
		height: 100%;
	}
	.content{
		margin-top: 60px;
	}
</style>


================================================
FILE: src/assets/less/icon.less
================================================
@font-face {
  font-family: 'icon';
  src:  url('../fonts/icon.eot?g68udz');
  src:  url('../fonts/icon.eot?g68udz#iefix') format('embedded-opentype'),
    url('../fonts/icon.ttf?g68udz') format('truetype'),
    url('../fonts/icon.woff?g68udz') format('woff'),
    url('../fonts/icon.svg?g68udz#icon') format('svg');
  font-weight: normal;
  font-style: normal;
}

[class^="icon-"], [class*=" icon-"] {
  /* use !important to prevent issues with browser extensions that change fonts */
  font-family: 'icon' !important;
  speak: none;
  font-style: normal;
  font-weight: normal;
  font-variant: normal;
  text-transform: none;
  line-height: 1;

  /* Better Font Rendering =========== */
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
}

.icon-diamond:before {
  content: "\e90e";
}
.icon-diamond_article:before {
  content: "\e910";
}
.icon-diamond_commend:before {
  content: "\e912";
}
.icon-diamond_fm:before {
  content: "\e913";
}
.icon-diamond_list:before {
  content: "\e914";
}
.icon-diamond_music:before {
  content: "\e915";
}
.icon-diamond_newmusic:before {
  content: "\e916";
}
.icon-diamond_play:before {
  content: "\e917";
}
.icon-diamond_playcard:before {
  content: "\e918";
}
.icon-diamond_share:before {
  content: "\e919";
}
.icon-fourhouse:before {
  content: "\e90c";
}
.icon-add_circle:before {
  content: "\e901";
}
.icon-arrow_lift:before {
  content: "\e902";
}
.icon-check_circle:before {
  content: "\e903";
}
.icon-close:before {
  content: "\e904";
}
.icon-favorite:before {
  content: "\e906";
}
.icon-keyboard_arrow_right:before {
  content: "\e907";
}
.icon-remove_circle_outline:before {
  content: "\e908";
}
.icon-shopping_cart:before {
  content: "\e909";
}
.icon-thumb_down:before {
  content: "\e90a";
}
.icon-thumb_up:before {
  content: "\e90b";
}
.icon-home:before {
  content: "\e900";
}
.icon-home2:before {
  content: "\e91a";
}
.icon-home3:before {
  content: "\e91b";
}
.icon-office:before {
  content: "\e91c";
}
.icon-newspaper:before {
  content: "\e91d";
}
.icon-pencil:before {
  content: "\e905";
}
.icon-pencil2:before {
  content: "\e91e";
}
.icon-quill:before {
  content: "\e91f";
}
.icon-pen:before {
  content: "\e920";
}
.icon-blog:before {
  content: "\e921";
}
.icon-eyedropper:before {
  content: "\e922";
}
.icon-droplet:before {
  content: "\e923";
}
.icon-paint-format:before {
  content: "\e924";
}
.icon-image:before {
  content: "\e90d";
}
.icon-images:before {
  content: "\e925";
}
.icon-camera:before {
  content: "\e90f";
}
.icon-headphones:before {
  content: "\e926";
}
.icon-music:before {
  content: "\e911";
}
.icon-play:before {
  content: "\e927";
}
.icon-film:before {
  content: "\e928";
}
.icon-video-camera:before {
  content: "\e929";
}
.icon-dice:before {
  content: "\e92a";
}
.icon-pacman:before {
  content: "\e92b";
}
.icon-spades:before {
  content: "\e92c";
}
.icon-clubs:before {
  content: "\e92d";
}
.icon-connection:before {
  content: "\e92e";
}
.icon-book:before {
  content: "\e92f";
}
.icon-books:before {
  content: "\e930";
}
.icon-library:before {
  content: "\e931";
}
.icon-file-text:before {
  content: "\e932";
}
.icon-profile:before {
  content: "\e933";
}
.icon-file-text2:before {
  content: "\e934";
}
.icon-barcode:before {
  content: "\e937";
}
.icon-qrcode:before {
  content: "\e938";
}
.icon-cart:before {
  content: "\e93a";
}
.icon-coin-dollar:before {
  content: "\e93b";
}
.icon-credit-card:before {
  content: "\e93f";
}
.icon-phone:before {
  content: "\e942";
}
.icon-phone-hang-up:before {
  content: "\e943";
}
.icon-address-book:before {
  content: "\e944";
}
.icon-location:before {
  content: "\e947";
}
.icon-location2:before {
  content: "\e948";
}
.icon-compass:before {
  content: "\e949";
}
.icon-compass2:before {
  content: "\e94a";
}
.icon-history:before {
  content: "\e94d";
}
.icon-clock:before {
  content: "\e94e";
}
.icon-clock2:before {
  content: "\e94f";
}
.icon-alarm:before {
  content: "\e950";
}
.icon-stopwatch:before {
  content: "\e952";
}
.icon-calendar:before {
  content: "\e953";
}
.icon-display:before {
  content: "\e956";
}
.icon-mobile:before {
  content: "\e958";
}
.icon-mobile2:before {
  content: "\e959";
}
.icon-tv:before {
  content: "\e95b";
}
.icon-floppy-disk:before {
  content: "\e962";
}
.icon-database:before {
  content: "\e964";
}
.icon-undo:before {
  content: "\e965";
}
.icon-redo:before {
  content: "\e966";
}
.icon-undo2:before {
  content: "\e967";
}
.icon-redo2:before {
  content: "\e968";
}
.icon-forward:before {
  content: "\e969";
}
.icon-reply:before {
  content: "\e96a";
}
.icon-bubbles:before {
  content: "\e96c";
}
.icon-bubbles2:before {
  content: "\e96d";
}
.icon-bubble2:before {
  content: "\e96e";
}
.icon-bubbles3:before {
  content: "\e96f";
}
.icon-user:before {
  content: "\e971";
}
.icon-users:before {
  content: "\e972";
}
.icon-user-plus:before {
  content: "\e973";
}
.icon-user-minus:before {
  content: "\e974";
}
.icon-user-check:before {
  content: "\e975";
}
.icon-user-tie:before {
  content: "\e976";
}
.icon-quotes-left:before {
  content: "\e977";
}
.icon-quotes-right:before {
  content: "\e978";
}
.icon-hour-glass:before {
  content: "\e979";
}
.icon-spinner:before {
  content: "\e97a";
}
.icon-spinner2:before {
  content: "\e97b";
}
.icon-spinner3:before {
  content: "\e97c";
}
.icon-spinner4:before {
  content: "\e97d";
}
.icon-spinner5:before {
  content: "\e97e";
}
.icon-spinner6:before {
  content: "\e97f";
}
.icon-spinner7:before {
  content: "\e980";
}
.icon-spinner9:before {
  content: "\e982";
}
.icon-spinner10:before {
  content: "\e983";
}
.icon-spinner11:before {
  content: "\e984";
}
.icon-search:before {
  content: "\e986";
}
.icon-zoom-in:before {
  content: "\e987";
}
.icon-zoom-out:before {
  content: "\e988";
}
.icon-enlarge:before {
  content: "\e989";
}
.icon-shrink:before {
  content: "\e98a";
}
.icon-enlarge2:before {
  content: "\e98b";
}
.icon-shrink2:before {
  content: "\e98c";
}
.icon-key:before {
  content: "\e98d";
}
.icon-key2:before {
  content: "\e98e";
}
.icon-lock:before {
  content: "\e98f";
}
.icon-unlocked:before {
  content: "\e990";
}
.icon-wrench:before {
  content: "\e991";
}
.icon-equalizer:before {
  content: "\e992";
}
.icon-equalizer2:before {
  content: "\e993";
}
.icon-cog:before {
  content: "\e994";
}
.icon-cogs:before {
  content: "\e995";
}
.icon-hammer:before {
  content: "\e996";
}
.icon-magic-wand:before {
  content: "\e997";
}
.icon-aid-kit:before {
  content: "\e998";
}
.icon-stats-dots:before {
  content: "\e99b";
}
.icon-stats-bars:before {
  content: "\e99c";
}
.icon-stats-bars2:before {
  content: "\e99d";
}
.icon-trophy:before {
  content: "\e99e";
}
.icon-gift:before {
  content: "\e99f";
}
.icon-list-numbered:before {
  content: "\e9b9";
}
.icon-list:before {
  content: "\e9ba";
}
.icon-list2:before {
  content: "\e9bb";
}
.icon-tree:before {
  content: "\e9bc";
}
.icon-menu:before {
  content: "\e9bd";
}
.icon-menu2:before {
  content: "\e9be";
}
.icon-menu3:before {
  content: "\e9bf";
}
.icon-download2:before {
  content: "\e9c5";
}
.icon-upload2:before {
  content: "\e9c6";
}
.icon-download3:before {
  content: "\e9c7";
}
.icon-upload3:before {
  content: "\e9c8";
}
.icon-sphere:before {
  content: "\e9c9";
}
.icon-earth:before {
  content: "\e9ca";
}
.icon-link:before {
  content: "\e9cb";
}
.icon-flag:before {
  content: "\e9cc";
}
.icon-attachment:before {
  content: "\e9cd";
}
.icon-eye:before {
  content: "\e9ce";
}
.icon-eye-plus:before {
  content: "\e9cf";
}
.icon-eye-minus:before {
  content: "\e9d0";
}
.icon-eye-blocked:before {
  content: "\e9d1";
}
.icon-bookmark:before {
  content: "\e9d2";
}
.icon-bookmarks:before {
  content: "\e9d3";
}
.icon-sun:before {
  content: "\e9d4";
}
.icon-contrast:before {
  content: "\e9d5";
}
.icon-brightness-contrast:before {
  content: "\e9d6";
}
.icon-star-empty:before {
  content: "\e9d7";
}
.icon-star-half:before {
  content: "\e9d8";
}
.icon-star-full:before {
  content: "\e9d9";
}
.icon-heart:before {
  content: "\e9da";
}
.icon-heart-broken:before {
  content: "\e9db";
}
.icon-plus:before {
  content: "\ea0a";
}
.icon-minus:before {
  content: "\ea0b";
}
.icon-play3:before {
  content: "\ea1c";
}
.icon-pause2:before {
  content: "\ea1d";
}
.icon-stop2:before {
  content: "\ea1e";
}
.icon-backward2:before {
  content: "\ea1f";
}
.icon-forward3:before {
  content: "\ea20";
}
.icon-first:before {
  content: "\ea21";
}
.icon-last:before {
  content: "\ea22";
}
.icon-previous2:before {
  content: "\ea23";
}
.icon-next2:before {
  content: "\ea24";
}
.icon-eject:before {
  content: "\ea25";
}
.icon-volume-high:before {
  content: "\ea26";
}
.icon-volume-medium:before {
  content: "\ea27";
}
.icon-volume-low:before {
  content: "\ea28";
}
.icon-volume-mute:before {
  content: "\ea29";
}
.icon-volume-mute2:before {
  content: "\ea2a";
}
.icon-volume-increase:before {
  content: "\ea2b";
}
.icon-volume-decrease:before {
  content: "\ea2c";
}
.icon-loop2:before {
  content: "\ea2e";
}
.icon-checkbox-checked:before {
  content: "\ea52";
}
.icon-checkbox-unchecked:before {
  content: "\ea53";
}
.icon-radio-checked:before {
  content: "\ea54";
}
.icon-radio-checked2:before {
  content: "\ea55";
}
.icon-radio-unchecked:before {
  content: "\ea56";
}
.icon-section:before {
  content: "\ea76";
}
.icon-paragraph-left:before {
  content: "\ea77";
}
.icon-paragraph-center:before {
  content: "\ea78";
}
.icon-paragraph-right:before {
  content: "\ea79";
}
.icon-paragraph-justify:before {
  content: "\ea7a";
}
.icon-indent-increase:before {
  content: "\ea7b";
}
.icon-indent-decrease:before {
  content: "\ea7c";
}
.icon-share:before {
  content: "\ea7d";
}
.icon-embed:before {
  content: "\ea7f";
}
.icon-embed2:before {
  content: "\ea80";
}
.icon-terminal:before {
  content: "\ea81";
}
.icon-share2:before {
  content: "\ea82";
}
.icon-mail:before {
  content: "\ea83";
}
.icon-mail2:before {
  content: "\ea84";
}
.icon-mail4:before {
  content: "\ea86";
}
.icon-google:before {
  content: "\ea88";
}
.icon-google-drive:before {
  content: "\ea8f";
}
.icon-instagram:before {
  content: "\ea92";
}
.icon-telegram:before {
  content: "\ea95";
}
.icon-sina-weibo:before {
  content: "\ea9a";
}
.icon-flickr:before {
  content: "\eaa3";
}
.icon-flickr2:before {
  content: "\eaa4";
}
.icon-github:before {
  content: "\eab0";
}
.icon-delicious:before {
  content: "\eacd";
}


================================================
FILE: src/assets/less/index.less
================================================
@import "./icon.less";


================================================
FILE: src/assets/less/mixin.less
================================================
@baseBoxBackground:#fff;//盒子背景


================================================
FILE: src/components/article/Article.vue
================================================
<template>
  <div class="article">
    <div class="box">
      <pic-box :src="article.pic"></pic-box>
      <div class="title">{{'「'+article.title+'」'}}</div>
      <bottom-bar :nickname="article.nickname" :avatar="article.avatar" :time="article.time" :userid="article.userid"></bottom-bar>
    </div>
  </div>
</template>

<script>
import PicBox from 'components/picbox/PicBox'
import BottomBar from 'components/bottombar/BottomBar'


export default {
  props: {
    article: {
      type: Object
    }
  },
  components: {
    "bottom-bar": BottomBar,
    "pic-box": PicBox
  }
}
</script>

<style lang="less">
@baseBackgroundColor:#fff;

.article {
    position: relative;
    width: 100%;
    background-color: #fff;

    .box {
        position: relative;
        width: 90%;
        background-color: @baseBackgroundColor;
        margin: 0 auto;
        // border: 1px solid #d1dbe5;
        margin: 0 auto;
        // box-shadow:0 2px 4px 0 rgba(0,0,0,.12), 0 0 6px 0 rgba(0,0,0,.04);
        box-shadow: 0 0 30px -7px rgba(0,0,0,.3);
        padding: 5px 0;
        border-radius:4px;

        .title {
          font-size: 16px;
          font-weight: 400;
          font-family: fangzheng;
          margin:3%;
          padding: 5% 0;
          width: 80%;
          overflow: hidden;
          white-space: nowrap;
          text-overflow: ellipsis;
        }

    }
}
</style>


================================================
FILE: src/components/bottombar/BottomBar.vue
================================================
<template>
  <div class="bottom">
    <div class="time">
      <div class="day">
        Feb.02
      </div>
      <div class="year">
        2017
      </div>
      <div class="plus">+</div>
    </div>
    <div class="owner" @click="goPersonalPages(userid,nickname)">
      <div class="avatar">
        <img :src="avatarUrl" alt="" @error="setErrorAvatar">
      </div>
      <div class="name">
        {{nickname}}
      </div>
    </div>
  </div>
</template>

<script>
export default {
  props: {
    time: {
      type: String
    },
    avatar: {
      type: String
    },
    nickname: {
      type: String
    },
    userid: {
      type: String
    }
  },
  data () {
    return {
      avatarUrl: this.avatar
    }
  },
  methods: {
    goPersonalPages (uid,nickname) {
      if (this.$route.name !== 'personal'){
        if (uid && nickname) {
          this.$store.dispatch('goPersonalPages',{userId:uid})
          this.$store.dispatch('toggleheader',{nickname:nickname})
        }
      }
    },
    setErrorAvatar () {
      this.$nextTick(function () {
        let errorImgUrl = require('../../assets/image/img_error_avatar.png')
        this.avatarUrl = errorImgUrl
     })
    }
  }
}
</script>

<style lang="less">
@font-face {
  font-family: 'fangzheng';
  src:  url('../../../static/fonts/fangzheng.ttf');
  font-weight: normal;
  font-style: normal;
}

  .bottom{
    margin: 3%;
    display: flex;
    justify-content: space-between;
    align-items: flex-end;

    .owner {
      flex: 0 0 20%;
      display: inline-flex;
      flex-direction: column;
      align-items: center;
      vertical-align: bottom;

      .avatar img{
        border-radius: 50%;
        width: 40px;
        height: 40px;
        margin: 0 auto;
      }

      .name {
        line-height: 40px;
        height: 40px;
        font-size: 16px;
        text-align: center;
        font-family: fangzheng;
        align-self: center;
      }
    }

    .time {
      flex: 0 0 20%;
      display: inline-block;
      border: 1px solid #B7B7B7;
      color: #B7B7B7;
      padding: 2px;
      width: 20%;
      height: 82px;
      line-height: 20px;

      .plus{
        font-size: 20px;
        margin-left: 2px;
      }
    }
  }
</style>


================================================
FILE: src/components/detailheader/DetailHeader.vue
================================================
<template lang="html">
  <header class="detailheader">
    <div class="menu" @click="goBack">
      <i class=" icon-arrow_lift"></i>
    </div>
    <div class="nickname">
      <h1>{{nickname}}</h1>
    </div>
    <div class="share" @click="sharePerson">
      <i class="icon-share2"></i>
    </div>
  </header>
</template>

<script>
import VueRouter from '../../router/routes.js'
import { mapGetters, mapActions } from 'vuex'

export default {
  props: {
    nickname: {
      type: String
    }
  },
  methods: {
    goBack () {
      VueRouter.go(-1)
      this.$store.dispatch('toggleheader')
    },
    sharePerson () {
      alert("分享功能待完善!")
    }
  }
}
</script>

<style lang="less">
@header-height:46px;
@icon-font-size:22px;
@title-font-size: 18px;
@baseBorderColor:#3B3B3B;

.detailheader {
  position: fixed;
  display: flex;
  width: 100%;
  height: @header-height;
  background: #fff;
  text-align: center;
  line-height: @header-height;
  box-shadow: 0 2px 10px #D8D8D8;
  top:0;
  left: 0;
  z-index: 10;
  .menu {
    flex: 0 0 @header-height;
    font-size: @icon-font-size;
  }
  .nickname {
    flex: 1;
    font-size: @title-font-size;
  }
  .share {
    flex: 0 0 @header-height;
    font-size: @icon-font-size;
  }

}
</style>


================================================
FILE: src/components/header/Header.vue
================================================
<template>
  <header class="heade">
    <div class="menu" @click="toggleSlideBar">
      <i class="icon-diamond"></i>
    </div>
    <div class="title">
      <h1>{{headertitle}}</h1>
    </div>
    <div class="write" @click="goChooseThemePage">
      <i class="icon-quill"></i>
    </div>
  </header>
</template>

<script>
import VueRouter from '../../router/routes.js'
import { mapGetters, mapActions } from 'vuex'

export default {
  computed: mapGetters({
    headertitle: 'headerTitle',
  }),
  methods: {
    toggleSlideBar () {
      this.$store.dispatch('toggleSlideBar')
    },
    goChooseThemePage () {
      // VueRouter.push({ path: '/choosetheme' })
    }
  }
}
</script>

<style lang="less">
  @header-height:46px;
  @icon-font-size:22px;
  @title-font-size: 18px;
  @baseBorderColor:#3B3B3B;

  .heade {
    position: fixed;
    display: flex;
    width: 100%;
    height: @header-height;
    background: #fff;
    text-align: center;
    line-height: @header-height;
    box-shadow: 0 2px 10px #D8D8D8;
    top:0;
    left: 0;
    z-index: 10;
    .menu {
      flex: 0 0 @header-height;
      font-size: @icon-font-size;
    }
    .title {
      flex: 1;
      font-size: @title-font-size;
    }
    .write {
      flex: 0 0 @header-height;
      font-size: @icon-font-size;
    }

  }
</style>


================================================
FILE: src/components/info/Info.vue
================================================
<template>
<div class="info">
  <div class="box">
    <pic-box :src="info.pic" :id="info.id" :nickname="info.nickname"></pic-box>
    <div class="desc" @click="goDetailPage(info)">
      {{info.desc}}
    </div>
    <bottom-bar :nickname="info.nickname" :avatar="info.avatar" :time="info.time" :userid="info.userid"></bottom-bar>
  </div>
</div>
</template>

<script>
import BottomBar from 'components/bottombar/BottomBar'
import PicBox from 'components/picbox/PicBox'

export default {
  props: {
    info: {
      type: Object
    }
  },
  components: {
    "bottom-bar": BottomBar,
    "pic-box":PicBox
  },
  methods: {
    goDetailPage: function (info) {
        this.$store.dispatch('goDetailPage',{id:info.id})
        this.$store.dispatch('toggleheader',{nickname:info.nickname})
    }
  }
}
</script>

<style lang="less">
@baseBackgroundColor:#fff;
@baseBorderColor:#3B3B3B;

.info {
    position: relative;
    width: 100%;
    background-color: #fff;

    .box {
        position: relative;
        width: 90%;
        background-color: @baseBackgroundColor;
        margin: 0 auto;
        // border: 1px solid #d1dbe5;
        margin: 0 auto;
        // box-shadow:0 2px 4px 0 rgba(0,0,0,.12), 0 0 6px 0 rgba(0,0,0,.04);
        box-shadow: 0 0 30px -7px rgba(0,0,0,.3);
        padding: 5px 0;
        border-radius:4px;

        .desc {
          font-size: 16px;
          font-weight: 400;
          font-family: fangzheng;
          margin:3%;
          padding: 5% 0;
          width: 80%;
        }

    }
}
</style>


================================================
FILE: src/components/infodetail/InfoDetail.vue
================================================
<template>
  <div class="info-detail">
    <div class="img-box">
      <img :src="info.pic" alt="">
    </div>

    <div class="content-box"><span>{{info.desc}}</span></div>

    <div class="author-box">
      <span class="text">by</span>
      <span class="nickname">{{info.nickname}}</span>
    </div>

    <div class="love" @click="toggleLove">
      <div class="love-icon">
        <img src="../../assets/image/heart_select.png" alt="" v-if="isLove">
        <img src="../../assets/image/heart_unselect.png" alt="" v-else>
      </div>
      <div class="lovecount">{{lovecount}}</div>
    </div>

  </div>
</template>

<script>

import { mapGetters } from 'vuex'

export default {
  props: {
    info: {
      type: Object
    }
  },
  computed: mapGetters({
    isLove: 'isLove',
    lovecount:'lovecount'
  }),
  components: {
  },
  methods: {
    toggleLove: function () {
      this.$store.dispatch('toggleLove')
    }
  }
}
</script>

<style lang="less">
  .info-detail{
    display: flex;
    justify-content: center;
    align-items: center;
    flex-direction: column;
    font-family: fangzheng;


    .img-box{
      width: 94%;
      margin: 3%;

      img{
        width: 100%;
      }
    }

    .content-box{
      width: 80%;
      margin: 3% auto;
      text-align:left;

      span{
        border-bottom: 1px solid #000;
        line-height: 2rem;
        padding: 5px 0;
      }

    }

    .author-box{
      width: 94%;
      margin: 3% ;
      text-align: right;

      .text{
        color: #7b7b7b;
        font-size: .9rem;
      }

      .nickname{
        font-size: 1rem;
      }
    }

    .love{
      width: 80%;
      text-align: left;
      display: flex;

      .love-icon{
        display: inline-flex;
        justify-content: center;
        align-items: center;
        margin-right: .5rem;

        img{
          width: 1.5rem;
          height: 1.5rem;
        }
      }
      .lovecount{
        display: inline-flex;
        justify-content: center;
        align-items: center;
      }




    }
  }
</style>


================================================
FILE: src/components/music/Music.vue
================================================
<template>
  <div class="music">
    <div class="box">
      <pic-box :src="music.pic"></pic-box>
      <music-bar :musicurl="music.musicurl" :imgurl="music.imgurl" :singer="music.singer" :songname="music.songname" ></music-bar>
      <bottom-bar :nickname="music.nickname" :avatar="music.avatar" :time="music.time" :userid="music.userid"></bottom-bar>
    </div>
  </div>
</template>

<script>
import BottomBar from 'components/bottombar/BottomBar'
import MusicBar from 'components/musicbar/MusicBar'
import PicBox from 'components/picbox/PicBox'

export default {
  props: {
    music: {
      type: Object
    }
  },
  components: {
    "bottom-bar": BottomBar,
    "music-bar": MusicBar,
    "pic-box": PicBox
  }
}
</script>

<style lang="less">
@baseBackgroundColor:#fff;
@baseBorderColor:#d1dbe5;

.music {
  position: relative;
  width: 100%;
  background-color: #fff;


  .box {
    position: relative;
    width: 90%;
    background-color: @baseBackgroundColor;
    // border: 1px solid #d1dbe5;
    margin: 0 auto;
    // box-shadow:0 2px 4px 0 rgba(0,0,0,.12), 0 0 6px 0 rgba(0,0,0,.04);
    box-shadow: 0 0 30px -7px rgba(0,0,0,.3);
    padding: 5px 0;
    border-radius:4px;
  }
}
</style>


================================================
FILE: src/components/musicbar/MusicBar.vue
================================================
<template>
  <div class="musicbar">
    <div class="musicbar-container">
      <div class="left">
        <img :src="imgurl" alt="">
      </div>
      <div class="center">
        <div class="songname">{{songname}}</div>
        <div class="singer">{{singer}}</div>
      </div>
      <div class="right" @click="togglePlayerStatus(musicurl)">
        <i class="icon-play3"></i>
      </div>
    </div>
  </div>
</template>

<script>
export default {
  props: {
    musicurl: {
      type: String
    },
    imgurl: {
      type: String
    },
    singer: {
      type: String
    },
    songname: {
      type: String
    }
  },
  methods: {
    togglePlayerStatus: function (url) {
      this.$store.dispatch('togglePlayerStatus',{currentPlayerUrl:url})
    }
  }
}
</script>

<style lang="less">
  .musicbar {
    margin: 3%;

    .musicbar-container {
      padding: 2px;
      display: flex;
      position: relative;
      border: 1px solid #d1dbe5;

      .left {
        display: inline-block;
        flex: 0 0 40px;

        img {
          width: 40px;
          height: 40px;
        }
      }

      .center {
        display: inline-block;
        flex: 0 0 auto;
        font-family: fangzheng;
        margin-left: 10px;

        .songname {
          height: 25px;
          line-height: 25px;
          font-size: 16px;
        }

        .singer {
          height: 15px;
          line-height: 15px;
          font-size: 12px;
        }
      }

      .right {
        position: absolute;
        right: 0;
        bottom: 0;
        display: inline-block;
        font-size: 30px;
        line-height: 42px;
        height: 42px;
        vertical-align: middle;
        opacity:0.5;
      }

    }

  }
</style>


================================================
FILE: src/components/picbox/PicBox.vue
================================================
<template>
  <div class="pic" @click="goDetailPage(id,nickname)">
    <img :src="imgsrc" alt="" @error="setErrorImg">
  </div>
</template>

<script>
import { mapGetters, mapActions } from 'vuex'
export default {
  props: {
    src: {
      type: String
    },
    id: {
      type: Number
    },
    nickname: {
      type: String
    }
  },
  data () {
    return {
      imgsrc:this.src
    }
  },
  methods: {
    setErrorImg () {
      this.$nextTick(function () {
        let errorImgUrl = require('../../assets/image/img_error_bg.jpg')
        this.imgsrc = errorImgUrl
     })
   },
   goDetailPage (id,nickname) {
     if (id && nickname) {
       this.$store.dispatch('goDetailPage',{id:id})
       this.$store.dispatch('toggleheader',{nickname:nickname})
     }
   }
  }
}
</script>

<style lang="less">
  .pic {
    width: 94%;
    margin: 3%;

    img{
     width: 100%;
   }
  }
</style>


================================================
FILE: src/components/player/Player.vue
================================================
<template lang="html">
  <div class="player">
    <audio :src="currentPlayerUrl" autoplay="autoplay" controls="controls" ref="audiopleyer" v-show="isAudioPlay"></audio>
  </div>
</template>

<script>
import { mapGetters, mapActions } from 'vuex'

export default {
  computed: {
    ...mapGetters({
      isAudioPlay: 'isAudioPlay'
    }),
    currentPlayerUrl: function ( ) {
      if (this.$refs.audiopleyer) {
        this.$refs.audiopleyer.load()
      }
      return this.$store.getters.currentPlayerUrl
    }
  }
}
</script>

<style lang="less">
  .player{
    width: 100%;
    position: fixed;
    z-index: 10;
    bottom: 0;
    display: flex;
    justify-content: center;
    align-items: center;

    audio {
      width: 90%;
      border: 1px solid #000;
    }
  }
</style>


================================================
FILE: src/components/slidebar/SlideBar.vue
================================================
<template lang="html">
  <div class="slidebar" v-if="isSlideBarShow">
    <el-row class="container">
      <el-col :span="16" class="left" @click="toggleSlideBar">
        <div class="useravatar">
          <div class="avatar">
            <img :src="personalInfo.avatar" alt="" @error="setErrorAvatar" ref="sliderbaravatar">
          </div>
          <div class="name">
            {{personalInfo.nickname}}
          </div>
        </div>
        <el-menu class="el-menu-vertical-demo" @select="handleSelect">
          <el-menu-item index="1"><i class="icon-user"></i><div class="navtext">个人</div></el-menu-item>
          <el-menu-item index="2"><i class="icon-eye"></i><div class="navtext">关注</div></el-menu-item>
          <el-menu-item index="3"><i class="icon-bubbles3"></i><div class="navtext">消息</div></el-menu-item>
          <el-menu-item index="4"><i class="icon-cog"></i><div class="navtext">设置</div></el-menu-item>
        </el-menu>
      </el-col>
      <el-col :span="8" class="right" ><div @click="toggleSlideBar" class="rightEvent"></div></el-col>
    </el-row>
  </div>
</template>

<script>
import { mapGetters, mapState } from 'vuex'

export default {
  computed: {
    ...mapState({
      personalInfo: 'personalInfo'
    }),
    ...mapGetters({
	    isSlideBarShow: 'isSlideBarShow',
	  }),
  },
  methods: {
    toggleSlideBar () {
      this.$store.dispatch('toggleSlideBar')
    },
    handleSelect (data) {
      let index = parseInt(data)
      switch (index) {
        case 1:
          if (this.personalInfo.uid && this.personalInfo.nickname){
            this.$store.dispatch('goPersonalPages',{userId:this.personalInfo.uid})
            this.$store.dispatch('toggleheader',{nickname:this.personalInfo.nickname})
            this.$store.dispatch('toggleSlideBar')
          }
          break;
        default:

      }
    },
    setErrorAvatar () {
      this.$nextTick(function () {
        let errorImgUrl = require('../../assets/image/img_error_avatar.png')
        this.$refs.sliderbaravatar.src = errorImgUrl
     })
    }
  }
}
</script>

<style lang="less">
  @font-face {
    font-family: 'fangzheng';
    src:  url('../../../static/fonts/fangzheng.ttf');
    font-weight: normal;
    font-style: normal;
  }

  .slidebar {
    position: fixed;
    left: 0;
    top: 0;
    width: 100%;
    height: 100%;
    z-index: 50;
    font-family: fangzheng;
    animation: slidetoright .5s;
    -moz-animation: slidetoright .5s;	/* Firefox */
    -webkit-animation: slidetoright .5s;	/* Safari 和 Chrome */
    -o-animation: slidetoright .5s;

    .container{
      height: 100%;

      .left{
        height: 100%;
        background-color: #252525;

        .useravatar{
          display: flex;
          vertical-align: middle;
          align-items: center;
          flex-direction: column;
          margin: 20% 0 10% 0;

          img{
            border-radius:50%;
            width: 100px;
            height: 100px;
            margin: 0 auto;
            border: 2px solid #404040;
          }

          .name {
            font-size: 20px;
            color: #fff;
            margin: 5% 0;
          }
        }

        .el-menu{
          background-color: #252525;

          .el-menu-item{
            color: white;
            display: flex;
            align-items: center;
            justify-content: center;
            border-bottom: 1px solid #404040;
            color: #707070;

            i {
              flex: 0 0 5% ;
            }
            .navtext {
              flex: 0 0 50%;
              text-align: center;
            }
          }
          .el-menu-item:hover {
            background-color: #252525;
            color: #fff;
          }
        }
      }

      .right{
        opacity: 0.6;
        height: 100%;
        background-color: #808080;
        z-index: 100;

        .rightEvent {
          height: 100%;
        }
      }
    }
  }

  @keyframes slidetoright{
    from {width: 0%;}
    to {width: 100%;}
  }

  @-moz-keyframes slidetoright{
    from {width: 0%;}
    to {width: 100%;}
  }

  @-webkit-keyframes slidetoright {
    from {width: 0%;}
    to {width: 100%;}
  }

  @-o-keyframes slidetoright{
    from {width: 0%;}
    to {width: 100%;}
  }

</style>


================================================
FILE: src/components/switchbutton/SwitchButton.vue
================================================
<template lang="html">
  <div class="switchbutton">
    <div class="button" @click="goNextPage"><i class="icon-loop2" ref="iconLoop"></i></div>
  </div>
</template>

<script>
export default {
  methods: {
    goNextPage () {
      this.$store.dispatch('updatePage')
      // this.$refs.iconLoop.style.transform = 'rotate(360deg)'
    }
  }
}
</script>

<style lang="css">
.switchbutton {
  position: fixed;
  bottom: 5%;
  right: 5%;
}
.button {
  background-color: #000;
  width: 3rem;
  height: 3rem;
  font-size: 1.5rem;
  color: #fff;
  display: flex;
  justify-content: center;
  align-items: center;
  border-radius: 50%;
}

.icon-loop2{
  margin: 0.5rem;
}

</style>


================================================
FILE: src/components/trip/Trip.vue
================================================
<template>
  <div class="trip">
    <div class="box">
      <pic-box :src="trip.pic"></pic-box>
      <div class="center">
        <div class="destination">
          {{'【'+trip.destination+'】'}}
        </div>
        <div class="title">
          {{trip.title}}
        </div>
      </div>
      <bottom-bar :nickname="trip.nickname" :avatar="trip.avatar" :time="trip.time" :userid="trip.userid"></bottom-bar>
    </div>
  </div>
</template>

<script>
import PicBox from 'components/picbox/PicBox'
import BottomBar from 'components/bottombar/BottomBar'

export default {
  props: {
    trip: {
      type: Object
    }
  },
  components: {
    "bottom-bar": BottomBar,
    "pic-box": PicBox
  }
}
</script>

<style lang="less">
  .trip {
      position: relative;
      width: 100%;
      background-color: #fff;

      .box {
          position: relative;
          width: 90%;
          background-color: #fff;
          margin: 0 auto;
          // border: 1px solid #d1dbe5;
          margin: 0 auto;
          // box-shadow:0 2px 4px 0 rgba(0,0,0,.12), 0 0 6px 0 rgba(0,0,0,.04);
          box-shadow: 0 0 30px -7px rgba(0,0,0,.3);
          padding: 5px 0;
          border-radius:4px;

          .center {
            font-size: 16px;
            font-weight: 400;
            font-family: fangzheng;
            margin:3%;
            padding: 5% 0;
            width: 94%;
            white-space: nowrap;
            text-overflow: ellipsis;
            overflow: hidden;
            display: flex;

            .destination {
            }

            .title {
              flex: 1;
              overflow: hidden;
              white-space: nowrap;
              text-overflow: ellipsis;
            }
          }
      }
  }
</style>


================================================
FILE: src/main.js
================================================
// 项目入口,配置全局vue
import Vue from 'vue'
import VueRouter from './router/routes.js'
import Store from './store/index.js'

import './assets/less/index.less'
import App from './App.vue'

import ElementUI from 'element-ui'
import 'element-ui/lib/theme-default/index.css'

Vue.use(ElementUI)

new Vue({
	router:VueRouter,
	store:Store,
	template:'<App/>',
	components: {App}
}).$mount('#app')

// 默认进入商品模块
VueRouter.push({ path: '/home' })


================================================
FILE: src/pages/choosetheme/ChooseTheme.vue
================================================
<template lang="html">

</template>

<script>
export default {
}
</script>

<style lang="css">
</style>


================================================
FILE: src/pages/daily/Daily.vue
================================================
<template>
  <div class="daily">
    <div class="info-container" v-for="item in dailylist">
      <info :info="item" class="info"></info>
    </div>
    <switch-button></switch-button>
  </div>
</template>

<script>
import axios from 'axios'

import Info from 'components/info/Info.vue'
import SwitchButton from 'components/switchbutton/SwitchButton.vue'

const ERR_OK = 0

export default {
  data () {
    return {
      dailylist:[]
    }
  },
  created() {
    axios.get('/api/daily').then((res) => {
      res = res.data
      if (res.errno === ERR_OK) {
        this.dailylist = res.data
      }
    }).catch((error) => {
      console.warn(error)
    })
  },
  components: {
    "info": Info,
    "switch-button": SwitchButton
  }}
</script>

<style lang="less">
  .daily {
    .info{
      margin: 20px 0;
    }
  }
</style>


================================================
FILE: src/pages/detail/Detail.vue
================================================
<template lang="html">
  <div class="detail">
    <!-- <info v-if="detail.themeid == 'info' " :info="detail"></info> -->
    <!-- <music v-if="detail.themeid == 'music' " :info="detail"></music> -->
    <!-- <v-article v-if="detail.themeid == 'article' " :info="detail"></v-article> -->
    <!-- <trip v-if="detail.themeid == 'trip' " :info="detail"></trip> -->
    <info-detail :info="detail"></info-detail>

  </div>
</template>

<script>
import axios from 'axios'
import Info from 'components/info/Info.vue'
import Music from 'components/music/Music.vue'
import Article from 'components/article/Article.vue'
import Trip from 'components/trip/Trip.vue'

import InfoDetail from 'components/infodetail/InfoDetail.vue'

const ERR_OK = 0

export default {
  data () {
    return {
      detail:{}
    }
  },
  components: {
    "info": Info,
    "music": Music,
    "v-article": Article,
    "trip": Trip,
    "info-detail":InfoDetail,
  },
  created () {
    axios.get('/api/detail',{
      params: {
        id: this.$route.params
      }
    }).then((res) => {
      res = res.data
      console.info(res)
      if (res.errno === ERR_OK) {
        this.detail = res.data
      }
    }).catch((error) => {
      console.warn(error)
    })

  }
}
</script>

<style lang="less">
</style>


================================================
FILE: src/pages/essay/Essay.vue
================================================
<template>
  <div class="eassy">
    <div class="article-container" v-for="item in articlelist">
      <v-article :article="item" class="articleitem"></v-article>
    </div>
    <switch-button></switch-button>
  </div>
</template>

<script>
import axios from 'axios'

import Header from 'components/header/Header.vue'
import Article from 'components/article/Article.vue'
import SwitchButton from 'components/switchbutton/SwitchButton.vue'

const ERR_OK = 0

export default {
  data () {
    return {
      articlelist:[]
    }
  },
  created() {
    axios.get('/api/essay').then((res) => {
      res = res.data
      if (res.errno === ERR_OK) {
        this.articlelist = res.data
      }
    }).catch((error) => {
      console.warn(error)
    })
  },
  components: {
    "v-article": Article,
    "switch-button": SwitchButton
  }
}
</script>

<style lang="less">
  .eassy {
    .articleitem{
      margin: 20px 0;
    }
  }
</style>


================================================
FILE: src/pages/home/Home.vue
================================================
<template>
  <div class="home">
    <div class="info-container" v-for="item in homelist">
      <info :info="item" class="info"></info>
    </div>
		<switch-button></switch-button>
  </div>
</template>

<script>
import axios from 'axios'

import Info from 'components/info/Info.vue'
import SwitchButton from 'components/switchbutton/SwitchButton.vue'

const ERR_OK = 0

export default {
  data () {
    return {
      homelist: []
    }
  },
  created() {
    axios.get('/api/home').then((res) => {
      res = res.data
      if (res.errno === ERR_OK) {
        this.homelist = res.data
      }
    }).catch((error) => {
      console.warn(error)
    })
  },
  components: {
    "info": Info,
    "switch-button": SwitchButton
  }
}
</script>

<style lang="less">
  .home {
    .info{
      margin: 20px 0;
    }
  }
</style>


================================================
FILE: src/pages/personal/Personal.vue
================================================
<template>
  <div class="personal">
    <div class="personal-container">
      <div class="personal-info">
        <div class="info">
          <div class="avatar">
            <img :src="user.avatar" alt="" @error="setErrorAvatar">
          </div>
          <div class="name">
            {{user.nickname}}
          </div>
        </div>
        <div class="follow">
          <div class="menu" @click="toggleFollowPerson(user.isfollow)">
            <i :class=" isfollow == true ? 'icon-checkbox-checked' : 'icon-checkbox-unchecked'"></i>
          </div>
            <div class="count">
              {{'Follower:'+ followcount}}
            </div>
        </div>
      </div>
      <div class="total">{{'Total Cards : '+listlength}}</div>
      <div class="content-box">
        <template v-for="item in user.contentlist">
          <div v-if="item.themeid === 'info'" class="item">
            <info :info="item"></info>
          </div>
          <div v-else-if="item.themeid === 'music'" class="item">
            <music :music="item"></music>
          </div>
          <div v-else-if="item.themeid === 'article'" class="item">
            <v-article :article="item"></v-article>
          </div>
          <div v-else-if="item.themeid === 'trip'" class="item">
              <trip :trip="item"></trip>
          </div>
        </template>
      </div>
    </div>
  </div>
</template>

<script>
import axios from 'axios'

import Info from 'components/info/Info.vue'
import Music from 'components/music/Music.vue'
import Article from 'components/article/Article.vue'
import Trip from 'components/trip/Trip.vue'


import { mapGetters, mapActions } from 'vuex'

const ERR_OK = 0

export default {
  data () {
    return {
      user: {},
      listlength: ""
    }
  },
  created() {
    axios.get('/api/personal').then((res) => {
      res = res.data
      if (res.errno === ERR_OK) {
        this.user = res.data
        this.listlength = res.data.contentlist.length
      }
    }).catch((error) => {
      console.warn(error)
    })
  },
  methods: {
    toggleFollowPerson () {
      this.$nextTick(function () {
        this.$store.dispatch('toggleFollowPerson',{userId:this.user.userid})
      })
    },
    setErrorAvatar () {
      this.$nextTick(function () {
        let errorImgUrl = require('../../assets/image/img_error_avatar.png')
        this.user.avatar = errorImgUrl
     })
    }
  },
  // mock下模拟的数据,正常情况下不需要computed下isfollow和followcount,而是真实的数据库数据
  computed: mapGetters({
    isfollow: 'isfollow',
    followcount: 'followcount'
  }),
  components: {
    "info": Info,
    "music": Music,
    "v-article": Article,
    "trip": Trip
  }
}
</script>

<style lang="less">
@font-face {
  font-family: 'fangzheng';
  src:  url('../../../static/fonts/fangzheng.ttf');
  font-weight: normal;
  font-style: normal;
}

  .personal {
    .personal-container {

      .personal-info {
        margin: 3%;
        display: flex;
        justify-content: space-between;
        align-items: flex-end;

        .info {
          flex: 0 0 20%;
          display: inline-flex;
          flex-direction: column;
          align-items: center;
          vertical-align: bottom;

          .avatar img{
            border-radius: 50%;
            width: 40px;
            height: 40px;
            margin: 0 auto;
          }

          .name {
            line-height: 40px;
            height: 40px;
            font-size: 16px;
            text-align: center;
            font-family: fangzheng;
            align-self: center;
          }

        }

        .follow {
          flex: 0 0 40%;
          display: inline-flex;
          flex-direction: column;
          align-items: center;
          vertical-align: bottom;

          .menu {
            line-height: 42px;
            height: 42px;
            text-align: center;
            font-size: 25px;
          }


          .count {
            line-height: 40px;
            height: 40px;
            font-size: 16px;
            text-align: center;
            font-family: fangzheng;
            align-self: center;
          }
        }

        .total {
          display: inline-block;
          position: relative;
        }
      }

      .total {
        margin: 5%;
        font-size: 16px;
        color: #000;
        font-family: fangzheng;
      }

      .content-box {
        .item {
          margin: 20px 0;
        }
      }
    }
  }

</style>


================================================
FILE: src/pages/travels/Travels.vue
================================================
<template>
  <div class="travels">
    <div class="trip-container" v-for="item in triplist">
      <trip :trip="item" class="trip"></trip>
    </div>
    <switch-button></switch-button>
  </div>
</template>

<script>
import axios from 'axios'

import Trip from 'components/trip/Trip.vue'
import SwitchButton from 'components/switchbutton/SwitchButton.vue'

const ERR_OK = 0

export default {
  data () {
    return {
      triplist:[]
    }
  },
  created() {
    axios.get('/api/travels').then((res) => {
      res = res.data
      if (res.errno === ERR_OK) {
        this.triplist = res.data
      }
    }).catch((error) => {
      console.warn(error)
    })
  },
  components: {
    "trip": Trip,
    "switch-button": SwitchButton
  }}
</script>

<style lang="less">
  .travels {
    .trip{
      margin: 20px 0;
    }
  }
</style>


================================================
FILE: src/pages/vocality/Vocality.vue
================================================
<template>
  <div class="vocality">
    <div class="music-container" v-for="item in musiclist">
      <music :music="item" class="music"></music>
    </div>
    <switch-button></switch-button>
    <v-player></v-player>
  </div>
</template>

<script>
import axios from 'axios'

import Header from 'components/header/Header.vue'
import Music from 'components/music/Music.vue'
import SwitchButton from 'components/switchbutton/SwitchButton.vue'
import Player from 'components/player/Player.vue'

const ERR_OK = 0

export default {
  data () {
    return {
      musiclist:[]
    }
  },
  created() {
    axios.get('/api/vocality').then((res) => {
      res = res.data
      if (res.errno === ERR_OK) {
        this.musiclist = res.data
      }
    }).catch((error) => {
      console.warn(error)
    })
  },
  components: {
    "music": Music,
    "switch-button": SwitchButton,
    "v-player": Player
  }}
</script>

<style lang="less">
  .vocality {
    .music{
      margin: 20px 0;
    }
  }
</style>


================================================
FILE: src/router/routes.js
================================================
/*路由配置文件*/

// 引入vue及相关插件
import Vue from 'vue'
import VueRouter from 'vue-router'
import Vuex from 'vuex'

// 引入自定义单文件组件
import Home from 'pages/home/Home'
import daily from 'pages/daily/Daily'
import Travels from 'pages/travels/Travels'
import Vocality from 'pages/vocality/Vocality'
import Essay from 'pages/essay/Essay'
import Personal from 'pages/personal/Personal'
import ChooseTheme from 'pages/choosetheme/ChooseTheme'
import Detail from 'pages/detail/Detail'

// 注册插件
Vue.use(VueRouter)
Vue.use(Vuex)

// 配置routes
const routes = [
  {
    path: '/home',
    name: 'home',
    component:Home
  },
  {
    path: '/daily',
    name: 'daily',
    component:daily
  },
  {
    path: '/travels',
    name: 'travels',
    component:Travels
  },
  {
    path: '/vocality',
    name: 'vocality',
    component:Vocality
  },
  {
    path: '/essay',
    name: 'essay',
    component:Essay
  },
  {
    path: '/personal',
    name: 'personal',
    component:Personal
  },
  {
    path: '/choosetheme',
    name: 'choosetheme',
    component:ChooseTheme
  },
  {
    path: '/detail',
    name: 'detail',
    component:Detail
  },
  {
    path: '/',
    component:Home
  }
]

// 路由配置
 const router = new VueRouter({
	mode:"history",
	routes
})

 export default router


================================================
FILE: src/store/actions.js
================================================
// 分发actions,页面的action同意dispatch到此进行逻辑处理

import * as types from './mutation-types.js'

// 首页各个模块跳转
export const  updatePage = ({commit}) => {
  commit(types.UPDATE_NEXT_PAGE)
}

// 点击用户头像进入个人页面
export const  goPersonalPages = ({commit},payload) => {
  if(payload.userId){
    commit(types.GO_PERSONAL_PAGES,{
      userId:payload.userId
    })
  }
}

// 切换关注用户
export const  toggleFollowPerson = ({commit}) => {
  commit(types.TOGGLE_FOLLOW_PERSON)
}

// 切换侧边栏显示
export const  toggleSlideBar = ({commit}) => {
  commit(types.TOGGLE_SLIDE_BAR)
}

// 切换header
export const  toggleheader = ({commit},payload) => {
  if(payload){
    commit(types.ADD_DETAIL_HEADER_NICKNAME,{
      nickname:payload.nickname
    })
  } else {
    commit(types.DELEATE_DETAIL_HEADER_NICKNAME)
  }
  commit(types.TOGGLE_HEADER)
}

// 切换音乐播放
export const  togglePlayerStatus = ({commit},payload) => {
  if (payload.currentPlayerUrl) {
    commit(types.TOGGLE_PLAYER_STATUS,{
      currentPlayerUrl:payload.currentPlayerUrl
    })
  }
}

// 点击列表项进入详情页面
export const  goDetailPage = ({commit},payload) => {
  if(payload.id){
    commit(types.GO_DETAIL_PAGES,{
      id:payload.id
    })
  }
}

// 点击列表项进入详情页面
export const  toggleLove = ({commit}) => {
  commit(types.TOGGLE_LOVE)
}


================================================
FILE: src/store/getters.js
================================================
export const headerTitle = state => state.pageArray[state.pageIndex].headerTitle
export const isSlideBarShow = state => state.isSlideBarShow
export const isDetailHeader = state => state.isDetailHeader
export const detailHeaderNickName = state => state.detailHeaderNickName
export const isAudioPlay = state => state.isAudioPlay
export const currentPlayerUrl = state => state.currentPlayerUrl

//mockx下临时模拟的数据,正常情况下没有该方法
export const isfollow = state => state.isfollow
export const followcount = state => state.followcount
export const isLove = state => state.isLove
export const lovecount = state => state.lovecount


================================================
FILE: src/store/index.js
================================================
// vuex配置

import Vue from 'vue'
import Vuex from 'vuex'
import state from './state'
import * as actions from './actions'
import * as getters from './getters'
import mutations from './mutations'

Vue.use(Vuex)

const debug = process.env.NODE_ENV !== 'production'

export default new Vuex.Store({
  state,
  actions,
  getters,
  mutations,
  strict:debug,
})


================================================
FILE: src/store/mutation-types.js
================================================
export const UPDATE_NEXT_PAGE = 'UPDATE_NEXT_PAGE'
export const GO_PERSONAL_PAGES = 'GO_PERSONAL_PAGES'
export const TOGGLE_FOLLOW_PERSON = 'TOGGLE_FOLLOW_PERSON'
export const TOGGLE_SLIDE_BAR = 'TOGGLE_SLIDE_BAR'
export const TOGGLE_HEADER = 'TOGGLE_HEADER'
export const ADD_DETAIL_HEADER_NICKNAME = 'ADD_DETAIL_HEADER_NICKNAME'
export const DELEATE_DETAIL_HEADER_NICKNAME = 'DELEATE_DETAIL_HEADER_NICKNAME'
export const TOGGLE_PLAYER_STATUS = 'TOGGLE_PLAYER_STATUS'
export const GO_DETAIL_PAGES = 'GO_DETAIL_PAGES'
export const TOGGLE_LOVE = 'TOGGLE_LOVE'


================================================
FILE: src/store/mutations.js
================================================
import * as types from './mutation-types.js'
import VueRouter from '../router/routes.js'

export default {
  [types.UPDATE_NEXT_PAGE](state) {
    if (state.pageIndex < state.pageArray.length -1) {
      state.pageIndex ++
    } else {
      state.pageIndex = 0
    }
    VueRouter.push({
      path: '/' + state.pageArray[state.pageIndex].routename
    })

  },

  [types.GO_PERSONAL_PAGES](state, {userId}) {
    VueRouter.push({ name: 'personal', params: { userId: userId }})
  },

  [types.TOGGLE_FOLLOW_PERSON](state) {
    // 正常的逻辑应该是将是否关注提交到数据库,更改数据库的字段并返回前端,现在是mock环境,只能在state中加了一个临时变量
    if (state.isfollow) {
      state.followcount --
    } else {
        state.followcount ++
    }
    state.isfollow = !state.isfollow
  },

  [types.TOGGLE_SLIDE_BAR](state) {
    state.isSlideBarShow = !state.isSlideBarShow
  },

  [types.TOGGLE_HEADER](state) {
    state.isDetailHeader = !state.isDetailHeader
  },

  [types.ADD_DETAIL_HEADER_NICKNAME](state,{nickname}) {
    state.detailHeaderNickName = nickname
  },

  [types.DELEATE_DETAIL_HEADER_NICKNAME](state) {
    state.detailHeaderNickName = ''
  },

  [types.TOGGLE_PLAYER_STATUS](state,{currentPlayerUrl}) {
    if (!state.isAudioPlay) {
      state.currentPlayerUrl = currentPlayerUrl
      state.isAudioPlay = true
    } else {
      state.currentPlayerUrl = currentPlayerUrl
    }
  },

  [types.GO_DETAIL_PAGES](state, {id}) {
    VueRouter.push({ name: 'detail', params: { id: id }})
  },

  [types.TOGGLE_LOVE](state) {
    // 正常的逻辑应该是将是否关注提交到数据库,更改数据库的字段并返回前端,现在是mock环境,只能在state中加了一个临时变量
    if (state.isLove) {
      state.lovecount --
    } else {
        state.lovecount ++
    }
    state.isLove = !state.isLove
  },

}


================================================
FILE: src/store/state.js
================================================
// 定义初始状态
const state = {
  pageIndex: 0,
  pageArray: [
    {headerTitle: "此处留白", routename: "home"},
    {headerTitle: "片刻留白", routename: "daily"},
    {headerTitle: "回音留白", routename: "vocality"},
    {headerTitle: "字符留白", routename: "essay"},
    {headerTitle: "半步留白", routename: "travels"}
  ],
  isSlideBarShow: false,
  isDetailHeader: false,
  detailHeaderNickName:'',
  personalInfo: {
    avatar:'http://p1.wmpic.me/article/2017/03/06/1488780213_usvFXYIl.jpg',
    nickname:'李留白',
    uid: 9001
  },
  isAudioPlay:false,
  currentPlayerUrl:'',
  isfollow: false ,   //mockx下临时模拟的数据,正常情况下没有该字段
  followcount:101,   //mockx下临时模拟的数据,正常情况下没有该字段
  isLove:false,      //mockx下临时模拟的数据,正常情况下没有该字段
  lovecount:12      //mockx下临时模拟的数据,正常情况下没有该字段
}

export default state


================================================
FILE: static/.gitkeep
================================================


================================================
FILE: static/css/reset.css
================================================
/**
 * Eric Meyer's Reset CSS v2.0 (http://meyerweb.com/eric/tools/css/reset/)
 * http://cssreset.com
 */
html, body, div, span, applet, object, iframe,
h1, h2, h3, h4, h5, h6, p, blockquote, pre,
a, abbr, acronym, address, big, cite, code,
del, dfn, em, img, ins, kbd, q, s, samp,
small, strike, strong, sub, sup, tt, var,
b, u, i, center,
dl, dt, dd, ol, ul, li,
fieldset, form, label, legend,
table, caption, tbody, tfoot, thead, tr, th, td,
article, aside, canvas, details, embed,
figure, figcaption, footer, header,
menu, nav, output, ruby, section, summary,
time, mark, audio, video, input {
    margin: 0;
    padding: 0;
    border: 0;
    font-size: 100%;
    font-weight: normal;
    vertical-align: baseline;
}

/* HTML5 display-role reset for older browsers */
article, aside, details, figcaption, figure,
footer, header, menu, nav, section {
    display: block;
}

body {
    line-height: 1;
}

blockquote, q {
    quotes: none;
}

blockquote:before, blockquote:after,
q:before, q:after {
    content: none;
}

table {
    border-collapse: collapse;
    border-spacing: 0;
}

/* custom */
a {
    color: #7e8c8d;
    text-decoration: none;
    -webkit-backface-visibility: hidden;
}

li {
    list-style: none;
}

::-webkit-scrollbar {
    width: 5px;
    height: 5px;
}

::-webkit-scrollbar-track-piece {
    background-color: rgba(0, 0, 0, 0.2);
    -webkit-border-radius: 6px;
}

::-webkit-scrollbar-thumb:vertical {
    height: 5px;
    background-color: rgba(125, 125, 125, 0.7);
    -webkit-border-radius: 6px;
}

::-webkit-scrollbar-thumb:horizontal {
    width: 5px;
    background-color: rgba(125, 125, 125, 0.7);
    -webkit-border-radius: 6px;
}

html, body {
    width: 100%;
}

body {
    -webkit-text-size-adjust: none;
    -webkit-tap-highlight-color: rgba(0, 0, 0, 0);
}
Download .txt
gitextract_np9uns0u/

├── .babelrc
├── .editorconfig
├── .gitignore
├── README.md
├── api/
│   ├── apiroutes.js
│   └── mockdata/
│       ├── daily.json
│       ├── detail.json
│       ├── essay.json
│       ├── home.json
│       ├── personal.json
│       ├── travels.json
│       └── vocality.json
├── build/
│   ├── build.js
│   ├── check-versions.js
│   ├── dev-client.js
│   ├── dev-server.js
│   ├── utils.js
│   ├── vue-loader.conf.js
│   ├── webpack.base.conf.js
│   ├── webpack.dev.conf.js
│   └── webpack.prod.conf.js
├── config/
│   ├── dev.env.js
│   ├── index.js
│   └── prod.env.js
├── index.html
├── package.json
├── src/
│   ├── App.vue
│   ├── assets/
│   │   └── less/
│   │       ├── icon.less
│   │       ├── index.less
│   │       └── mixin.less
│   ├── components/
│   │   ├── article/
│   │   │   └── Article.vue
│   │   ├── bottombar/
│   │   │   └── BottomBar.vue
│   │   ├── detailheader/
│   │   │   └── DetailHeader.vue
│   │   ├── header/
│   │   │   └── Header.vue
│   │   ├── info/
│   │   │   └── Info.vue
│   │   ├── infodetail/
│   │   │   └── InfoDetail.vue
│   │   ├── music/
│   │   │   └── Music.vue
│   │   ├── musicbar/
│   │   │   └── MusicBar.vue
│   │   ├── picbox/
│   │   │   └── PicBox.vue
│   │   ├── player/
│   │   │   └── Player.vue
│   │   ├── slidebar/
│   │   │   └── SlideBar.vue
│   │   ├── switchbutton/
│   │   │   └── SwitchButton.vue
│   │   └── trip/
│   │       └── Trip.vue
│   ├── main.js
│   ├── pages/
│   │   ├── choosetheme/
│   │   │   └── ChooseTheme.vue
│   │   ├── daily/
│   │   │   └── Daily.vue
│   │   ├── detail/
│   │   │   └── Detail.vue
│   │   ├── essay/
│   │   │   └── Essay.vue
│   │   ├── home/
│   │   │   └── Home.vue
│   │   ├── personal/
│   │   │   └── Personal.vue
│   │   ├── travels/
│   │   │   └── Travels.vue
│   │   └── vocality/
│   │       └── Vocality.vue
│   ├── router/
│   │   └── routes.js
│   └── store/
│       ├── actions.js
│       ├── getters.js
│       ├── index.js
│       ├── mutation-types.js
│       ├── mutations.js
│       └── state.js
└── static/
    ├── .gitkeep
    └── css/
        └── reset.css
Download .txt
SYMBOL INDEX (23 symbols across 5 files)

FILE: build/check-versions.js
  function exec (line 5) | function exec (cmd) {

FILE: build/utils.js
  function generateLoaders (line 15) | function generateLoaders (loaders) {

FILE: build/webpack.base.conf.js
  function resolve (line 7) | function resolve (dir) {

FILE: src/store/mutation-types.js
  constant UPDATE_NEXT_PAGE (line 1) | const UPDATE_NEXT_PAGE = 'UPDATE_NEXT_PAGE'
  constant GO_PERSONAL_PAGES (line 2) | const GO_PERSONAL_PAGES = 'GO_PERSONAL_PAGES'
  constant TOGGLE_FOLLOW_PERSON (line 3) | const TOGGLE_FOLLOW_PERSON = 'TOGGLE_FOLLOW_PERSON'
  constant TOGGLE_SLIDE_BAR (line 4) | const TOGGLE_SLIDE_BAR = 'TOGGLE_SLIDE_BAR'
  constant TOGGLE_HEADER (line 5) | const TOGGLE_HEADER = 'TOGGLE_HEADER'
  constant ADD_DETAIL_HEADER_NICKNAME (line 6) | const ADD_DETAIL_HEADER_NICKNAME = 'ADD_DETAIL_HEADER_NICKNAME'
  constant DELEATE_DETAIL_HEADER_NICKNAME (line 7) | const DELEATE_DETAIL_HEADER_NICKNAME = 'DELEATE_DETAIL_HEADER_NICKNAME'
  constant TOGGLE_PLAYER_STATUS (line 8) | const TOGGLE_PLAYER_STATUS = 'TOGGLE_PLAYER_STATUS'
  constant GO_DETAIL_PAGES (line 9) | const GO_DETAIL_PAGES = 'GO_DETAIL_PAGES'
  constant TOGGLE_LOVE (line 10) | const TOGGLE_LOVE = 'TOGGLE_LOVE'

FILE: src/store/mutations.js
  method [types.UPDATE_NEXT_PAGE] (line 5) | [types.UPDATE_NEXT_PAGE](state) {
  method [types.GO_PERSONAL_PAGES] (line 17) | [types.GO_PERSONAL_PAGES](state, {userId}) {
  method [types.TOGGLE_FOLLOW_PERSON] (line 21) | [types.TOGGLE_FOLLOW_PERSON](state) {
  method [types.TOGGLE_SLIDE_BAR] (line 31) | [types.TOGGLE_SLIDE_BAR](state) {
  method [types.TOGGLE_HEADER] (line 35) | [types.TOGGLE_HEADER](state) {
  method [types.ADD_DETAIL_HEADER_NICKNAME] (line 39) | [types.ADD_DETAIL_HEADER_NICKNAME](state,{nickname}) {
  method [types.DELEATE_DETAIL_HEADER_NICKNAME] (line 43) | [types.DELEATE_DETAIL_HEADER_NICKNAME](state) {
  method [types.TOGGLE_PLAYER_STATUS] (line 47) | [types.TOGGLE_PLAYER_STATUS](state,{currentPlayerUrl}) {
  method [types.GO_DETAIL_PAGES] (line 56) | [types.GO_DETAIL_PAGES](state, {id}) {
  method [types.TOGGLE_LOVE] (line 60) | [types.TOGGLE_LOVE](state) {
Condensed preview — 61 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (110K chars).
[
  {
    "path": ".babelrc",
    "chars": 200,
    "preview": "{\n  \"presets\": [\n    [\"es2015\", { \"modules\": false }],\n    \"stage-2\"\n  ],\n  \"plugins\": [\"transform-runtime\"],\n  \"comment"
  },
  {
    "path": ".editorconfig",
    "chars": 147,
    "preview": "root = true\n\n[*]\ncharset = utf-8\nindent_style = space\nindent_size = 2\nend_of_line = lf\ninsert_final_newline = true\ntrim_"
  },
  {
    "path": ".gitignore",
    "chars": 53,
    "preview": ".DS_Store\nnode_modules/\ndist/\nresource/\nnpm-debug.log"
  },
  {
    "path": "README.md",
    "chars": 2368,
    "preview": "TimeCat\n=======\n\n> 【此处留白】 - 图片社交分享App\n\n技术栈\n------\n\n前端:Vue2 + Vuex + Vue-Router2 + Axios + Webpack + ES6/7 + Less + Eleme"
  },
  {
    "path": "api/apiroutes.js",
    "chars": 964,
    "preview": "// Mock data by hicoldcat\n\nvar express = require('express')\nvar apiRoutes = express.Router();\n\nvar home = require('./moc"
  },
  {
    "path": "api/mockdata/daily.json",
    "chars": 3599,
    "preview": "{\n  \"errno\": 0,\n  \"data\": [\n    {\n      \"id\":1001,\n      \"userid\":\"u9001\",\n      \"nickname\": \"李留白\",\n      \"avatar\": \"htt"
  },
  {
    "path": "api/mockdata/detail.json",
    "chars": 630,
    "preview": "{\n  \"errno\": 0,\n  \"data\": {\n    \"id\":1001,\n    \"userid\":\"u9001\",\n    \"nickname\": \"李留白\",\n    \"avatar\": \"http://p1.wmpic.m"
  },
  {
    "path": "api/mockdata/essay.json",
    "chars": 3816,
    "preview": "{\n  \"errno\": 0,\n  \"data\": [\n    {\n      \"id\":1007,\n      \"userid\":\"u9007\",\n      \"nickname\": \"李留白\",\n      \"avatar\": \"htt"
  },
  {
    "path": "api/mockdata/home.json",
    "chars": 3599,
    "preview": "{\n  \"errno\": 0,\n  \"data\": [\n    {\n      \"id\":1001,\n      \"userid\":\"u9001\",\n      \"nickname\": \"李留白\",\n      \"avatar\": \"htt"
  },
  {
    "path": "api/mockdata/personal.json",
    "chars": 2074,
    "preview": "{\n  \"errno\": 0,\n  \"data\": {\n    \"userid\":\"u9001\",\n    \"nickname\": \"李留白\",\n    \"avatar\": \"http://p1.wmpic.me/article/2017/"
  },
  {
    "path": "api/mockdata/travels.json",
    "chars": 4104,
    "preview": "{\n  \"errno\": 0,\n  \"data\": [\n    {\n      \"id\":1005,\n      \"userid\":\"u9005\",\n      \"nickname\": \"李留白\",\n      \"avatar\": \"htt"
  },
  {
    "path": "api/mockdata/vocality.json",
    "chars": 6180,
    "preview": "{\n  \"errno\": 0,\n  \"data\": [\n    {\n      \"id\":1003,\n      \"userid\":\"u9003\",\n      \"nickname\": \"李留白\",\n      \"avatar\": \"htt"
  },
  {
    "path": "build/build.js",
    "chars": 1096,
    "preview": "// https://github.com/shelljs/shelljs\nrequire('./check-versions')()\n\nprocess.env.NODE_ENV = 'production'\n\nvar ora = requ"
  },
  {
    "path": "build/check-versions.js",
    "chars": 1172,
    "preview": "var chalk = require('chalk')\nvar semver = require('semver')\nvar packageConfig = require('../package.json')\n\nfunction exe"
  },
  {
    "path": "build/dev-client.js",
    "chars": 245,
    "preview": "/* eslint-disable */\nrequire('eventsource-polyfill')\nvar hotClient = require('webpack-hot-middleware/client?noInfo=true&"
  },
  {
    "path": "build/dev-server.js",
    "chars": 2382,
    "preview": "require('./check-versions')()\n\nvar config = require('../config')\nif (!process.env.NODE_ENV) {\n  process.env.NODE_ENV = J"
  },
  {
    "path": "build/utils.js",
    "chars": 2001,
    "preview": "var path = require('path')\nvar config = require('../config')\nvar ExtractTextPlugin = require('extract-text-webpack-plugi"
  },
  {
    "path": "build/vue-loader.conf.js",
    "chars": 398,
    "preview": "var utils = require('./utils')\nvar config = require('../config')\nvar isProduction = process.env.NODE_ENV === 'production"
  },
  {
    "path": "build/webpack.base.conf.js",
    "chars": 1643,
    "preview": "var path = require('path')\nvar utils = require('./utils')\nvar config = require('../config')\nvar vueLoaderConfig = requir"
  },
  {
    "path": "build/webpack.dev.conf.js",
    "chars": 1225,
    "preview": "var utils = require('./utils')\nvar webpack = require('webpack')\nvar config = require('../config')\nvar merge = require('w"
  },
  {
    "path": "build/webpack.prod.conf.js",
    "chars": 3135,
    "preview": "var path = require('path')\nvar utils = require('./utils')\nvar webpack = require('webpack')\nvar config = require('../conf"
  },
  {
    "path": "config/dev.env.js",
    "chars": 139,
    "preview": "var merge = require('webpack-merge')\nvar prodEnv = require('./prod.env')\n\nmodule.exports = merge(prodEnv, {\n  NODE_ENV: "
  },
  {
    "path": "config/index.js",
    "chars": 1437,
    "preview": "// see http://vuejs-templates.github.io/webpack for documentation.\nvar path = require('path')\n\nmodule.exports = {\n  buil"
  },
  {
    "path": "config/prod.env.js",
    "chars": 48,
    "preview": "module.exports = {\n  NODE_ENV: '\"production\"'\n}\n"
  },
  {
    "path": "index.html",
    "chars": 313,
    "preview": "<!DOCTYPE html>\n<html>\n\n<head>\n\t<meta charset=\"utf-8\">\n\t<title>timecat</title>\n\t<meta name=\"viewport\" content=\"width=dev"
  },
  {
    "path": "package.json",
    "chars": 1650,
    "preview": "{\n  \"name\": \"timecat\",\n  \"version\": \"1.0.0\",\n  \"description\": \"时光留白-图片分享App\",\n  \"author\": \"hicoldcat <1351290389@qq.com>"
  },
  {
    "path": "src/App.vue",
    "chars": 890,
    "preview": "<template>\n\t<div class=\"app\">\n\t\t<v-header v-show=\"!isDetailHeader\"></v-header>\n\t\t<detail-header :nickname=\"detailHeaderN"
  },
  {
    "path": "src/assets/less/icon.less",
    "chars": 10418,
    "preview": "@font-face {\n  font-family: 'icon';\n  src:  url('../fonts/icon.eot?g68udz');\n  src:  url('../fonts/icon.eot?g68udz#iefix"
  },
  {
    "path": "src/assets/less/index.less",
    "chars": 23,
    "preview": "@import \"./icon.less\";\n"
  },
  {
    "path": "src/assets/less/mixin.less",
    "chars": 31,
    "preview": "@baseBoxBackground:#fff;//盒子背景\n"
  },
  {
    "path": "src/components/article/Article.vue",
    "chars": 1391,
    "preview": "<template>\n  <div class=\"article\">\n    <div class=\"box\">\n      <pic-box :src=\"article.pic\"></pic-box>\n      <div class=\""
  },
  {
    "path": "src/components/bottombar/BottomBar.vue",
    "chars": 2240,
    "preview": "<template>\n  <div class=\"bottom\">\n    <div class=\"time\">\n      <div class=\"day\">\n        Feb.02\n      </div>\n      <div "
  },
  {
    "path": "src/components/detailheader/DetailHeader.vue",
    "chars": 1250,
    "preview": "<template lang=\"html\">\n  <header class=\"detailheader\">\n    <div class=\"menu\" @click=\"goBack\">\n      <i class=\" icon-arro"
  },
  {
    "path": "src/components/header/Header.vue",
    "chars": 1313,
    "preview": "<template>\n  <header class=\"heade\">\n    <div class=\"menu\" @click=\"toggleSlideBar\">\n      <i class=\"icon-diamond\"></i>\n  "
  },
  {
    "path": "src/components/info/Info.vue",
    "chars": 1537,
    "preview": "<template>\n<div class=\"info\">\n  <div class=\"box\">\n    <pic-box :src=\"info.pic\" :id=\"info.id\" :nickname=\"info.nickname\"><"
  },
  {
    "path": "src/components/infodetail/InfoDetail.vue",
    "chars": 2058,
    "preview": "<template>\n  <div class=\"info-detail\">\n    <div class=\"img-box\">\n      <img :src=\"info.pic\" alt=\"\">\n    </div>\n\n    <div"
  },
  {
    "path": "src/components/music/Music.vue",
    "chars": 1204,
    "preview": "<template>\n  <div class=\"music\">\n    <div class=\"box\">\n      <pic-box :src=\"music.pic\"></pic-box>\n      <music-bar :musi"
  },
  {
    "path": "src/components/musicbar/MusicBar.vue",
    "chars": 1733,
    "preview": "<template>\n  <div class=\"musicbar\">\n    <div class=\"musicbar-container\">\n      <div class=\"left\">\n        <img :src=\"img"
  },
  {
    "path": "src/components/picbox/PicBox.vue",
    "chars": 901,
    "preview": "<template>\n  <div class=\"pic\" @click=\"goDetailPage(id,nickname)\">\n    <img :src=\"imgsrc\" alt=\"\" @error=\"setErrorImg\">\n  "
  },
  {
    "path": "src/components/player/Player.vue",
    "chars": 785,
    "preview": "<template lang=\"html\">\n  <div class=\"player\">\n    <audio :src=\"currentPlayerUrl\" autoplay=\"autoplay\" controls=\"controls\""
  },
  {
    "path": "src/components/slidebar/SlideBar.vue",
    "chars": 4261,
    "preview": "<template lang=\"html\">\n  <div class=\"slidebar\" v-if=\"isSlideBarShow\">\n    <el-row class=\"container\">\n      <el-col :span"
  },
  {
    "path": "src/components/switchbutton/SwitchButton.vue",
    "chars": 674,
    "preview": "<template lang=\"html\">\n  <div class=\"switchbutton\">\n    <div class=\"button\" @click=\"goNextPage\"><i class=\"icon-loop2\" re"
  },
  {
    "path": "src/components/trip/Trip.vue",
    "chars": 1751,
    "preview": "<template>\n  <div class=\"trip\">\n    <div class=\"box\">\n      <pic-box :src=\"trip.pic\"></pic-box>\n      <div class=\"center"
  },
  {
    "path": "src/main.js",
    "chars": 433,
    "preview": "// 项目入口,配置全局vue\nimport Vue from 'vue'\nimport VueRouter from './router/routes.js'\nimport Store from './store/index.js'\n\ni"
  },
  {
    "path": "src/pages/choosetheme/ChooseTheme.vue",
    "chars": 104,
    "preview": "<template lang=\"html\">\n\n</template>\n\n<script>\nexport default {\n}\n</script>\n\n<style lang=\"css\">\n</style>\n"
  },
  {
    "path": "src/pages/daily/Daily.vue",
    "chars": 832,
    "preview": "<template>\n  <div class=\"daily\">\n    <div class=\"info-container\" v-for=\"item in dailylist\">\n      <info :info=\"item\" cla"
  },
  {
    "path": "src/pages/detail/Detail.vue",
    "chars": 1286,
    "preview": "<template lang=\"html\">\n  <div class=\"detail\">\n    <!-- <info v-if=\"detail.themeid == 'info' \" :info=\"detail\"></info> -->"
  },
  {
    "path": "src/pages/essay/Essay.vue",
    "chars": 936,
    "preview": "<template>\n  <div class=\"eassy\">\n    <div class=\"article-container\" v-for=\"item in articlelist\">\n      <v-article :artic"
  },
  {
    "path": "src/pages/home/Home.vue",
    "chars": 826,
    "preview": "<template>\n  <div class=\"home\">\n    <div class=\"info-container\" v-for=\"item in homelist\">\n      <info :info=\"item\" class"
  },
  {
    "path": "src/pages/personal/Personal.vue",
    "chars": 4441,
    "preview": "<template>\n  <div class=\"personal\">\n    <div class=\"personal-container\">\n      <div class=\"personal-info\">\n        <div "
  },
  {
    "path": "src/pages/travels/Travels.vue",
    "chars": 835,
    "preview": "<template>\n  <div class=\"travels\">\n    <div class=\"trip-container\" v-for=\"item in triplist\">\n      <trip :trip=\"item\" cl"
  },
  {
    "path": "src/pages/vocality/Vocality.vue",
    "chars": 1002,
    "preview": "<template>\n  <div class=\"vocality\">\n    <div class=\"music-container\" v-for=\"item in musiclist\">\n      <music :music=\"ite"
  },
  {
    "path": "src/router/routes.js",
    "chars": 1263,
    "preview": "/*路由配置文件*/\n\n// 引入vue及相关插件\nimport Vue from 'vue'\nimport VueRouter from 'vue-router'\nimport Vuex from 'vuex'\n\n// 引入自定义单文件组"
  },
  {
    "path": "src/store/actions.js",
    "chars": 1257,
    "preview": "// 分发actions,页面的action同意dispatch到此进行逻辑处理\n\nimport * as types from './mutation-types.js'\n\n// 首页各个模块跳转\nexport const  update"
  },
  {
    "path": "src/store/getters.js",
    "chars": 615,
    "preview": "export const headerTitle = state => state.pageArray[state.pageIndex].headerTitle\nexport const isSlideBarShow = state => "
  },
  {
    "path": "src/store/index.js",
    "chars": 359,
    "preview": "// vuex配置\n\nimport Vue from 'vue'\nimport Vuex from 'vuex'\nimport state from './state'\nimport * as actions from './actions"
  },
  {
    "path": "src/store/mutation-types.js",
    "chars": 558,
    "preview": "export const UPDATE_NEXT_PAGE = 'UPDATE_NEXT_PAGE'\nexport const GO_PERSONAL_PAGES = 'GO_PERSONAL_PAGES'\nexport const TOG"
  },
  {
    "path": "src/store/mutations.js",
    "chars": 1696,
    "preview": "import * as types from './mutation-types.js'\nimport VueRouter from '../router/routes.js'\n\nexport default {\n  [types.UPDA"
  },
  {
    "path": "src/store/state.js",
    "chars": 770,
    "preview": "// 定义初始状态\nconst state = {\n  pageIndex: 0,\n  pageArray: [\n    {headerTitle: \"此处留白\", routename: \"home\"},\n    {headerTitle:"
  },
  {
    "path": "static/.gitkeep",
    "chars": 0,
    "preview": ""
  },
  {
    "path": "static/css/reset.css",
    "chars": 1800,
    "preview": "/**\n * Eric Meyer's Reset CSS v2.0 (http://meyerweb.com/eric/tools/css/reset/)\n * http://cssreset.com\n */\nhtml, body, di"
  }
]

About this extraction

This page contains the full source code of the hicoldcat/TimeCat GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 61 files (93.8 KB), approximately 31.2k tokens, and a symbol index with 23 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!