├── .browserslistrc
├── .eslintrc.js
├── .gitignore
├── LICENSE
├── README.md
├── babel.config.js
├── package.json
├── public
├── favicon.ico
├── index.html
└── swiper.min.js
├── src
├── App.vue
├── api
│ ├── actor.js
│ ├── api.js
│ ├── article.js
│ ├── award.js
│ ├── common.js
│ ├── movie.js
│ ├── review.js
│ ├── role.js
│ ├── serial.js
│ ├── user.js
│ └── video.js
├── assets
│ ├── iconfont
│ │ ├── iconfont.css
│ │ ├── iconfont.ttf
│ │ ├── iconfont.woff
│ │ └── iconfont.woff2
│ ├── images
│ │ ├── honour-cup.png
│ │ └── logo.png
│ └── styles
│ │ ├── common.css
│ │ ├── cropper.min.css
│ │ ├── index.css
│ │ ├── reset.css
│ │ ├── swiper.min.css
│ │ └── variables.scss
├── components
│ ├── Actor
│ │ ├── ActorItem
│ │ │ ├── index.js
│ │ │ └── index.vue
│ │ └── ActorRow
│ │ │ ├── index.js
│ │ │ └── index.vue
│ ├── App
│ │ └── FooterInfo
│ │ │ ├── index.js
│ │ │ └── index.vue
│ ├── Article
│ │ └── ArticleItem
│ │ │ ├── index.js
│ │ │ └── index.vue
│ ├── Basic
│ │ └── BasicItem.vue
│ ├── BottomBar.vue
│ ├── Header
│ │ ├── HeaderBar
│ │ │ ├── index.js
│ │ │ └── index.vue
│ │ └── HeaderScrollBar
│ │ │ ├── index.js
│ │ │ └── index.vue
│ ├── ImageGroup
│ │ ├── index.js
│ │ └── index.vue
│ ├── ImageUpload
│ │ ├── index.js
│ │ └── src
│ │ │ ├── CropImage.vue
│ │ │ └── index.vue
│ ├── MPanel
│ │ ├── index.js
│ │ └── index.vue
│ ├── Movie
│ │ ├── MovieCard
│ │ │ ├── index.js
│ │ │ └── index.vue
│ │ ├── MovieItem
│ │ │ ├── index.js
│ │ │ └── index.vue
│ │ ├── MovieRow
│ │ │ ├── index.js
│ │ │ └── index.vue
│ │ └── Skeleton
│ │ │ ├── index.js
│ │ │ └── index.vue
│ ├── NoData
│ │ ├── index.js
│ │ └── index.vue
│ ├── Page
│ │ ├── index.js
│ │ └── index.vue
│ ├── Photo
│ │ ├── PhotoGroup
│ │ │ ├── index.js
│ │ │ └── index.vue
│ │ └── PhotoSwiper
│ │ │ ├── index.js
│ │ │ └── index.vue
│ ├── Player
│ │ ├── PlayerProgress.vue
│ │ └── index.vue
│ ├── Report
│ │ ├── index.js
│ │ └── src
│ │ │ └── report.vue
│ ├── Review
│ │ └── ReviewItem
│ │ │ ├── index.js
│ │ │ └── index.vue
│ ├── Role
│ │ ├── RoleItem
│ │ │ ├── index.js
│ │ │ └── index.vue
│ │ └── RoleRow
│ │ │ ├── index.js
│ │ │ └── index.vue
│ ├── Skeleton
│ │ ├── index.js
│ │ └── index.vue
│ ├── TabSwitch
│ │ ├── index.js
│ │ └── index.vue
│ ├── Tool
│ │ ├── ToolBar
│ │ │ ├── index.js
│ │ │ └── index.vue
│ │ ├── UserCollection
│ │ │ ├── index.js
│ │ │ └── index.vue
│ │ └── UserLike
│ │ │ ├── index.js
│ │ │ └── index.vue
│ └── Video
│ │ ├── VideoItem
│ │ ├── index.js
│ │ └── index.vue
│ │ └── VideoRow
│ │ ├── index.js
│ │ └── index.vue
├── config.js
├── directive
│ └── infinite-scroll
│ │ ├── index.js
│ │ └── infinite-scroll.js
├── filters
│ └── index.js
├── http
│ └── index.js
├── main.js
├── mixins
│ ├── getInfiniteData.js
│ └── preventScroll.js
├── router
│ ├── actor.js
│ ├── article.js
│ ├── award.js
│ ├── index.js
│ ├── main.js
│ ├── movie.js
│ ├── profile.js
│ ├── role.js
│ └── video.js
├── store
│ ├── index.js
│ └── modules
│ │ ├── actor.js
│ │ ├── movie.js
│ │ └── user.js
├── util
│ ├── color.js
│ └── index.js
└── views
│ ├── 404.vue
│ ├── Layout.vue
│ ├── account
│ ├── components
│ │ └── CaptchaModal.vue
│ ├── forget.vue
│ ├── login.vue
│ └── register.vue
│ ├── actor
│ ├── award
│ │ ├── components
│ │ │ └── AwardItem.vue
│ │ └── index.vue
│ ├── detail
│ │ ├── components
│ │ │ ├── ActorAward.vue
│ │ │ ├── ActorCount.vue
│ │ │ └── Skeleton.vue
│ │ ├── index.vue
│ │ └── information.vue
│ ├── role
│ │ └── index.vue
│ └── works
│ │ └── index.vue
│ ├── article
│ └── detail
│ │ ├── components
│ │ └── Skeleton.vue
│ │ └── index.vue
│ ├── award
│ ├── detail
│ │ ├── components
│ │ │ └── AwardInfo.vue
│ │ ├── index.vue
│ │ └── info.vue
│ ├── index
│ │ └── index.vue
│ └── session
│ │ ├── components
│ │ └── Skeleton.vue
│ │ └── index.vue
│ ├── comment
│ ├── components
│ │ ├── CommentBar.vue
│ │ ├── CommentEditor.vue
│ │ ├── CommentItem.vue
│ │ ├── CommentSkeleton.vue
│ │ └── CommentTool.vue
│ └── index.vue
│ ├── demo.vue
│ ├── home
│ ├── components
│ │ ├── HeaderBar.vue
│ │ ├── HomeMenu.vue
│ │ ├── HomeSwiper.vue
│ │ └── Skeleton.vue
│ └── index.vue
│ ├── movie
│ ├── coming.vue
│ ├── detail
│ │ ├── article
│ │ │ └── index.vue
│ │ ├── award
│ │ │ ├── components
│ │ │ │ └── AwardItem.vue
│ │ │ └── index.vue
│ │ ├── cast
│ │ │ ├── components
│ │ │ │ └── CastPanel.vue
│ │ │ └── index.vue
│ │ ├── company
│ │ │ └── index.vue
│ │ ├── dialogue
│ │ │ └── index.vue
│ │ ├── index
│ │ │ ├── components
│ │ │ │ ├── MovieAward.vue
│ │ │ │ ├── MovieBar.vue
│ │ │ │ ├── MovieExtra.vue
│ │ │ │ ├── MovieInfo.vue
│ │ │ │ ├── MovieRating.vue
│ │ │ │ ├── PhotoWall.vue
│ │ │ │ ├── SerialRow.vue
│ │ │ │ └── Skeleton.vue
│ │ │ ├── detail.vue
│ │ │ ├── favorite.vue
│ │ │ └── index.vue
│ │ ├── knowledge
│ │ │ └── index.vue
│ │ ├── level
│ │ │ └── index.vue
│ │ ├── pubdate
│ │ │ └── index.vue
│ │ ├── rating
│ │ │ ├── components
│ │ │ │ ├── RateDetail.vue
│ │ │ │ └── RateTrend.vue
│ │ │ ├── create.vue
│ │ │ └── index.vue
│ │ ├── review
│ │ │ └── index.vue
│ │ ├── role
│ │ │ └── index.vue
│ │ ├── serial
│ │ │ ├── components
│ │ │ │ └── SerialItem.vue
│ │ │ └── index.vue
│ │ └── video
│ │ │ └── index.vue
│ ├── index
│ │ ├── components
│ │ │ ├── MenuSkeleton.vue
│ │ │ ├── MovieRow.vue
│ │ │ ├── MovieSkeleton.vue
│ │ │ ├── NavGroup.vue
│ │ │ └── NavList.vue
│ │ └── index.vue
│ ├── serial
│ │ └── detail
│ │ │ ├── components
│ │ │ └── SerialInfo.vue
│ │ │ └── index.vue
│ ├── theater.vue
│ ├── today.vue
│ └── top.vue
│ ├── offline.vue
│ ├── photo
│ ├── components
│ │ └── PhotoItem.vue
│ └── index.vue
│ ├── profile
│ ├── aboutus
│ │ ├── author.vue
│ │ └── project.vue
│ ├── changelog
│ │ └── index.vue
│ ├── collection
│ │ ├── actor
│ │ │ └── index.vue
│ │ ├── review
│ │ │ └── index.vue
│ │ ├── role
│ │ │ └── index.vue
│ │ └── video
│ │ │ └── index.vue
│ ├── favorite
│ │ ├── create
│ │ │ └── index.vue
│ │ ├── detail
│ │ │ ├── components
│ │ │ │ └── FavoriteInfo.vue
│ │ │ └── index.vue
│ │ ├── edit
│ │ │ └── index.vue
│ │ └── index
│ │ │ └── index.vue
│ ├── feedback
│ │ └── index.vue
│ ├── index
│ │ ├── components
│ │ │ ├── MineCell.vue
│ │ │ ├── MineInfo.vue
│ │ │ └── MineMenu.vue
│ │ └── index.vue
│ ├── information
│ │ └── index.vue
│ └── setting
│ │ └── index.vue
│ ├── review
│ └── detail
│ │ ├── components
│ │ ├── Skeleton.vue
│ │ └── ToolVote.vue
│ │ └── index.vue
│ ├── role
│ ├── actor
│ │ └── index.vue
│ ├── detail
│ │ ├── components
│ │ │ ├── RoleCount.vue
│ │ │ └── Skeleton.vue
│ │ ├── index.vue
│ │ └── information.vue
│ └── movie
│ │ └── index.vue
│ ├── search
│ ├── components
│ │ ├── SearchBar.vue
│ │ ├── SearchHistory.vue
│ │ ├── SearchMenu.vue
│ │ └── SearchResult.vue
│ └── index.vue
│ └── video
│ ├── detail
│ ├── components
│ │ ├── MVideo.vue
│ │ ├── Skeleton.vue
│ │ ├── VideoInfo.vue
│ │ ├── VideoItem.vue
│ │ └── VideoRow.vue
│ └── index.vue
│ └── index
│ ├── components
│ ├── VideoCard.vue
│ └── VideoListSkeleton.vue
│ └── index.vue
└── vue.config.js
/.browserslistrc:
--------------------------------------------------------------------------------
1 | > 1%
2 | last 2 versions
3 | not dead
4 |
--------------------------------------------------------------------------------
/.eslintrc.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | root: true,
3 | env: {
4 | node: true
5 | },
6 | 'extends': [
7 | 'plugin:vue/essential',
8 | 'eslint:recommended'
9 | ],
10 | parserOptions: {
11 | parser: 'babel-eslint'
12 | },
13 | rules: {
14 | 'no-console': process.env.NODE_ENV === 'production' ? 'warn' : 'off',
15 | 'no-debugger': process.env.NODE_ENV === 'production' ? 'warn' : 'off'
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | .DS_Store
2 | node_modules
3 | /html
4 | /dist
5 | html.zip
6 |
7 | # local env files
8 | .env.local
9 | .env.*.local
10 |
11 | # Log files
12 | npm-debug.log*
13 | yarn-debug.log*
14 | yarn-error.log*
15 |
16 | package-lock.json
17 |
18 | # Editor directories and files
19 | .idea
20 | .vscode
21 | *.suo
22 | *.ntvs*
23 | *.njsproj
24 | *.sln
25 | *.sw?
26 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # 慕影网
2 |
3 | ## Vue 实现的影视评分类网站
4 |
5 | 一个基于 `vue` 实现的移动端影视评分网站,涉及 `60+` 个页面,`70+` 个接口,包含注册登录、个人中心、影视信息、影人信息、相册、评分等多个功能。
6 | 本项目会长期更新。
7 |
8 | ## 演示
9 | 演示地址:[https://test-h5.ixook.com](https://test-h5.ixook.com)
10 |
11 | 接口文档:[https://doc.ixook.com](https://doc.ixook.com/doc/movie-mobile-test/api?api=readme)
12 |
13 | 开发文档:[https://h5-doc.ixook.com](https://h5-doc.ixook.com)
14 |
15 |
16 | ## 脑图
17 | 
18 |
19 | ## 技术栈
20 | - `vue2.6`
21 | - `vuex`
22 | - `vue-router`
23 | - `vue-cli`
24 | - `sass`
25 | - `axios.js` [基于 promise 的 HTTP 库](https://www.kancloud.cn/yunye/axios/234845)
26 | - `iconfont` [阿里字体图标库](https://www.iconfont.cn/)
27 | - `mind-ui-vue` [个人为本项目制作的`vue`移动端组件库](https://mind-ui-vue.ixook.com/docs)
28 | - `lib-flexible` [移动端自适应方案](https://github.com/amfe/lib-flexible)
29 | - `cropperjs` [图片裁剪](https://github.com/fengyuanchen/cropperjs)
30 | - `echarts` [百度图表插件](https://echarts.apache.org/zh/index.html)
31 | - `swiper` [图片轮播/预览插件](https://www.swiper.com.cn)
32 | - `vue-lazyload` [图片懒加载插件](https://github.com/hilongjw/vue-lazyload)
33 |
34 |
35 | ## 安装
36 | ```
37 | npm install
38 | ```
39 |
40 | ## 开发环境启动
41 | ```
42 | npm run serve
43 | ```
44 |
45 | ## 打包编译
46 | ```
47 | npm run build
48 | ```
49 |
50 | ## 联系作者
51 | 如有问题可以提 `issue` 或者加入qq群: `577133021` 进行反馈
52 |
53 | 作者主页地址:[https://ixook.com](https://ixook.com)
54 |
55 |
56 | ## License
57 | GPL
58 |
--------------------------------------------------------------------------------
/babel.config.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | presets: [
3 | '@vue/cli-plugin-babel/preset'
4 | ]
5 | }
6 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "muying-h5",
3 | "version": "0.1.2",
4 | "private": true,
5 | "scripts": {
6 | "serve": "vue-cli-service serve",
7 | "build": "vue-cli-service build",
8 | "lint": "vue-cli-service lint"
9 | },
10 | "dependencies": {
11 | "axios": "^0.19.2",
12 | "core-js": "^3.21.1",
13 | "cropperjs": "^1.5.12",
14 | "echarts": "^5.3.1",
15 | "lib-flexible": "^0.3.2",
16 | "mind-ui-vue": "^1.0.3",
17 | "qiniu-js": "^3.4.0",
18 | "spark-md5": "^3.0.2",
19 | "swiper": "^8.1.0",
20 | "vue": "^2.6.14",
21 | "vue-lazyload": "^1.3.3",
22 | "vue-router": "^3.5.3",
23 | "vuex": "^3.6.2"
24 | },
25 | "devDependencies": {
26 | "@vue/cli-plugin-babel": "~4.3.0",
27 | "@vue/cli-plugin-eslint": "~4.3.0",
28 | "@vue/cli-plugin-router": "~4.3.0",
29 | "@vue/cli-plugin-vuex": "~4.3.0",
30 | "@vue/cli-service": "~4.3.0",
31 | "babel-eslint": "^10.1.0",
32 | "eslint": "^6.7.2",
33 | "eslint-plugin-vue": "^6.2.2",
34 | "px2rem-loader": "^0.1.9",
35 | "sass": "^1.30.0",
36 | "sass-loader": "^10.1.0",
37 | "css-loader": "^5.2.7",
38 | "vue-style-loader": "^4.1.3",
39 | "vue-template-compiler": "^2.6.14"
40 | }
41 | }
42 |
--------------------------------------------------------------------------------
/public/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/NameLi/muying-h5/48c42bc32638fe871265e42c85c2a026133d5ece/public/favicon.ico
--------------------------------------------------------------------------------
/public/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 | 慕影网
11 |
12 |
13 |
26 |
27 |
28 |
29 |
33 |
34 |
35 |
36 |
37 |
--------------------------------------------------------------------------------
/src/App.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
14 |
15 |
16 |
--------------------------------------------------------------------------------
/src/api/actor.js:
--------------------------------------------------------------------------------
1 | import http from '@/http/index'
2 |
3 | // 影人相关
4 | export const getActor = (id) => http.get(`/actors/${id}`); // 获取影人信息
5 | export const getActorAwards = (id) => http.get(`/actors/${id}/awards`); // 获取影人奖项
6 | export const getActorPhotos = (id, params) => http.get(`/actors/${id}/photos`, params); // 获取影人相册
7 | export const getActorWorks = (id, params) => http.get(`/actors/${id}/works`, params); // 获取影人参演作品
8 | export const getActorRoles = (id, params) => http.get(`/actors/${id}/roles`, params); // 获取影人饰演角色
9 |
--------------------------------------------------------------------------------
/src/api/api.js:
--------------------------------------------------------------------------------
1 | import http from '@/http/index';
2 |
3 | export const getCover = () => http.get('movie/cover'); // 今日封面
4 | export const getIndex = () => http.get('index'); // 首页聚合接口
5 |
6 | export const getCategories = () => http.get("/categories"); // 影视分类
7 | export const getMovieTheater = (params) => http.get('movie/theater', params); // 正在热映
8 | export const getMovieComing = (params) => http.get('movie/coming', params); // 即将上映
9 | export const getMovieTop = (params) => http.get('movie/top', params); // TOP 100
10 | export const getMovieToday = (params) => http.get('movie/today', params); // 历史上的今日上映影片
11 |
--------------------------------------------------------------------------------
/src/api/article.js:
--------------------------------------------------------------------------------
1 | import http from '@/http/index'
2 |
3 | // 文章相关
4 | export const getArticle = (id) => http.get(`/articles/${id}`); // 文章详情
5 |
--------------------------------------------------------------------------------
/src/api/award.js:
--------------------------------------------------------------------------------
1 | import http from '@/http/index'
2 |
3 | export const getAwards = () => http.get(`/awards`); // 奖项列表
4 | export const getAward = (name) => http.get(`/awards/${name}`); // 奖项详情
5 | export const getAwardSession = (name, session) => http.get(`/awards/${name}/${session}`); // 奖项届详情
--------------------------------------------------------------------------------
/src/api/common.js:
--------------------------------------------------------------------------------
1 | import http from '@/http/index'
2 |
3 | export const getVersion = () => http.get("/version") // 获取版本号
4 | export const getQiniuUpToken = params => http.get("/qiniu/uptoken", params) // 七牛文件上传token
5 |
6 | export const getCaptcha = () => http.get("/captcha") // 获取图片验证码
7 | export const createPhoneCode = (params) => http.get("/code", params) // 获取手机验证码
8 | export const checkPhoneCode = (params) => http.post("/code", params) // 校验手机验证码
9 |
10 | export const search = (params) => http.get("/search", params); // 搜索
11 |
12 | // 获取评论
13 | export const getComments = (type, id, params) => http.get(`/${type}/${id}/comments`, params);
14 | export const createComment = (type, id, params) => http.post(`/${type}/${id}/comments`, params);
15 | export const deleteComment = (id) => http.delete(`/comments/${id}`);
16 |
17 |
18 |
19 | // 举报
20 | export const getReport = (params) => http.get(`/reports`, params);
21 | export const createReport = (params) => http.post(`/reports`, params);
--------------------------------------------------------------------------------
/src/api/movie.js:
--------------------------------------------------------------------------------
1 | import http from '@/http/index'
2 |
3 | // 影视相关接口
4 | export const getMovies = (params) => http.get(`/movies`, params); // 影视列表
5 | export const getMovie = (id) => http.get(`/movies/${id}`); // 影视详情
6 | export const getMovieCast = (id) => http.get(`/movies/${id}/cast`); // 影视演员
7 | export const getMovieRoles = (id, params) => http.get(`/movies/${id}/roles`, params); // 影视角色
8 | export const getMoviePhotos = (id, params) => http.get(`/movies/${id}/photos`, params); // 影视相册
9 | export const getMovieVideos = (id, params) => http.get(`/movies/${id}/videos`, params); // 影视视频
10 | export const getMovieComments = (id, params) => http.get(`/movies/${id}/comments`, params); // 影视评分
11 | export const getMovieReviews = (id, params) => http.get(`/movies/${id}/reviews`, params); // 影视长评
12 | export const getMovieLevels = (id, params) => http.get(`/movies/${id}/levels`, params); // 引导等级
13 | export const getMoviePubdates = (id, params) => http.get(`/movies/${id}/pubdates`, params); // 上映日期
14 | export const getMovieAwards = (id) => http.get(`/movies/${id}/awards`); // 获得奖项
15 | export const getMovieKnowledges = (id, params) => http.get(`/movies/${id}/knowledges`, params); // 幕后知识
16 | export const getMovieDialogues = (id, params) => http.get(`/movies/${id}/dialogues`, params); // 经典台词
17 | export const getMovieCompanies = (id) => http.get(`/movies/${id}/companies`); // 关联公司
18 | export const getMovieArticles = (id, params) => http.get(`/movies/${id}/articles`, params); // 文章资讯
19 | export const getMovieSerials = (id, params) => http.get(`/movies/${id}/serials`, params); // 所属系列
20 | export const getMovieRatings = (id) => http.get(`/movies/${id}/ratings`); // 评分详情
--------------------------------------------------------------------------------
/src/api/review.js:
--------------------------------------------------------------------------------
1 | import http from '@/http/index'
2 |
3 | // 影评相关接口
4 | export const getReview = (id) => http.get(`/reviews/${id}`); // 影评详情
5 |
6 |
7 |
--------------------------------------------------------------------------------
/src/api/role.js:
--------------------------------------------------------------------------------
1 | import http from '@/http/index'
2 |
3 | // 角色相关接口
4 | export const getRole = (id) => http.get(`/roles/${id}`); // 角色详情
5 | export const getRolePhotos = (id, params) => http.get(`/roles/${id}/photos`, params); // 角色相册
6 | export const getRoleMovies = (id, params) => http.get(`/roles/${id}/movies`, params); // 角色影视
7 | export const getRoleActors = (id, params) => http.get(`/roles/${id}/actors`, params); // 角色影人
--------------------------------------------------------------------------------
/src/api/serial.js:
--------------------------------------------------------------------------------
1 | import http from '@/http/index'
2 |
3 | // 系列相关接口
4 | export const getSerials = (params) => http.get(`/serials`, params); // 系列列表
5 | export const getSerialMovies = (id, params) => http.get(`/serials/${id}/movies`, params); // 系列影视
6 |
--------------------------------------------------------------------------------
/src/api/user.js:
--------------------------------------------------------------------------------
1 | import http from '@/http/index'
2 |
3 | // 账号
4 | export const register = (params) => http.post(`/register`, params); // 注册
5 | export const getUserToken = (params) => http.post(`/login`, params); // 登录获取token
6 | export const getUserInfo = (params) => http.get(`/user`, params); // 登录用户信息
7 | export const updateUserInfo = (params) => http.put(`/user`, params); // 更新用户信息
8 | export const checkAccount = (params) => http.post(`/account`, params); // 校验手机号是否存在
9 | export const updateUserPassword = (params) => http.put(`/user/password`, params); // 更新用户密码
10 |
11 |
12 |
13 | // 影视收藏
14 | export const getUserFavorites = (params) => http.get(`/user/favorites`, params); // 收藏夹列表
15 | export const getUserFavorite = (id, params) => http.get(`/user/favorites/${id}`, params); // 收藏夹详情
16 | export const createUserFavorite = (params) => http.post(`/user/favorites`, params); // 新建收藏夹
17 | export const updateUserFavorite = (id, params) => http.put(`/user/favorites/${id}`, params); // 更新收藏夹
18 | export const deleteUserFavorite = (id) => http.delete(`/user/favorites/${id}`); // 删除收藏夹
19 | export const deleteUserFavoriteMovies = (id, union_id) => http.delete(`/user/favorites/${id}/movies/${union_id}`); // 删除收藏夹下影视
20 |
21 | export const getUserFavoriteMovies = (id, params) => http.get(`/user/favorites/${id}/movies`, params); // 收藏夹下影视
22 | export const updateUserMovieFavorite = (id, params) => http.put(`/user/movies/${id}/favorites`, params); // 更新影视所属收藏夹
23 |
24 |
25 | // 用户评分
26 | export const createUserMovieRating = (id, params) => http.post(`/user/movies/${id}/rating`, params) // 用户评分
27 | export const userMovieWish = (id, params) => http.post(`/user/movies/${id}/wish`, params) // 用户想看
28 |
29 | // 用户反馈
30 | export const createFeedback = (params) => http.post(`/feedback`, params)
31 |
32 |
33 | /**
34 | * @desc 用户收藏
35 | * */
36 |
37 | // 收藏统计
38 | export const getUserCollectionCount = () => http.get(`/user/collections/count`);
39 |
40 |
41 | /**
42 | * @desc 收藏
43 | * type 被收藏资源 可选值为 actors reviews roles videos
44 | * @return array
45 | */
46 | export const getUserCollection = (type) => http.get(`/user/collections/${type}`);
47 | export const createCollection = (type, id) => http.post(`/user/${type}/${id}/collections`);
48 | export const deleteCollection = (type, id) => http.delete(`/user/${type}/${id}/collections`);
49 |
50 | // 投票,赞同与反对
51 | export const createReviewVote = (id, params) => http.post(`/reviews/${id}/voters`, params);
52 |
53 | // 评论喜欢
54 | export const createCommentLike = (id) => http.post(`/comments/${id}/like`);
55 | export const deleteCommentLike = (id) => http.delete(`/comments/${id}/like`);
56 |
57 |
58 | /**
59 | * @desc 点赞
60 | * type 被点赞的资源 可选值为 videos photos
61 | * @return array
62 | */
63 | // 喜欢
64 | export const createLike = (type, id) => http.post(`/${type}/${id}/like`);
65 | export const deleteLike = (type, id) => http.delete(`/${type}/${id}/like`);
66 |
--------------------------------------------------------------------------------
/src/api/video.js:
--------------------------------------------------------------------------------
1 | import http from '@/http/index'
2 |
3 | export const getVideos = (params) => http.get('/videos', params); // 获取视频列表
4 | export const getVideo = (id) => http.get(`/videos/${id}`); // 获取视频详情
5 |
--------------------------------------------------------------------------------
/src/assets/iconfont/iconfont.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/NameLi/muying-h5/48c42bc32638fe871265e42c85c2a026133d5ece/src/assets/iconfont/iconfont.ttf
--------------------------------------------------------------------------------
/src/assets/iconfont/iconfont.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/NameLi/muying-h5/48c42bc32638fe871265e42c85c2a026133d5ece/src/assets/iconfont/iconfont.woff
--------------------------------------------------------------------------------
/src/assets/iconfont/iconfont.woff2:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/NameLi/muying-h5/48c42bc32638fe871265e42c85c2a026133d5ece/src/assets/iconfont/iconfont.woff2
--------------------------------------------------------------------------------
/src/assets/images/honour-cup.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/NameLi/muying-h5/48c42bc32638fe871265e42c85c2a026133d5ece/src/assets/images/honour-cup.png
--------------------------------------------------------------------------------
/src/assets/images/logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/NameLi/muying-h5/48c42bc32638fe871265e42c85c2a026133d5ece/src/assets/images/logo.png
--------------------------------------------------------------------------------
/src/assets/styles/common.css:
--------------------------------------------------------------------------------
1 | html {
2 | font-family: -apple-system, BlinkMacSystemFont, Helvetica Neue, PingFang SC, Microsoft YaHei, Source Han Sans SC, Noto Sans CJK SC, WenQuanYi Micro Hei, sans-serif;
3 | -webkit-font-smoothing: antialiased;
4 | -moz-osx-font-smoothing: grayscale;
5 | color: #303133;
6 | font-size: 14px;
7 | }
8 |
9 | body {
10 | -webkit-tap-highlight-color: rgba(0, 0, 0, 0);
11 | }
12 |
13 | .border, .border_top, .border_right, .border_bottom, .border_left {
14 | position: relative;
15 | }
16 |
17 | .border::before {
18 | display: block;
19 | content: "";
20 | position: absolute;
21 | left: 0;
22 | top: 0;
23 | border: 1px solid #dedede;
24 | transform-origin: 0 0;
25 | box-sizing: border-box;
26 | border-radius: 6px;
27 | }
28 |
29 | .border_top::before, .border_right::before, .border_bottom::before, .border_left::before {
30 | display: block;
31 | content: "";
32 | position: absolute;
33 | background: #dedede;
34 | }
35 |
36 | .border_top::before {
37 | left: 0;
38 | top: 0;
39 | width: 100%;
40 | height: 1px;
41 | }
42 |
43 | .border_left::before {
44 | left: 0;
45 | top: 0;
46 | bottom: 0;
47 | width: 1px;
48 | height: 100%;
49 | }
50 |
51 |
52 | .border_right::before {
53 | right: 0;
54 | top: 0;
55 | bottom: 0;
56 | width: 1px;
57 | height: 100%;
58 | }
59 |
60 | .border_bottom::before {
61 | left: 0;
62 | bottom: 0;
63 | width: 100%;
64 | height: 1px;
65 | }
66 |
67 | @media screen and (-webkit-min-device-pixel-ratio: 2) {
68 | .border::before {
69 | width: 200%;
70 | height: 200%;
71 | transform: scale(0.5);
72 | }
73 |
74 | .border_top::before, .border_bottom::before {
75 | transform: scaleY(0.5);
76 | }
77 |
78 | .border_left::before, .border_right::before {
79 | transform: scaleX(0.5);
80 | }
81 | }
82 |
83 | @media screen and (-webkit-min-device-pixel-ratio: 3) {
84 | .border::before {
85 | width: 300%;
86 | height: 300%;
87 | transform: scale(0.33333);
88 | }
89 |
90 | .border_top::before, .border_bottom::before {
91 | transform: scaleY(0.33333);
92 | }
93 |
94 | .border_left::before, .border_right::before {
95 | transform: scaleX(0.33333);
96 | }
97 | }
98 |
99 | @media (max-width: 800px) {
100 | ::-webkit-scrollbar {
101 | display: none;
102 | }
103 | }
104 |
105 | .ellipsis {
106 | overflow: hidden;
107 | text-overflow: ellipsis;
108 | white-space: nowrap;
109 | }
110 |
111 | .hidden {
112 | display: none;
113 | }
114 |
115 | .overflow-hidden {
116 | overflow: hidden;
117 | }
--------------------------------------------------------------------------------
/src/assets/styles/index.css:
--------------------------------------------------------------------------------
1 | @import url(./reset.css);
2 | @import url(./common.css);
3 | @import url(./cropper.min.css);
4 | @import url(./swiper.min.css);
5 | @import url(../iconfont/iconfont.css);
--------------------------------------------------------------------------------
/src/assets/styles/reset.css:
--------------------------------------------------------------------------------
1 | /*
2 | css 初始化
3 | 2017.4.20
4 | */
5 | body, ul, ol, li, h1, h2, h3, h4, h5, h6, p, form, th, dd, dl, fieldset, legend, input, textarea, select {margin: 0;padding: 0;}
6 |
7 | ul, ol { list-style:none; }
8 |
9 | a {text-decoration:none;}
10 | h1, h2, h3, h4, h5, h6 {font-weight: normal;}
11 | address, em {font-style:normal}
12 | li {list-style:none}
13 | img {border:0; vertical-align:middle}
14 | table {border-collapse:collapse; border-spacing:0}
15 | p {word-wrap:break-word}
16 | input{outline:none}
--------------------------------------------------------------------------------
/src/assets/styles/variables.scss:
--------------------------------------------------------------------------------
1 | $color-theme: #e54847;
--------------------------------------------------------------------------------
/src/components/Actor/ActorItem/index.js:
--------------------------------------------------------------------------------
1 | import ActorItem from './index.vue';
2 |
3 | export default {
4 | install(Vue) {
5 | Vue.component(ActorItem.name, ActorItem);
6 | }
7 | };
--------------------------------------------------------------------------------
/src/components/Actor/ActorItem/index.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
![]()
4 |
5 |
6 |
7 |
{{ actor.name_en }}
8 |
9 | {{ actor.gender }}
10 | ·
11 | {{ actor.country }}
12 |
13 |
14 |
15 |
16 |
17 |
48 |
49 |
99 |
--------------------------------------------------------------------------------
/src/components/Actor/ActorRow/index.js:
--------------------------------------------------------------------------------
1 | import ActorRow from './index.vue';
2 |
3 | export default {
4 | install(Vue) {
5 | Vue.component(ActorRow.name, ActorRow);
6 | }
7 | };
--------------------------------------------------------------------------------
/src/components/Actor/ActorRow/index.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
![]()
4 |
5 |
6 |
{{ actor.name }}
7 |
导演
8 |
12 | 饰: {{ actor.act }}
13 |
14 |
15 |
16 |
17 |
18 |
19 |
38 |
39 |
74 |
--------------------------------------------------------------------------------
/src/components/App/FooterInfo/index.js:
--------------------------------------------------------------------------------
1 | import FooterInfo from './index.vue';
2 |
3 | export default {
4 | install(Vue) {
5 | Vue.component(FooterInfo.name, FooterInfo);
6 | }
7 | };
--------------------------------------------------------------------------------
/src/components/App/FooterInfo/index.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |

5 |
{{ APP_NAME }}
6 |
7 |
8 |
9 |
21 |
22 |
--------------------------------------------------------------------------------
/src/components/Article/ArticleItem/index.js:
--------------------------------------------------------------------------------
1 | import VideoItem from './index.vue';
2 |
3 | export default {
4 | install(Vue) {
5 | Vue.component(VideoItem.name, VideoItem);
6 | }
7 | };
--------------------------------------------------------------------------------
/src/components/Basic/BasicItem.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
![]()
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
26 |
27 |
53 |
--------------------------------------------------------------------------------
/src/components/Header/HeaderBar/index.js:
--------------------------------------------------------------------------------
1 | import HeaderBar from './index.vue';
2 |
3 | export default {
4 | install(Vue) {
5 | Vue.component(HeaderBar.name, HeaderBar);
6 | }
7 | };
--------------------------------------------------------------------------------
/src/components/Header/HeaderScrollBar/index.js:
--------------------------------------------------------------------------------
1 | import Component from './index.vue';
2 |
3 | export default {
4 | install(Vue) {
5 | Vue.component(Component.name, Component);
6 | }
7 | };
--------------------------------------------------------------------------------
/src/components/ImageGroup/index.js:
--------------------------------------------------------------------------------
1 | import ImageGroup from './index.vue';
2 |
3 | export default {
4 | install(Vue) {
5 | Vue.component(ImageGroup.name, ImageGroup);
6 | }
7 | };
--------------------------------------------------------------------------------
/src/components/ImageGroup/index.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
![]()
11 |
12 |

17 |
18 |
19 |
20 |
43 |
44 |
--------------------------------------------------------------------------------
/src/components/ImageUpload/index.js:
--------------------------------------------------------------------------------
1 | import ImageUploadComponent from './src/index.vue';
2 |
3 | const ImageUpload = {
4 | install: function (Vue) {
5 | Vue.component('ImageUpload', ImageUploadComponent)
6 | }
7 | }
8 |
9 | export default ImageUpload;
--------------------------------------------------------------------------------
/src/components/MPanel/index.js:
--------------------------------------------------------------------------------
1 | import MPanel from './index.vue';
2 |
3 | export default {
4 | install(Vue) {
5 | Vue.component(MPanel.name, MPanel);
6 | }
7 | };
--------------------------------------------------------------------------------
/src/components/MPanel/index.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
57 |
58 |
--------------------------------------------------------------------------------
/src/components/Movie/MovieCard/index.js:
--------------------------------------------------------------------------------
1 | import MovieCard from './index.vue';
2 |
3 | export default {
4 | install(Vue) {
5 | Vue.component(MovieCard.name, MovieCard);
6 | }
7 | };
--------------------------------------------------------------------------------
/src/components/Movie/MovieCard/index.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
![]()
6 |
7 |
8 |
23 |
24 | {{ movie.year }}·{{ movie.countries }}·{{ movie.genres }}·{{ movie.duration }}
28 |
29 |
30 |
31 |
32 |
33 |
34 |
44 |
45 |
--------------------------------------------------------------------------------
/src/components/Movie/MovieItem/index.js:
--------------------------------------------------------------------------------
1 | import MovieItem from './index.vue';
2 |
3 | export default {
4 | install(Vue) {
5 | Vue.component(MovieItem.name, MovieItem);
6 | }
7 | };
--------------------------------------------------------------------------------
/src/components/Movie/MovieRow/index.js:
--------------------------------------------------------------------------------
1 | import MovieRow from './index.vue';
2 |
3 | export default {
4 | install(Vue) {
5 | Vue.component(MovieRow.name, MovieRow);
6 | }
7 | };
--------------------------------------------------------------------------------
/src/components/Movie/Skeleton/index.js:
--------------------------------------------------------------------------------
1 | import Component from './index.vue';
2 |
3 | export default {
4 | install(Vue) {
5 | Vue.component(Component.name, Component);
6 | }
7 | };
--------------------------------------------------------------------------------
/src/components/Movie/Skeleton/index.vue:
--------------------------------------------------------------------------------
1 |
2 |
15 |
16 |
17 |
32 |
33 |
82 |
--------------------------------------------------------------------------------
/src/components/NoData/index.js:
--------------------------------------------------------------------------------
1 | import NoData from './index.vue';
2 |
3 | export default {
4 | install(Vue) {
5 | Vue.component(NoData.name, NoData);
6 | }
7 | };
--------------------------------------------------------------------------------
/src/components/NoData/index.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
{{ content }}
5 |
6 |
7 |
8 |
9 |
10 |
41 |
42 |
54 |
--------------------------------------------------------------------------------
/src/components/Page/index.js:
--------------------------------------------------------------------------------
1 | import Page from './index.vue';
2 |
3 | export default {
4 | install(Vue) {
5 | Vue.component(Page.name, Page);
6 | }
7 | };
--------------------------------------------------------------------------------
/src/components/Photo/PhotoGroup/index.js:
--------------------------------------------------------------------------------
1 | import PhotoGroup from './index.vue';
2 |
3 | export default {
4 | install(Vue) {
5 | Vue.component(PhotoGroup.name, PhotoGroup);
6 | }
7 | };
--------------------------------------------------------------------------------
/src/components/Photo/PhotoGroup/index.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
![]()
5 |
6 |
7 |
8 |
9 |
19 |
20 |
--------------------------------------------------------------------------------
/src/components/Photo/PhotoSwiper/index.js:
--------------------------------------------------------------------------------
1 | import PhotoSwiper from './index.vue';
2 |
3 | export default {
4 | install(Vue) {
5 | Vue.component(PhotoSwiper.name, PhotoSwiper);
6 | }
7 | };
--------------------------------------------------------------------------------
/src/components/Report/index.js:
--------------------------------------------------------------------------------
1 | import Report from './src/report.vue';
2 |
3 | export default {
4 | install(Vue) {
5 | Vue.component(Report.name, Report);
6 | }
7 | };
--------------------------------------------------------------------------------
/src/components/Review/ReviewItem/index.js:
--------------------------------------------------------------------------------
1 | import ReviewItem from './index.vue';
2 |
3 | export default {
4 | install(Vue) {
5 | Vue.component(ReviewItem.name, ReviewItem);
6 | }
7 | };
--------------------------------------------------------------------------------
/src/components/Review/ReviewItem/index.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
17 |
18 |
21 |
22 |
23 | {{ review.vote_up_count }} 赞 · {{ review.read_count }} 浏览
26 | 转载自
29 | {{ review.created_at | dateBefore }}
30 |
31 |
32 |
33 |
34 |
45 |
46 |
96 |
--------------------------------------------------------------------------------
/src/components/Role/RoleItem/index.js:
--------------------------------------------------------------------------------
1 | import RoleItem from './index.vue';
2 |
3 | export default {
4 | install(Vue) {
5 | Vue.component(RoleItem.name, RoleItem);
6 | }
7 | };
--------------------------------------------------------------------------------
/src/components/Role/RoleItem/index.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
![]()
4 |
5 |
6 |
7 |
{{ role.name_en }}
8 |
{{ info }}
9 |
10 |
11 |
12 |
13 |
14 |
49 |
50 |
106 |
--------------------------------------------------------------------------------
/src/components/Role/RoleRow/index.js:
--------------------------------------------------------------------------------
1 | import RoleRow from './index.vue';
2 |
3 | export default {
4 | install(Vue) {
5 | Vue.component(RoleRow.name, RoleRow);
6 | }
7 | };
--------------------------------------------------------------------------------
/src/components/Role/RoleRow/index.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
![]()
4 |
5 |
8 |
9 |
10 |
11 |
28 |
29 |
64 |
--------------------------------------------------------------------------------
/src/components/Skeleton/index.js:
--------------------------------------------------------------------------------
1 | import Skeleton from './index.vue';
2 |
3 | export default {
4 | install(Vue) {
5 | Vue.component(Skeleton.name, Skeleton);
6 | }
7 | };
--------------------------------------------------------------------------------
/src/components/Skeleton/index.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
12 |
13 |
--------------------------------------------------------------------------------
/src/components/TabSwitch/index.js:
--------------------------------------------------------------------------------
1 | import TabSwitch from './index.vue';
2 |
3 | export default {
4 | install(Vue) {
5 | Vue.component(TabSwitch.name, TabSwitch);
6 | }
7 | };
--------------------------------------------------------------------------------
/src/components/TabSwitch/index.vue:
--------------------------------------------------------------------------------
1 |
2 |
7 |
13 |
14 |
15 |
16 |
54 |
55 |
103 |
--------------------------------------------------------------------------------
/src/components/Tool/ToolBar/index.js:
--------------------------------------------------------------------------------
1 | import ToolBar from './index.vue';
2 |
3 | export default {
4 | install(Vue) {
5 | Vue.component(ToolBar.name, ToolBar);
6 | }
7 | };
--------------------------------------------------------------------------------
/src/components/Tool/UserCollection/index.js:
--------------------------------------------------------------------------------
1 | import UserCollection from './index.vue';
2 |
3 | export default {
4 | install(Vue) {
5 | Vue.component(UserCollection.name, UserCollection);
6 | }
7 | };
--------------------------------------------------------------------------------
/src/components/Tool/UserCollection/index.vue:
--------------------------------------------------------------------------------
1 |
2 |
14 |
15 |
16 |
--------------------------------------------------------------------------------
/src/components/Tool/UserLike/index.js:
--------------------------------------------------------------------------------
1 | import UserLike from './index.vue';
2 |
3 | export default {
4 | install(Vue) {
5 | Vue.component(UserLike.name, UserLike);
6 | }
7 | };
--------------------------------------------------------------------------------
/src/components/Tool/UserLike/index.vue:
--------------------------------------------------------------------------------
1 |
2 |
12 |
13 |
14 |
--------------------------------------------------------------------------------
/src/components/Video/VideoItem/index.js:
--------------------------------------------------------------------------------
1 | import VideoItem from './index.vue';
2 |
3 | export default {
4 | install(Vue) {
5 | Vue.component(VideoItem.name, VideoItem);
6 | }
7 | };
--------------------------------------------------------------------------------
/src/components/Video/VideoRow/index.js:
--------------------------------------------------------------------------------
1 | import VideoRow from './index.vue';
2 |
3 | export default {
4 | install(Vue) {
5 | Vue.component(VideoRow.name, VideoRow);
6 | }
7 | };
--------------------------------------------------------------------------------
/src/components/Video/VideoRow/index.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
6 |
![]()
7 |
8 |
9 |
10 |
11 |
22 |
23 |
--------------------------------------------------------------------------------
/src/config.js:
--------------------------------------------------------------------------------
1 | export const HOST = '//test-h5-api.ixook.com';
2 | export const FILE_DOMAIN = "https://img.ixook.com"
3 |
4 | export const APP_NAME = '慕影网';
5 | export const DEVELOPER = '冰糖雪梨';
6 | export const VERSION = '0.1 alpha';
--------------------------------------------------------------------------------
/src/directive/infinite-scroll/index.js:
--------------------------------------------------------------------------------
1 | import infiniteScroll from './infinite-scroll'
2 |
3 | export default {
4 | install(Vue) {
5 | Vue.directive('infinite-scroll', infiniteScroll)
6 | }
7 | }
--------------------------------------------------------------------------------
/src/filters/index.js:
--------------------------------------------------------------------------------
1 | import { dateBefore, timeFormat } from '@/util/index'
2 |
3 |
4 | export { dateBefore, timeFormat };
--------------------------------------------------------------------------------
/src/http/index.js:
--------------------------------------------------------------------------------
1 | import axios from 'axios'
2 | import store from '@/store'
3 | import router from '@/router'
4 | import { HOST } from '@/config'
5 | import { Toast } from 'mind-ui-vue'
6 |
7 | // axios 配置
8 | axios.defaults.timeout = 20000
9 | axios.defaults.baseURL = HOST
10 | axios.defaults.headers['Content-Type'] = 'application/json;charset=UTF-8'
11 |
12 |
13 | // 请求时的拦截
14 | axios.interceptors.request.use(config => {
15 | if (store.state.user.token) {
16 | config.headers['Authorization'] = 'Bearer ' + store.state.user.token
17 | }
18 | return config
19 | }, function (error) {
20 | return Promise.reject(error)
21 | })
22 |
23 | // 返回值
24 | axios.interceptors.response.use(res => {
25 | if (res.status === 200) {
26 |
27 | if (res.data.code >= 400) {
28 | Toast({
29 | position: 'top',
30 | message: res.data.message
31 | })
32 | }
33 |
34 | return res.data
35 | }
36 |
37 | return {
38 | code: res.status_code,
39 | message: res.message,
40 | data: {}
41 | }
42 |
43 | }, error => {
44 |
45 | if (String(error).includes('timeout')) {
46 | Toast('网络请求超时')
47 | } else if (String(error).includes('Network Error')) {
48 | // Toast('网络异常')
49 |
50 | router.push({
51 | path: '/offline'
52 | })
53 |
54 | } else if (error.response) {
55 | const { status, statusText } = error.response
56 |
57 | // 未登录
58 | if (status === 401) {
59 |
60 | // 清空
61 | store.commit("user/SET_USER", null);
62 | store.commit("user/SET_TOKEN", "");
63 | localStorage.removeItem("user");
64 | localStorage.removeItem("token");
65 |
66 | if (!['Login', 'Profile', 'Register', 'NotFound', 'Forget'].includes(router.currentRoute.name)) {
67 | router.push({
68 | path: '/login',
69 | query: { redirect: router.currentRoute.fullPath }
70 | })
71 | }
72 |
73 | return error.response.data
74 | }
75 |
76 | Toast(status + '' + statusText)
77 | }
78 |
79 | return {
80 | 'code': 400,
81 | 'messsage': 'error'
82 | }
83 | })
84 |
85 |
86 | export default {
87 | get(url, params) {
88 | return axios({
89 | method: 'get',
90 | url,
91 | params
92 | })
93 | },
94 |
95 | post(url, data) {
96 | return axios({
97 | method: 'post',
98 | url,
99 | data
100 | })
101 | },
102 |
103 | patch(url, data) {
104 | return axios({
105 | method: 'patch',
106 | url,
107 | data
108 | })
109 | },
110 |
111 | put(url, data) {
112 | return axios({
113 | method: 'put',
114 | url,
115 | data
116 | })
117 | },
118 |
119 | delete(url, data) {
120 | return axios({
121 | method: 'delete',
122 | url,
123 | data
124 | })
125 | }
126 | }
--------------------------------------------------------------------------------
/src/mixins/getInfiniteData.js:
--------------------------------------------------------------------------------
1 | export const getInfiniteData = {
2 | data() {
3 | return {
4 | loading: false,
5 | noData: false,
6 | noMoreData: false,
7 | isError: false,
8 | list: [],
9 | total: 0,
10 | page: 1,
11 | per_page: 20,
12 | form: {},
13 | };
14 | },
15 |
16 | computed: {
17 | isShowSkeleton() {
18 | return this.loading && this.page === 1;
19 | },
20 | },
21 |
22 | mounted() {
23 | this.loadMore();
24 | },
25 |
26 | methods: {
27 | async getData(fn, ...args) {
28 |
29 | if (this.isError) return;
30 |
31 | if (this.noMoreData && this.page === 1 && this.list.length === 0) {
32 | this.noMoreData = false;
33 | }
34 |
35 | if (this.loading || this.noMoreData) return;
36 |
37 | this.loading = true;
38 |
39 | let params = {
40 | page: this.page,
41 | per_page: this.per_page,
42 | ...this.form
43 | };
44 |
45 | const { code, data, total } = await fn(...args, params);
46 |
47 | if (code === 200) {
48 | // 是否无数据
49 | if (this.page === 1 && data.length === 0) {
50 | this.noData = true;
51 | } else {
52 | this.noData = false;
53 | }
54 |
55 | this.isError = false;
56 |
57 | this.page++;
58 |
59 | this.list.push(...data);
60 | this.total = total || 0
61 |
62 | if (data.length < this.per_page) {
63 | this.noMoreData = true;
64 | }
65 | } else {
66 | this.isError = true;
67 | }
68 |
69 | this.$nextTick(() => {
70 | this.loading = false;
71 | });
72 | },
73 | },
74 | }
--------------------------------------------------------------------------------
/src/mixins/preventScroll.js:
--------------------------------------------------------------------------------
1 | export const preventScroll = {
2 | mounted() {
3 | this.$preventScroll(true);
4 | },
5 |
6 | beforeDestroy() {
7 | this.$preventScroll(false);
8 | },
9 | }
--------------------------------------------------------------------------------
/src/router/actor.js:
--------------------------------------------------------------------------------
1 |
2 | // 影人路由表
3 | export default [
4 | {
5 | path: '/actors/:id',
6 | props: true,
7 | name: "Actor",
8 | component: () => import('@/views/actor/detail'),
9 | children: [
10 | {
11 | path: '/actors/:id/information',
12 | props: true,
13 | name: "ActorDetail",
14 | component: () => import('@/views/actor/detail/information')
15 | },
16 | {
17 | path: '/actors/:id/awards',
18 | props: true,
19 | name: "ActorAwards",
20 | component: () => import('@/views/actor/award/index')
21 | },
22 | {
23 | path: '/actors/:id/works',
24 | props: true,
25 | name: "ActorWorks",
26 | component: () => import('@/views/actor/works/index')
27 | },
28 | {
29 | path: '/actors/:id/roles',
30 | props: true,
31 | name: "ActorRoles",
32 | component: () => import('@/views/actor/role/index')
33 | },
34 | ]
35 | },
36 | ]
--------------------------------------------------------------------------------
/src/router/article.js:
--------------------------------------------------------------------------------
1 |
2 | // 文章路由
3 | export default [
4 | // {
5 | // path: '/articles',
6 | // name: "Articles",
7 | // component: () => import('@/views/article/index')
8 | // },
9 | {
10 | path: '/articles/:id',
11 | props: true,
12 | name: "Article",
13 | component: () => import('@/views/article/detail/index'),
14 | children: [
15 | {
16 | path: '/articles/:id/comments',
17 | props: true,
18 | name: "ArticleComments",
19 | component: () => import('@/views/comment/index')
20 | },
21 | ]
22 | },
23 | ]
--------------------------------------------------------------------------------
/src/router/award.js:
--------------------------------------------------------------------------------
1 |
2 | // 奖项路由
3 | export default [
4 | {
5 | path: '/awards',
6 | name: "Awards",
7 | component: () => import('@/views/award/index/index')
8 | },
9 | {
10 | path: '/awards/:name',
11 | props: true,
12 | name: "Award",
13 | component: () => import('@/views/award/detail/index'),
14 | children: [
15 | {
16 | path: '/awards/:name/detail',
17 | name: "AwardDetail",
18 | props: true,
19 | component: () => import('@/views/award/detail/info')
20 | },
21 | ]
22 | },
23 | {
24 | path: '/awards/:name/:session',
25 | props: true,
26 | name: "AwardSession",
27 | component: () => import('@/views/award/session/index')
28 | },
29 | ]
--------------------------------------------------------------------------------
/src/router/main.js:
--------------------------------------------------------------------------------
1 |
2 | // 基础路由
3 | export default [
4 | {
5 | path: '/',
6 | component: () => import('@/views/Layout'),
7 | children: [
8 | {
9 | path: '/home',
10 | name: "Home",
11 | meta: { scrollY: 0 },
12 | component: () => import('@/views/home/index')
13 | },
14 | {
15 | path: '/movies',
16 | name: "Movies",
17 | meta: { scrollY: 0 },
18 | component: () => import('@/views/movie/index/index')
19 | },
20 | {
21 | path: '/videos',
22 | name: "Videos",
23 | meta: { scrollY: 0 },
24 | component: () => import('@/views/video/index/index')
25 | },
26 | {
27 | path: '/profile',
28 | name: "Profile",
29 | meta: { scrollY: 0 },
30 | component: () => import('@/views/profile/index/index'),
31 | children: [
32 | {
33 | path: '/profile/information',
34 | name: "ProfileInformation",
35 | component: () => import('@/views/profile/information/index')
36 | },
37 | {
38 | path: '/profile/feedback',
39 | name: "Feedback",
40 | component: () => import('@/views/profile/feedback')
41 | },
42 | {
43 | path: '/profile/changelog',
44 | name: "ChangeLog",
45 | component: () => import('@/views/profile/changelog')
46 | },
47 | {
48 | path: '/profile/author',
49 | name: "AboutAuthor",
50 | component: () => import('@/views/profile/aboutus/author')
51 | },
52 | {
53 | path: '/profile/project',
54 | name: "AboutProject",
55 | component: () => import('@/views/profile/aboutus/project')
56 | },
57 | {
58 | path: '/profile/setting',
59 | name: "Setting",
60 | component: () => import('@/views/profile/setting/index')
61 | },
62 | ]
63 | },
64 | ]
65 | },
66 | ]
--------------------------------------------------------------------------------
/src/router/profile.js:
--------------------------------------------------------------------------------
1 |
2 | // 个人中心
3 | export default [
4 | {
5 | path: '/profile/favorites',
6 | name: "ProfileFavorites",
7 | component: () => import('@/views/profile/favorite/index'),
8 | children: [
9 | {
10 | path: '/profile/favorites/create',
11 | props: true,
12 | name: "ProfileFavoriteCreate",
13 | component: () => import('@/views/profile/favorite/create/index')
14 | },
15 | ]
16 | },
17 | // {
18 | // path: '/profile/favorites/create',
19 | // props: true,
20 | // name: "ProfileFavoriteCreate",
21 | // component: () => import('@/views/profile/favorite/create/index')
22 | // },
23 | {
24 | path: '/profile/favorites/:id',
25 | props: true,
26 | name: "ProfileFavorite",
27 | component: () => import('@/views/profile/favorite/detail'),
28 | children: [
29 | {
30 | path: '/profile/favorites/:id/edit',
31 | props: true,
32 | name: "profileFavoriteEdit",
33 | component: () => import('@/views/profile/favorite/edit/index')
34 | },
35 | ]
36 | },
37 |
38 | {
39 | path: '/profile/actors',
40 | name: "ProfileActors",
41 | component: () => import('@/views/profile/collection/actor')
42 | },
43 | {
44 | path: '/profile/roles',
45 | name: "ProfileRoles",
46 | component: () => import('@/views/profile/collection/role')
47 | },
48 | {
49 | path: '/profile/reviews',
50 | name: "ProfileReviews",
51 | component: () => import('@/views/profile/collection/review')
52 | },
53 | {
54 | path: '/profile/videos',
55 | name: "ProfileVideos",
56 | component: () => import('@/views/profile/collection/video')
57 | },
58 | ]
--------------------------------------------------------------------------------
/src/router/role.js:
--------------------------------------------------------------------------------
1 |
2 | // 角色路由表
3 | export default [
4 | {
5 | path: '/roles/:id',
6 | props: true,
7 | name: "Role",
8 | component: () => import('@/views/role/detail'),
9 | children: [
10 | {
11 | path: '/roles/:id/information',
12 | props: true,
13 | name: "RoleDetail",
14 | component: () => import('@/views/role/detail/information')
15 | },
16 | {
17 | path: '/roles/:id/movies',
18 | props: true,
19 | name: 'RoleMovies',
20 | component: () => import('@/views/role/movie/index')
21 | },
22 | {
23 | path: '/roles/:id/actors',
24 | props: true,
25 | name: 'RoleActors',
26 | component: () => import('@/views/role/actor/index')
27 | },
28 | ]
29 | },
30 | ]
--------------------------------------------------------------------------------
/src/router/video.js:
--------------------------------------------------------------------------------
1 |
2 | // 视频路由
3 | export default [
4 | {
5 | path: '/videos/:id',
6 | props: true,
7 | name: "Video",
8 | component: () => import('@/views/video/detail/index'),
9 | children: [
10 | {
11 | path: '/videos/:id/comments',
12 | props: true,
13 | name: "VideoComments",
14 | component: () => import('@/views/comment'),
15 | }
16 | ]
17 | },
18 | ]
--------------------------------------------------------------------------------
/src/store/index.js:
--------------------------------------------------------------------------------
1 | import Vue from 'vue'
2 | import Vuex from 'vuex'
3 |
4 | import user from './modules/user'
5 | import movie from './modules/movie'
6 | import actor from './modules/actor'
7 | Vue.use(Vuex)
8 |
9 | export default new Vuex.Store({
10 | modules: {
11 | user,
12 | movie,
13 | actor
14 | }
15 | })
--------------------------------------------------------------------------------
/src/store/modules/actor.js:
--------------------------------------------------------------------------------
1 | const state = {
2 | actor: localStorage.getItem('actor') ? JSON.parse(localStorage.getItem('actor')) : {},
3 | }
4 |
5 | const getters = {
6 | getActor: state => state.actor,
7 | }
8 |
9 | const mutations = {
10 | SET_ACTOR: (state, actor) => {
11 | state.actor = actor
12 | localStorage.setItem('actor', JSON.stringify(actor))
13 | },
14 | }
15 |
16 | export default {
17 | namespaced: false,
18 | state,
19 | mutations,
20 | getters
21 | }
22 |
--------------------------------------------------------------------------------
/src/store/modules/movie.js:
--------------------------------------------------------------------------------
1 | const state = {
2 | movie: localStorage.getItem('movie') ? JSON.parse(localStorage.getItem('movie')) : {},
3 | }
4 |
5 | const getters = {
6 | getMovie: state => state.movie,
7 | }
8 |
9 | const mutations = {
10 | SET_MOVIE: (state, movie) => {
11 | state.movie = movie
12 | localStorage.setItem('movie', JSON.stringify(movie))
13 | },
14 | }
15 |
16 | export default {
17 | namespaced: false,
18 | state,
19 | mutations,
20 | getters
21 | }
22 |
--------------------------------------------------------------------------------
/src/store/modules/user.js:
--------------------------------------------------------------------------------
1 | import { register, getUserToken, getUserInfo } from '@/api/user'
2 |
3 | const state = {
4 | token: localStorage.getItem('token') || '',
5 | user: localStorage.getItem('user') ? JSON.parse(localStorage.getItem('user')) : null,
6 | }
7 |
8 | const getters = {
9 | getUser: state => state.user,
10 | getToken: state => state.token
11 | }
12 |
13 | const mutations = {
14 | // 身份token
15 | SET_TOKEN: (state, token) => {
16 | state.token = token
17 | localStorage.setItem('token', token)
18 | },
19 | // 用户信息
20 | SET_USER: (state, user) => {
21 | state.user = user
22 | localStorage.setItem('user', JSON.stringify(user))
23 | },
24 | }
25 |
26 | const actions = {
27 | // user register
28 | async register({ commit }, form) {
29 | const { account, password, code } = form
30 |
31 | const res = await register({ account, password, code })
32 |
33 | if (res.code === 200) {
34 | commit('SET_TOKEN', res.data.token)
35 | }
36 | return res
37 | },
38 |
39 | // user login
40 | async login({ commit }, form) {
41 | const { account, password } = form
42 |
43 | const res = await getUserToken({ account, password })
44 |
45 | if (res.code === 200) {
46 | commit('SET_TOKEN', res.data.token)
47 | }
48 | return res
49 | },
50 |
51 | // get user info
52 | async getInfo({ commit }) {
53 |
54 | const res = await getUserInfo();
55 |
56 | if (res.code === 200) {
57 | commit('SET_USER', res.data)
58 | }
59 |
60 | return res
61 | }
62 | }
63 |
64 | export default {
65 | namespaced: true,
66 | state,
67 | mutations,
68 | actions,
69 | getters
70 | }
71 |
--------------------------------------------------------------------------------
/src/util/color.js:
--------------------------------------------------------------------------------
1 | export const colorToRgba = function (color, alpha) {
2 | // 16进制颜色值的正则
3 | let reg = /^#([0-9a-fA-f]{3}|[0-9a-fA-f]{6})$/;
4 |
5 | // 把颜色值变成小写
6 | color = color.toLowerCase();
7 |
8 | if (reg.test(color)) {
9 | // 如果只有三位的值,需变成六位,如:#fff => #ffffff
10 |
11 | if (color.length === 4) {
12 | let colorNew = "#";
13 | for (let i = 1; i < 4; i += 1) {
14 | colorNew += color.slice(i, i + 1).concat(color.slice(i, i + 1));
15 | }
16 | color = colorNew;
17 | }
18 |
19 | // 处理六位的颜色值,转为RGB
20 | let colorChange = [];
21 | for (let i = 1; i < 7; i += 2) {
22 | colorChange.push(parseInt("0x" + color.slice(i, i + 2)));
23 | }
24 | return `RGB(${colorChange.join(",")}, ${alpha})`;
25 | } else {
26 | return color;
27 | }
28 | };
--------------------------------------------------------------------------------
/src/util/index.js:
--------------------------------------------------------------------------------
1 | export const debounce = (func, wait = 200) => {
2 | let timeout;
3 | return function (event) {
4 | clearTimeout(timeout);
5 | timeout = setTimeout(() => {
6 | func.call(this, event);
7 | }, wait);
8 | };
9 | }
10 |
11 |
12 | export const throttle = (cb, wait = 1000 / 60) => {
13 | let last = 0;
14 | return function () {
15 | var now = new Date().getTime();;
16 | if (now - last > wait) {
17 | cb.call(this);
18 | last = new Date().getTime();;
19 | }
20 | }
21 | }
22 |
23 | // 格式化时间 将秒数转为 00:00 格式
24 | export const timeFormat = sec => {
25 | let min = 0;
26 | min = Math.floor(sec / 60); // 分
27 | min < 10 && (min = '0' + min); // 补零
28 | sec = Math.floor(sec % 60); // 秒
29 | sec < 10 && (sec = '0' + sec); // 补零
30 |
31 | return (min || '00') + ":" + sec;
32 | }
33 |
34 |
35 | export const dateBefore = (datatime) => {
36 | let dateTimeStamp = new Date(datatime).getTime()
37 |
38 | let minute = 1000 * 60;
39 | let hour = minute * 60;
40 | let day = hour * 24;
41 |
42 | let month = day * 30;
43 | let year = month * 12;
44 | let now = new Date().getTime();
45 | let diffValue = now - dateTimeStamp;
46 | let result = ""
47 |
48 | if (diffValue < 0) {
49 | return;
50 | }
51 |
52 | let monthC = diffValue / month;
53 | let weekC = diffValue / (7 * day);
54 | let dayC = diffValue / day;
55 | let hourC = diffValue / hour;
56 | let minC = diffValue / minute;
57 | let yearC = diffValue / year;
58 |
59 | if (yearC >= 1) {
60 | return "" + parseInt(yearC) + "年前";
61 | }
62 | if (monthC >= 1) {
63 | result = "" + parseInt(monthC) + "月前";
64 | } else if (weekC >= 1) {
65 | result = "" + parseInt(weekC) + "周前";
66 | } else if (dayC >= 1) {
67 | result = "" + parseInt(dayC) + "天前";
68 | } else if (hourC >= 1) {
69 | result = "" + parseInt(hourC) + "小时前";
70 | } else if (minC >= 1) {
71 | result = "" + parseInt(minC) + "分钟前";
72 | } else {
73 | result = "刚刚";
74 | }
75 |
76 | return result;
77 | }
78 |
79 | export const preventScroll = function (prevent = true) {
80 | if (prevent) {
81 | document.body.classList.add("overflow-hidden");
82 | } else {
83 | document.body.classList.remove("overflow-hidden");
84 | }
85 | }
--------------------------------------------------------------------------------
/src/views/404.vue:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
8 |
13 |
14 |
--------------------------------------------------------------------------------
/src/views/Layout.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
22 |
--------------------------------------------------------------------------------
/src/views/actor/award/components/AwardItem.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
{{ award.year }}年
4 |
5 |
6 |
7 |
第{{ item.session }}届 {{ item.award }}
8 |
9 | {{ item.type }} {{ item.win === 1 ? "(提名)" : "" }}
10 |
11 |
12 |
13 |
14 |
![]()
15 |
16 |
17 |
{{ item.movie.title }}
18 |
19 |
27 | {{ item.movie.rating }}
28 |
29 |
30 | {{ item.movie.year }} / {{ item.movie.genres }} /
31 | {{ item.movie.countries }}
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
50 |
51 |
--------------------------------------------------------------------------------
/src/views/actor/award/index.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/src/views/actor/detail/components/ActorAward.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
![]()
4 |
5 |
{{ award.title }}
6 |
{{ award.type_name }}
7 |
8 |
9 | 获奖{{ awardCount }}次
10 |
11 |
12 |
13 |
14 |
15 |
31 |
32 |
--------------------------------------------------------------------------------
/src/views/actor/detail/components/ActorCount.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
{{ actor.collection_count }}人
6 |
已关注数
7 |
8 |
9 |
{{ actor.works_count }}部
10 |
作品总数
11 |
12 |
13 |
{{ actor.role_count }}个
14 |
饰演角色
15 |
16 |
17 |
18 |
19 |
20 |
30 |
31 |
--------------------------------------------------------------------------------
/src/views/actor/detail/components/Skeleton.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
7 |
8 |
9 |
18 |
24 |
25 |
26 |
27 |
28 |
38 |
39 |
--------------------------------------------------------------------------------
/src/views/actor/detail/information.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
23 |
24 |
25 |
26 |
43 |
44 |
50 |
--------------------------------------------------------------------------------
/src/views/actor/role/index.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
54 |
55 |
73 |
--------------------------------------------------------------------------------
/src/views/actor/works/index.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
18 |
19 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
88 |
89 |
129 |
--------------------------------------------------------------------------------
/src/views/article/detail/components/Skeleton.vue:
--------------------------------------------------------------------------------
1 |
2 |
15 |
16 |
17 |
22 |
23 |
--------------------------------------------------------------------------------
/src/views/award/detail/components/AwardInfo.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
![]()
6 |
7 | {{ award.categories }}
8 | 始于{{ award.year }}年
9 | {{ award.country }}
10 |
11 |
12 |
13 |
{{ award.title }}
14 |
{{ award.original_title }}
15 |
{{ award.brief }}
16 |
17 |
18 |
19 |
36 |
37 |
--------------------------------------------------------------------------------
/src/views/award/detail/index.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
历届列表
16 |
22 | 第{{ award.session - n + 1 }}届
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
69 |
70 |
--------------------------------------------------------------------------------
/src/views/award/detail/info.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 | 简介:{{ award.brief }}
18 |
19 |
20 |
21 |
52 |
53 |
54 |
62 |
--------------------------------------------------------------------------------
/src/views/award/index/index.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
10 |
11 |
16 | {{ award.title }}
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
57 |
58 |
--------------------------------------------------------------------------------
/src/views/award/session/components/Skeleton.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
12 |
13 |
19 |
20 |
29 |
30 |
31 |
32 |
33 |
41 |
42 |
--------------------------------------------------------------------------------
/src/views/comment/components/CommentBar.vue:
--------------------------------------------------------------------------------
1 |
2 |
15 |
16 |
17 |
60 |
61 |
--------------------------------------------------------------------------------
/src/views/comment/components/CommentSkeleton.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
23 |
24 |
--------------------------------------------------------------------------------
/src/views/comment/components/CommentTool.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
108 |
109 |
--------------------------------------------------------------------------------
/src/views/demo.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 | {{ n }}
4 |
5 |
6 | 123
7 |
8 |
9 |
10 |
11 |
23 |
24 |
--------------------------------------------------------------------------------
/src/views/home/components/HomeMenu.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | -
5 |
6 |
7 |
8 | -
9 |
10 |
11 |
12 | -
13 |
14 |
15 |
16 | -
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
29 |
30 |
--------------------------------------------------------------------------------
/src/views/home/components/Skeleton.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
14 |
15 |
24 |
25 |
26 |
27 |
28 |
36 |
37 |
--------------------------------------------------------------------------------
/src/views/movie/coming.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 | {{ group.date }}
16 |
17 |
18 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
69 |
70 |
--------------------------------------------------------------------------------
/src/views/movie/detail/article/index.vue:
--------------------------------------------------------------------------------
1 |
2 |
15 |
16 |
17 |
35 |
36 |
--------------------------------------------------------------------------------
/src/views/movie/detail/award/components/AwardItem.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
![]()
6 |
7 |
8 |
第{{ award.session }}届 {{ award.award }}
9 |
{{ award.year }}年
10 |
11 |
12 |
13 |
14 |
15 | {{ item.type }} {{ item.win === 0 ? "(提名)" : "(获奖)" }}
16 |
17 |
18 | {{ actor.name }}
20 | {{ item.actors.length - 1 > index ? "/" : "" }}
22 |
23 |
24 |
25 |
26 |
27 |
28 |
39 |
40 |
--------------------------------------------------------------------------------
/src/views/movie/detail/award/index.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/src/views/movie/detail/cast/components/CastPanel.vue:
--------------------------------------------------------------------------------
1 |
2 |
14 |
15 |
16 |
39 |
40 |
--------------------------------------------------------------------------------
/src/views/movie/detail/cast/index.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
14 |
15 |
16 |
17 |
--------------------------------------------------------------------------------
/src/views/movie/detail/company/index.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
{{ item.type_zh }}
10 |
11 |
16 | {{ company.name }}
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
55 |
56 |
--------------------------------------------------------------------------------
/src/views/movie/detail/dialogue/index.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
17 |
18 |
19 |
20 |
38 |
39 |
--------------------------------------------------------------------------------
/src/views/movie/detail/index/components/MovieAward.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | {{ movie.awards_count }}
6 |
7 |
8 |
获奖
9 |
10 |
11 |
12 |
13 | {{ movie.awards_nominate_count }}
14 |
15 |
16 |
提名
17 |
18 |
19 |
20 |
{{ award.title }}
21 |
{{ award.info }}
22 |
23 |
24 |
25 |
26 |
53 |
54 |
--------------------------------------------------------------------------------
/src/views/movie/detail/index/components/MovieExtra.vue:
--------------------------------------------------------------------------------
1 |
2 |
47 |
48 |
49 |
65 |
66 |
--------------------------------------------------------------------------------
/src/views/movie/detail/index/components/PhotoWall.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
![]()
5 |
6 |
7 |
8 |
9 |
20 |
21 |
--------------------------------------------------------------------------------
/src/views/movie/detail/index/components/SerialRow.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
{{ serial.name }}
7 |
8 |
9 |
10 |
33 |
34 |
63 |
--------------------------------------------------------------------------------
/src/views/movie/detail/knowledge/index.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
17 |
18 |
19 |
20 |
38 |
39 |
--------------------------------------------------------------------------------
/src/views/movie/detail/level/index.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
{{ item.content }}
10 |
11 |
12 |
13 |
14 |
15 |
33 |
34 |
--------------------------------------------------------------------------------
/src/views/movie/detail/pubdate/index.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | {{ p.country }}
9 | {{ p.premiere ? "(首映)" : "" }}
11 |
12 |
13 |
14 |
32 |
33 |
--------------------------------------------------------------------------------
/src/views/movie/detail/rating/index.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | 评分分布功能因样本原因还在开发中,以下仅为示例数据
8 |
9 |
10 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
73 |
74 |
--------------------------------------------------------------------------------
/src/views/movie/detail/review/index.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
11 |
12 |
22 |
23 |
24 |
25 |
70 |
71 |
--------------------------------------------------------------------------------
/src/views/movie/detail/role/index.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
--------------------------------------------------------------------------------
/src/views/movie/detail/serial/components/SerialItem.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
{{ serial.name }}
7 |
{{ serial.name_en }}
8 |
影视数量 {{ serial.count }}
9 |
10 |
11 |
12 |
13 |
35 |
36 |
--------------------------------------------------------------------------------
/src/views/movie/detail/serial/index.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
13 |
14 |
15 |
16 |
17 |
--------------------------------------------------------------------------------
/src/views/movie/detail/video/index.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
18 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
86 |
87 |
--------------------------------------------------------------------------------
/src/views/movie/index/components/MenuSkeleton.vue:
--------------------------------------------------------------------------------
1 |
2 |
10 |
11 |
12 |
17 |
18 |
--------------------------------------------------------------------------------
/src/views/movie/index/components/MovieRow.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
![]()
5 |
6 | 全{{ movie.episode_count }}集
7 |
8 |
9 |
10 |
{{ movie.title }}
11 |
12 |
13 |
14 |
32 |
33 |
85 |
--------------------------------------------------------------------------------
/src/views/movie/index/components/MovieSkeleton.vue:
--------------------------------------------------------------------------------
1 |
2 |
10 |
11 |
12 |
17 |
18 |
--------------------------------------------------------------------------------
/src/views/movie/index/components/NavList.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 | -
9 | {{ item.name }}
10 |
11 |
12 |
13 |
14 |
36 |
37 |
--------------------------------------------------------------------------------
/src/views/movie/index/index.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
69 |
70 |
77 |
--------------------------------------------------------------------------------
/src/views/movie/serial/detail/components/SerialInfo.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
![]()
4 |
5 |
11 |
12 |
13 |
14 |
26 |
27 |
--------------------------------------------------------------------------------
/src/views/movie/serial/detail/index.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
15 |
16 |
17 |
18 |
19 |
53 |
54 |
60 |
--------------------------------------------------------------------------------
/src/views/movie/theater.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
31 |
32 |
--------------------------------------------------------------------------------
/src/views/movie/today.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
63 |
64 |
--------------------------------------------------------------------------------
/src/views/movie/top.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
37 |
38 |
--------------------------------------------------------------------------------
/src/views/offline.vue:
--------------------------------------------------------------------------------
1 |
2 |
19 |
20 |
21 |
46 |
47 |
--------------------------------------------------------------------------------
/src/views/photo/components/PhotoItem.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
16 |
17 |
--------------------------------------------------------------------------------
/src/views/profile/aboutus/author.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 | https://ixook.com
12 |
13 |
14 |
15 |
16 |
17 |
18 |
23 |
24 |
--------------------------------------------------------------------------------
/src/views/profile/aboutus/project.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 | vue2.6/vue-router/vuex/axios
10 |
11 |
12 |
13 | https://mind-ui-vue.ixook.com
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
28 |
29 |
--------------------------------------------------------------------------------
/src/views/profile/changelog/index.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
2022-10-23
10 |
11 |
1.优化影视、影人等页面 header-bar 显示效果
12 |
2.修复 tab-switch 由于组件库升级导致样式异常
13 |
3.收藏夹列表增加创建收藏夹入口
14 |
4.增加更新日志页面
15 |
5.其它一些样式优化
16 |
17 |
18 |
19 |
20 |
21 |
22 |
2022-10-22
23 |
24 | 修复 keep-alive 页面切换时滚动触底持续触发问题
25 |
26 |
27 |
28 |
29 |
30 |
31 |
2022-06-12
32 |
项目开发文档发布
33 |
34 |
35 |
36 |
37 |
38 |
2022-05-01
39 |
项目源码、在线演示版、接口文档发布
40 |
41 |
42 |
43 |
44 |
45 |
2022-03-27
46 |
项目初始化
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
59 |
60 |
--------------------------------------------------------------------------------
/src/views/profile/collection/actor/index.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
--------------------------------------------------------------------------------
/src/views/profile/collection/review/index.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
37 |
38 |
--------------------------------------------------------------------------------
/src/views/profile/collection/role/index.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
31 |
--------------------------------------------------------------------------------
/src/views/profile/collection/video/index.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
33 |
34 |
--------------------------------------------------------------------------------
/src/views/profile/feedback/index.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
8 |
9 |
10 |
11 |
17 |
{{ wordLength }}/{{ maxlength }}
18 |
19 |
20 |
提 交
29 |
30 |
31 |
32 |
33 |
79 |
80 |
--------------------------------------------------------------------------------
/src/views/profile/index/components/MineCell.vue:
--------------------------------------------------------------------------------
1 |
2 |
52 |
53 |
54 |
64 |
65 |
--------------------------------------------------------------------------------
/src/views/profile/index/components/MineMenu.vue:
--------------------------------------------------------------------------------
1 |
2 |
20 |
21 |
22 |
45 |
46 |
--------------------------------------------------------------------------------
/src/views/profile/index/index.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
89 |
--------------------------------------------------------------------------------
/src/views/profile/setting/index.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 | 退出登录
13 |
14 |
15 |
16 |
17 |
52 |
53 |
--------------------------------------------------------------------------------
/src/views/review/detail/components/Skeleton.vue:
--------------------------------------------------------------------------------
1 |
2 |
13 |
14 |
15 |
20 |
21 |
--------------------------------------------------------------------------------
/src/views/review/detail/components/ToolVote.vue:
--------------------------------------------------------------------------------
1 |
2 |
30 |
31 |
32 |
33 |
76 |
77 |
--------------------------------------------------------------------------------
/src/views/role/actor/index.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
10 |
11 |
12 |
13 |
14 |
32 |
33 |
38 |
--------------------------------------------------------------------------------
/src/views/role/detail/components/RoleCount.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
{{ role.collection_count }}人
6 |
关注数
7 |
8 |
9 |
{{ role.movie_count }}部
10 |
影视数
11 |
12 |
13 |
{{ role.actor_count }}个
14 |
影人数
15 |
16 |
17 |
18 |
19 |
20 |
30 |
31 |
--------------------------------------------------------------------------------
/src/views/role/detail/components/Skeleton.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
7 |
8 |
9 |
18 |
24 |
25 |
26 |
27 |
28 |
38 |
39 |
--------------------------------------------------------------------------------
/src/views/role/detail/information.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
14 |
15 |
21 |
22 |
23 |
24 |
25 |
28 |
29 |
30 |
31 |
51 |
52 |
58 |
--------------------------------------------------------------------------------
/src/views/role/movie/index.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
30 |
31 |
36 |
--------------------------------------------------------------------------------
/src/views/search/components/SearchHistory.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
历史记录
5 |
6 |
7 |
8 |
9 | -
15 | {{ keyword }}
16 |
17 |
18 |
19 |
20 |
21 |
58 |
59 |
--------------------------------------------------------------------------------
/src/views/search/components/SearchMenu.vue:
--------------------------------------------------------------------------------
1 |
2 |
16 |
17 |
18 |
23 |
24 |
--------------------------------------------------------------------------------
/src/views/video/detail/components/MVideo.vue:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
9 |
32 |
33 |
--------------------------------------------------------------------------------
/src/views/video/detail/components/Skeleton.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
16 |
17 |
18 |
19 |
20 |
25 |
26 |
--------------------------------------------------------------------------------
/src/views/video/detail/components/VideoRow.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
![]()
5 |
8 |
{{ video.duration | timeFormat }}
9 |
10 |
11 |
{{ video.title }}
12 |
13 |
14 |
15 |
26 |
27 |
--------------------------------------------------------------------------------
/src/views/video/index/components/VideoListSkeleton.vue:
--------------------------------------------------------------------------------
1 |
2 |
10 |
11 |
12 |
17 |
18 |
--------------------------------------------------------------------------------
/src/views/video/index/index.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
105 |
106 |
--------------------------------------------------------------------------------
/vue.config.js:
--------------------------------------------------------------------------------
1 | 'use strict'
2 | const path = require('path')
3 |
4 | function resolve(dir) {
5 | return path.join(__dirname, dir)
6 | }
7 |
8 |
9 | module.exports = {
10 | lintOnSave: false,
11 | productionSourceMap: false,
12 | outputDir: "html",
13 | publicPath: "/",
14 | devServer: {
15 | open: true,
16 | port: 8102
17 | },
18 | chainWebpack: (config) => {
19 | config.module
20 | .rule("scss")
21 | .oneOf("vue")
22 | .use("px2rem")
23 | .loader("px2rem-loader")
24 | .before("postcss-loader")
25 | .options({
26 | remUnit: 75,
27 | remPrecision: 8,
28 | })
29 | .end()
30 | .rule("js")
31 | .include.add("/packages")
32 | .end()
33 | .use("babel")
34 | .loader("babel-loader")
35 | .tap((options) => {
36 | return options;
37 | });
38 | },
39 | configureWebpack: {
40 | // provide the app's title in webpack's name field, so that
41 | // it can be accessed in index.html to inject the correct title.
42 | resolve: {
43 | alias: {
44 | '@': resolve('src'),
45 | 'images': resolve('src/assets/images'),
46 | }
47 | }
48 | },
49 | css: {
50 | extract: true,
51 | sourceMap: false,
52 | requireModuleExtension: true,
53 | loaderOptions: {
54 | // css: {
55 | // // 这里的选项会传递给 css-loader
56 | // importLoaders: 1,
57 | // },
58 | sass: {
59 | additionalData: `@import "@/assets/styles/variables.scss";`,
60 | },
61 | },
62 | },
63 | };
64 |
--------------------------------------------------------------------------------