├── pages └── douban │ ├── detail │ ├── detail.json │ ├── detail.wxss │ ├── detail.js │ └── detail.wxml │ ├── coming_soon │ ├── coming_soon.wxss │ ├── coming_soon.json │ ├── coming_soon.js │ └── coming_soon.wxml │ ├── in_theathers │ ├── in_theathers.wxss │ ├── in_theathers.json │ ├── in_theathers.js │ └── in_theathers.wxml │ ├── store.js │ ├── config.js │ └── functions.js ├── image ├── ing.png ├── coming.png ├── preview.gif ├── ing-active.png └── coming-active.png ├── app.js ├── readme.md ├── utils └── util.js ├── app.json └── app.wxss /pages/douban/detail/detail.json: -------------------------------------------------------------------------------- 1 | {} -------------------------------------------------------------------------------- /pages/douban/coming_soon/coming_soon.wxss: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /pages/douban/in_theathers/in_theathers.wxss: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /pages/douban/store.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | location: null 3 | } -------------------------------------------------------------------------------- /image/ing.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hingsir/weapp-douban-film/HEAD/image/ing.png -------------------------------------------------------------------------------- /pages/douban/coming_soon/coming_soon.json: -------------------------------------------------------------------------------- 1 | { 2 | "enablePullDownRefresh": true 3 | } -------------------------------------------------------------------------------- /pages/douban/in_theathers/in_theathers.json: -------------------------------------------------------------------------------- 1 | { 2 | "enablePullDownRefresh": true 3 | } -------------------------------------------------------------------------------- /image/coming.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hingsir/weapp-douban-film/HEAD/image/coming.png -------------------------------------------------------------------------------- /image/preview.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hingsir/weapp-douban-film/HEAD/image/preview.gif -------------------------------------------------------------------------------- /pages/douban/config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | baiduAK: '7VENmCeC4aaAfx3CKbSjT1K3oRucOgDK' 3 | } -------------------------------------------------------------------------------- /image/ing-active.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hingsir/weapp-douban-film/HEAD/image/ing-active.png -------------------------------------------------------------------------------- /image/coming-active.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hingsir/weapp-douban-film/HEAD/image/coming-active.png -------------------------------------------------------------------------------- /app.js: -------------------------------------------------------------------------------- 1 | App({ 2 | onLaunch: function () { 3 | }, 4 | onShow: function () { 5 | }, 6 | onHide: function () { 7 | }, 8 | globalData: { 9 | } 10 | }) 11 | -------------------------------------------------------------------------------- /readme.md: -------------------------------------------------------------------------------- 1 | # 微信小程序 - 豆瓣电影 2 | 3 | 如果要在手机上预览,因为程序包大小限制,需删掉`image/preview.gif`,并且需在公众号设置域名: 4 | ``` 5 | https://api.map.baidu.com 6 | https://api.douban.com 7 | ``` 8 | 9 | ![image/preview.gif](image/preview.gif) 10 | -------------------------------------------------------------------------------- /pages/douban/detail/detail.wxss: -------------------------------------------------------------------------------- 1 | .film-detail .film-info{ 2 | line-height: 1.2; 3 | } 4 | .film-detail .film-info view{ 5 | margin-bottom: 6px; 6 | } 7 | .summary{ 8 | padding: 0 10px; 9 | } 10 | .summary .title{ 11 | font-size: 16px; 12 | margin: 15px 0; 13 | } 14 | .summary .content{ 15 | text-indent: 2em; 16 | } 17 | .collect-wish view{ 18 | display: inline-block; 19 | } 20 | .collect-wish view:first-child{ 21 | margin-right: 5px; 22 | } 23 | .collect-wish text{ 24 | color: #666; 25 | } -------------------------------------------------------------------------------- /pages/douban/detail/detail.js: -------------------------------------------------------------------------------- 1 | Page({ 2 | data: { 3 | film: {}, 4 | showLoading: true, 5 | options: null 6 | }, 7 | onLoad: function (options) { 8 | var that = this 9 | wx.setNavigationBarTitle({ 10 | title: options.title 11 | }) 12 | wx.request({ 13 | url: 'https://api.douban.com/v2/movie/subject/' + options.id, 14 | header: { 15 | 'content-type': 'json' 16 | }, 17 | success: function (res) { 18 | var data = res.data 19 | that.setData({ 20 | film: data, 21 | showLoading: false 22 | }) 23 | } 24 | }) 25 | } 26 | }) 27 | -------------------------------------------------------------------------------- /utils/util.js: -------------------------------------------------------------------------------- 1 | function formatTime(date) { 2 | var year = date.getFullYear() 3 | var month = date.getMonth() + 1 4 | var day = date.getDate() 5 | 6 | var hour = date.getHours() 7 | var minute = date.getMinutes() 8 | var second = date.getSeconds(); 9 | 10 | 11 | return [year, month, day].map(formatNumber).join('/') + ' ' + [hour, minute, second].map(formatNumber).join(':') 12 | } 13 | 14 | function formatNumber(n) { 15 | n = n.toString() 16 | return n[1] ? n : '0' + n 17 | } 18 | 19 | function formatLocation(longitude, latitude) { 20 | longitude = longitude.toFixed(2) 21 | latitude = latitude.toFixed(2) 22 | 23 | return { 24 | longitude: longitude.toString().split('.'), 25 | latitude: latitude.toString().split('.') 26 | } 27 | } 28 | 29 | module.exports = { 30 | formatTime: formatTime, 31 | formatLocation: formatLocation 32 | } 33 | -------------------------------------------------------------------------------- /app.json: -------------------------------------------------------------------------------- 1 | { 2 | "pages":[ 3 | "pages/douban/in_theathers/in_theathers", 4 | "pages/douban/coming_soon/coming_soon", 5 | "pages/douban/detail/detail" 6 | ], 7 | "tabBar": { 8 | "color": "#666", 9 | "selectedColor": "#268dcd", 10 | "borderStyle": "white", 11 | "backgroundColor": "#fafafa", 12 | "list": [{ 13 | "pagePath": "pages/douban/in_theathers/in_theathers", 14 | "iconPath": "image/ing.png", 15 | "selectedIconPath": "image/ing-active.png", 16 | "text": "正在热映" 17 | },{ 18 | "pagePath": "pages/douban/coming_soon/coming_soon", 19 | "iconPath": "image/coming.png", 20 | "selectedIconPath": "image/coming-active.png", 21 | "text": "即将上映" 22 | }] 23 | }, 24 | "window":{ 25 | "backgroundTextStyle":"light", 26 | "navigationBarBackgroundColor": "#268dcd", 27 | "navigationBarTitleText": "豆瓣电影", 28 | "navigationBarTextStyle":"white", 29 | "enablePullDownRefresh": true 30 | }, 31 | "debug": true 32 | } 33 | -------------------------------------------------------------------------------- /pages/douban/in_theathers/in_theathers.js: -------------------------------------------------------------------------------- 1 | var functions = require('../functions.js') 2 | var url = 'https://api.douban.com/v2/movie/in_theaters' 3 | var pageSize = 20 4 | Page({ 5 | data: { 6 | films: [], 7 | hasMore: true, 8 | showLoading: true, 9 | start: 0 10 | }, 11 | onPullDownRefresh: function () { 12 | console.log('onPullDownRefresh', new Date()) 13 | }, 14 | scroll: function (e) { 15 | //console.log(e) 16 | }, 17 | onLoad: function () { 18 | var that = this 19 | functions.getCity(function (city) { 20 | functions.fetchFilms.call(that, url, city, 0, pageSize, function (data) { 21 | that.setData({ 22 | showLoading: false 23 | }) 24 | }) 25 | }) 26 | }, 27 | scrolltolower: function () { 28 | var that = this 29 | functions.getCity(function (city) { 30 | functions.fetchFilms.call(that, url, city, that.data.start, pageSize, function (data) { }) 31 | }) 32 | }, 33 | viewDetail: function (e) { 34 | var ds = e.currentTarget.dataset; 35 | wx.navigateTo({ 36 | url: '../detail/detail?id=' + ds.id + '&title=' + ds.title + '&type=ing' 37 | }) 38 | } 39 | }) 40 | -------------------------------------------------------------------------------- /pages/douban/coming_soon/coming_soon.js: -------------------------------------------------------------------------------- 1 | var functions = require('../functions.js') 2 | var url = 'https://api.douban.com/v2/movie/coming_soon' 3 | var pageSize = 20 4 | Page({ 5 | data: { 6 | films: [], 7 | hasMore: true, 8 | showLoading: true, 9 | loadMoreLoading: false, 10 | start: 0 11 | }, 12 | onPullDownRefresh: function () { 13 | }, 14 | scroll: function(e){ 15 | //console.log(e) 16 | }, 17 | onLoad: function () { 18 | var that = this 19 | functions.getCity(function(city){ 20 | functions.fetchFilms.call(that, url, city, 0, pageSize, function(data){ 21 | that.setData({ 22 | showLoading: false 23 | }) 24 | }) 25 | }) 26 | }, 27 | loadMore: function(){ 28 | var that = this 29 | functions.getCity(function(city){ 30 | that.setData({ 31 | loadMoreLoading: true 32 | }) 33 | functions.fetchFilms.call(that, url, city, that.data.start, pageSize, function(data){ 34 | that.setData({ 35 | loadMoreLoading: false 36 | }) 37 | }) 38 | }) 39 | }, 40 | viewDetail: function(e){ 41 | var ds = e.currentTarget.dataset; 42 | wx.navigateTo({ 43 | url: '../detail/detail?id=' + ds.id + '&title=' + ds.title + '&type=coming' 44 | }) 45 | } 46 | }) 47 | -------------------------------------------------------------------------------- /pages/douban/functions.js: -------------------------------------------------------------------------------- 1 | var store = require('./store.js') 2 | var config = require('./config.js') 3 | module.exports = { 4 | getLocation: function (cb) { 5 | var location = store.location 6 | if (location) { 7 | cb(location) 8 | return; 9 | } 10 | wx.getLocation({ 11 | success: function (res) { 12 | var locationParam = res.latitude + ',' + res.longitude 13 | wx.request({ 14 | url: 'https://api.map.baidu.com/geocoder/v2/?ak=' + config.baiduAK + '&location=' + locationParam + '1&output=json&pois=1', 15 | header: { 16 | "Content-Type": "json", 17 | }, 18 | success: function (res) { 19 | var data = res.data 20 | store.location = data.result 21 | cb(data.result) 22 | } 23 | }) 24 | } 25 | }) 26 | }, 27 | getCity: function (cb) { 28 | this.getLocation(function (location) { 29 | cb(location.addressComponent.city.replace('市', '')) 30 | }) 31 | }, 32 | fetchFilms: function (url, city, start, count, cb) { 33 | var that = this 34 | wx.request({ 35 | url: url + '?city=' + city + '&start=' + start + '&count=' + count, 36 | header: { 37 | "Content-Type": "json", 38 | }, 39 | success: function (res) { 40 | var data = res.data 41 | if (data.subjects.length === 0) { 42 | that.setData({ 43 | hasMore: false, 44 | }) 45 | } else { 46 | that.setData({ 47 | films: that.data.films.concat(data.subjects), 48 | start: that.data.start + data.subjects.length 49 | }) 50 | } 51 | cb(data) 52 | } 53 | }) 54 | } 55 | } -------------------------------------------------------------------------------- /pages/douban/in_theathers/in_theathers.wxml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 玩命加载中 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | {{film.title}} 16 | {{film.year}} 17 | 18 | 19 | 20 | 评分 21 | {{film.rating.average}} 22 | 23 | 24 | 暂无评分 25 | 26 | 27 | 28 | 导演 29 | 30 | {{director.name}} 31 | 32 | 33 | 34 | 主演 35 | 36 | {{cast.name}} 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 玩命加载中 46 | 47 | 48 | 49 | 50 | 没有更多内容了 51 | 52 | 53 | 54 | 55 | 56 | 57 | -------------------------------------------------------------------------------- /pages/douban/coming_soon/coming_soon.wxml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 玩命加载中 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | {{film.title}} 16 | {{film.year}} 17 | 18 | 19 | 20 | 评分 21 | {{film.rating.average}} 22 | 23 | 24 | 暂无评分 25 | 26 | 27 | 28 | 导演 29 | 30 | {{director.name}} 31 | 32 | 33 | 34 | 主演 35 | 36 | {{cast.name}} 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 玩命加载中 47 | 48 | 49 | 50 | 51 | 点击加载更多 52 | 53 | 54 | 55 | 56 | 57 | 没有更多内容了 58 | 59 | 60 | 61 | 62 | 63 | -------------------------------------------------------------------------------- /pages/douban/detail/detail.wxml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 玩命加载中 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | {{film.title}} 16 | {{film.year}} 17 | 18 | 19 | 20 | 评分: 21 | {{film.rating.average}} 22 | 23 | 24 | 暂无评分 25 | 26 | 27 | 28 | 导演: 29 | 30 | {{director.name}} 31 | 32 | 33 | 34 | 主演: 35 | 36 | {{cast.name}} 37 | 38 | 39 | 40 | 类型: 41 | 42 | {{genre}} 43 | 44 | 45 | 46 | 国家/地区: 47 | 48 | {{country}} 49 | 50 | 51 | 52 | 53 | 看过( 54 | {{film.collect_count}}) 55 | 56 | 57 | 想看( 58 | {{film.wish_count}}) 59 | 60 | 61 | 62 | 63 | 64 | 剧情简介 65 | 66 | {{film.summary}} 67 | 68 | 69 | 70 | -------------------------------------------------------------------------------- /app.wxss: -------------------------------------------------------------------------------- 1 | /**app.wxss**/ 2 | page{ 3 | height: 100%; 4 | } 5 | .clearfix{ 6 | zoom: 1; 7 | } 8 | .clearfix:after{ 9 | content:''; 10 | display: table; 11 | clear:both; 12 | } 13 | .hide{ 14 | display: none !important; 15 | } 16 | .container { 17 | display: flex; 18 | flex-direction: column; 19 | align-items: center; 20 | justify-content: space-between; 21 | box-sizing: border-box; 22 | font-family: "Helvetica Neue",Arial,"PingFang SC","Microsoft YaHei",sans-serif; 23 | font-size: 14px; 24 | line-height: 1.5; 25 | color: #333; 26 | } 27 | .film-item{ 28 | padding: 10px; 29 | display: flex; 30 | } 31 | .film-image{ 32 | width: 128px; 33 | } 34 | .film-image image{ 35 | width: 100%; 36 | height: 180px; 37 | } 38 | .film-info{ 39 | padding-left: 10px; 40 | flex: 1; 41 | } 42 | .film-info view{ 43 | margin-bottom: 10px; 44 | } 45 | .film-info .label{ 46 | margin-right: 5px; 47 | color: #666; 48 | } 49 | .film-info .rating{ 50 | color: #e09015; 51 | } 52 | .film-title{ 53 | font-size: 18px; 54 | margin-right: 10px; 55 | } 56 | .film-year{ 57 | font-size: 16px; 58 | color: #999; 59 | } 60 | .person{ 61 | margin-right: 5px; 62 | } 63 | .page-loading{ 64 | position: absolute; 65 | top: 50%; 66 | left: 50%; 67 | transform: translate(-50%,-50%); 68 | font-size: 14px; 69 | color: #666; 70 | } 71 | .page-loading .loading-text{ 72 | display: inline-block; 73 | vertical-align: middle; 74 | } 75 | .weui-loading { 76 | width: 20px; 77 | height: 20px; 78 | display: inline-block; 79 | vertical-align: middle; 80 | -webkit-animation: weuiLoading 1s steps(12, end) infinite; 81 | animation: weuiLoading 1s steps(12, end) infinite; 82 | background: transparent url(data:image/svg+xml;base64,PHN2ZyBjbGFzcz0iciIgd2lkdGg9JzEyMHB4JyBoZWlnaHQ9JzEyMHB4JyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAxMDAgMTAwIj4KICAgIDxyZWN0IHg9IjAiIHk9IjAiIHdpZHRoPSIxMDAiIGhlaWdodD0iMTAwIiBmaWxsPSJub25lIiBjbGFzcz0iYmsiPjwvcmVjdD4KICAgIDxyZWN0IHg9JzQ2LjUnIHk9JzQwJyB3aWR0aD0nNycgaGVpZ2h0PScyMCcgcng9JzUnIHJ5PSc1JyBmaWxsPScjRTlFOUU5JwogICAgICAgICAgdHJhbnNmb3JtPSdyb3RhdGUoMCA1MCA1MCkgdHJhbnNsYXRlKDAgLTMwKSc+CiAgICA8L3JlY3Q+CiAgICA8cmVjdCB4PSc0Ni41JyB5PSc0MCcgd2lkdGg9JzcnIGhlaWdodD0nMjAnIHJ4PSc1JyByeT0nNScgZmlsbD0nIzk4OTY5NycKICAgICAgICAgIHRyYW5zZm9ybT0ncm90YXRlKDMwIDUwIDUwKSB0cmFuc2xhdGUoMCAtMzApJz4KICAgICAgICAgICAgICAgICByZXBlYXRDb3VudD0naW5kZWZpbml0ZScvPgogICAgPC9yZWN0PgogICAgPHJlY3QgeD0nNDYuNScgeT0nNDAnIHdpZHRoPSc3JyBoZWlnaHQ9JzIwJyByeD0nNScgcnk9JzUnIGZpbGw9JyM5Qjk5OUEnCiAgICAgICAgICB0cmFuc2Zvcm09J3JvdGF0ZSg2MCA1MCA1MCkgdHJhbnNsYXRlKDAgLTMwKSc+CiAgICAgICAgICAgICAgICAgcmVwZWF0Q291bnQ9J2luZGVmaW5pdGUnLz4KICAgIDwvcmVjdD4KICAgIDxyZWN0IHg9JzQ2LjUnIHk9JzQwJyB3aWR0aD0nNycgaGVpZ2h0PScyMCcgcng9JzUnIHJ5PSc1JyBmaWxsPScjQTNBMUEyJwogICAgICAgICAgdHJhbnNmb3JtPSdyb3RhdGUoOTAgNTAgNTApIHRyYW5zbGF0ZSgwIC0zMCknPgogICAgPC9yZWN0PgogICAgPHJlY3QgeD0nNDYuNScgeT0nNDAnIHdpZHRoPSc3JyBoZWlnaHQ9JzIwJyByeD0nNScgcnk9JzUnIGZpbGw9JyNBQkE5QUEnCiAgICAgICAgICB0cmFuc2Zvcm09J3JvdGF0ZSgxMjAgNTAgNTApIHRyYW5zbGF0ZSgwIC0zMCknPgogICAgPC9yZWN0PgogICAgPHJlY3QgeD0nNDYuNScgeT0nNDAnIHdpZHRoPSc3JyBoZWlnaHQ9JzIwJyByeD0nNScgcnk9JzUnIGZpbGw9JyNCMkIyQjInCiAgICAgICAgICB0cmFuc2Zvcm09J3JvdGF0ZSgxNTAgNTAgNTApIHRyYW5zbGF0ZSgwIC0zMCknPgogICAgPC9yZWN0PgogICAgPHJlY3QgeD0nNDYuNScgeT0nNDAnIHdpZHRoPSc3JyBoZWlnaHQ9JzIwJyByeD0nNScgcnk9JzUnIGZpbGw9JyNCQUI4QjknCiAgICAgICAgICB0cmFuc2Zvcm09J3JvdGF0ZSgxODAgNTAgNTApIHRyYW5zbGF0ZSgwIC0zMCknPgogICAgPC9yZWN0PgogICAgPHJlY3QgeD0nNDYuNScgeT0nNDAnIHdpZHRoPSc3JyBoZWlnaHQ9JzIwJyByeD0nNScgcnk9JzUnIGZpbGw9JyNDMkMwQzEnCiAgICAgICAgICB0cmFuc2Zvcm09J3JvdGF0ZSgyMTAgNTAgNTApIHRyYW5zbGF0ZSgwIC0zMCknPgogICAgPC9yZWN0PgogICAgPHJlY3QgeD0nNDYuNScgeT0nNDAnIHdpZHRoPSc3JyBoZWlnaHQ9JzIwJyByeD0nNScgcnk9JzUnIGZpbGw9JyNDQkNCQ0InCiAgICAgICAgICB0cmFuc2Zvcm09J3JvdGF0ZSgyNDAgNTAgNTApIHRyYW5zbGF0ZSgwIC0zMCknPgogICAgPC9yZWN0PgogICAgPHJlY3QgeD0nNDYuNScgeT0nNDAnIHdpZHRoPSc3JyBoZWlnaHQ9JzIwJyByeD0nNScgcnk9JzUnIGZpbGw9JyNEMkQyRDInCiAgICAgICAgICB0cmFuc2Zvcm09J3JvdGF0ZSgyNzAgNTAgNTApIHRyYW5zbGF0ZSgwIC0zMCknPgogICAgPC9yZWN0PgogICAgPHJlY3QgeD0nNDYuNScgeT0nNDAnIHdpZHRoPSc3JyBoZWlnaHQ9JzIwJyByeD0nNScgcnk9JzUnIGZpbGw9JyNEQURBREEnCiAgICAgICAgICB0cmFuc2Zvcm09J3JvdGF0ZSgzMDAgNTAgNTApIHRyYW5zbGF0ZSgwIC0zMCknPgogICAgPC9yZWN0PgogICAgPHJlY3QgeD0nNDYuNScgeT0nNDAnIHdpZHRoPSc3JyBoZWlnaHQ9JzIwJyByeD0nNScgcnk9JzUnIGZpbGw9JyNFMkUyRTInCiAgICAgICAgICB0cmFuc2Zvcm09J3JvdGF0ZSgzMzAgNTAgNTApIHRyYW5zbGF0ZSgwIC0zMCknPgogICAgPC9yZWN0Pgo8L3N2Zz4=) no-repeat; 83 | background-size: 100%; 84 | } 85 | .load-more-wrap{ 86 | text-align: center; 87 | padding: 10px 20px 20px 20px; 88 | } 89 | .load-content{ 90 | padding: 5px; 91 | color: #666; 92 | } 93 | .btn-load-more text{ 94 | display: block; 95 | padding: 5px; 96 | border-radius: 3px; 97 | background: #e6e6e6; 98 | color: #666; 99 | text-align: center; 100 | } --------------------------------------------------------------------------------