├── .gitignore
├── src
├── pages
│ ├── about
│ │ ├── about.wxss
│ │ ├── about.json
│ │ ├── about.js
│ │ └── about.wxml
│ ├── home
│ │ ├── home.json
│ │ ├── home.wxml
│ │ ├── home.wxss
│ │ └── home.js
│ ├── my
│ │ ├── my.json
│ │ ├── my.wxss
│ │ ├── my.js
│ │ └── my.wxml
│ ├── detail
│ │ ├── detail.json
│ │ ├── detail.wxml
│ │ ├── detail.js
│ │ └── detail.wxss
│ ├── logs
│ │ ├── logs.json
│ │ ├── logs.wxss
│ │ ├── logs.wxml
│ │ └── logs.js
│ ├── books
│ │ ├── books.json
│ │ ├── books.wxml
│ │ ├── books.wxss
│ │ └── books.js
│ ├── comment
│ │ ├── comment.json
│ │ ├── comment.wxss
│ │ ├── comment.wxml
│ │ └── comment.js
│ ├── today
│ │ ├── today.json
│ │ ├── today.wxml
│ │ ├── today.wxss
│ │ └── today.js
│ ├── commentList
│ │ ├── commentList.json
│ │ ├── commentList.js
│ │ ├── commentList.wxml
│ │ └── commentList.wxss
│ └── index
│ │ ├── index.wxss
│ │ ├── index.wxml
│ │ └── index.js
├── images
│ ├── my.png
│ ├── book.png
│ ├── login.png
│ ├── sad.png
│ ├── bought.png
│ ├── bookstore.png
│ ├── luckyCoin.png
│ ├── mySelected.png
│ └── bookSelected.png
├── utils
│ ├── file.js
│ ├── util.js
│ ├── tip.js
│ ├── cache.js
│ ├── navigator.js
│ └── http.js
├── config
│ ├── const.js
│ └── config.js
├── project.config.json
├── app.json
├── app.wxss
└── app.js
├── readme
├── home.png
├── my.png
├── books.png
├── detail.png
├── scan1.jpg
└── scan2.jpg
└── README.md
/.gitignore:
--------------------------------------------------------------------------------
1 | .svn/
2 |
--------------------------------------------------------------------------------
/src/pages/about/about.wxss:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/src/pages/home/home.json:
--------------------------------------------------------------------------------
1 | {
2 | "navigationBarTitleText": "首页"
3 | }
--------------------------------------------------------------------------------
/src/pages/my/my.json:
--------------------------------------------------------------------------------
1 | {
2 | "navigationBarTitleText": "我的"
3 | }
--------------------------------------------------------------------------------
/src/pages/about/about.json:
--------------------------------------------------------------------------------
1 | {
2 | "navigationBarTitleText": "关于"
3 | }
--------------------------------------------------------------------------------
/src/pages/detail/detail.json:
--------------------------------------------------------------------------------
1 | {
2 | "navigationBarTitleText": "详情页"
3 | }
--------------------------------------------------------------------------------
/src/pages/logs/logs.json:
--------------------------------------------------------------------------------
1 | {
2 | "navigationBarTitleText": "查看启动日志"
3 | }
--------------------------------------------------------------------------------
/src/pages/books/books.json:
--------------------------------------------------------------------------------
1 | {
2 | "navigationBarTitleText": "图书列表"
3 | }
--------------------------------------------------------------------------------
/src/pages/comment/comment.json:
--------------------------------------------------------------------------------
1 | {
2 | "navigationBarTitleText": "评论"
3 | }
--------------------------------------------------------------------------------
/src/pages/today/today.json:
--------------------------------------------------------------------------------
1 | {
2 | "navigationBarTitleText": "历史上的今天"
3 | }
--------------------------------------------------------------------------------
/src/pages/commentList/commentList.json:
--------------------------------------------------------------------------------
1 | {
2 | "navigationBarTitleText": "评论列表"
3 | }
--------------------------------------------------------------------------------
/readme/home.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/liqingwen2015/ituring_small_bookshelf/HEAD/readme/home.png
--------------------------------------------------------------------------------
/readme/my.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/liqingwen2015/ituring_small_bookshelf/HEAD/readme/my.png
--------------------------------------------------------------------------------
/readme/books.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/liqingwen2015/ituring_small_bookshelf/HEAD/readme/books.png
--------------------------------------------------------------------------------
/readme/detail.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/liqingwen2015/ituring_small_bookshelf/HEAD/readme/detail.png
--------------------------------------------------------------------------------
/readme/scan1.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/liqingwen2015/ituring_small_bookshelf/HEAD/readme/scan1.jpg
--------------------------------------------------------------------------------
/readme/scan2.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/liqingwen2015/ituring_small_bookshelf/HEAD/readme/scan2.jpg
--------------------------------------------------------------------------------
/src/images/my.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/liqingwen2015/ituring_small_bookshelf/HEAD/src/images/my.png
--------------------------------------------------------------------------------
/src/images/book.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/liqingwen2015/ituring_small_bookshelf/HEAD/src/images/book.png
--------------------------------------------------------------------------------
/src/images/login.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/liqingwen2015/ituring_small_bookshelf/HEAD/src/images/login.png
--------------------------------------------------------------------------------
/src/images/sad.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/liqingwen2015/ituring_small_bookshelf/HEAD/src/images/sad.png
--------------------------------------------------------------------------------
/src/images/bought.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/liqingwen2015/ituring_small_bookshelf/HEAD/src/images/bought.png
--------------------------------------------------------------------------------
/src/images/bookstore.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/liqingwen2015/ituring_small_bookshelf/HEAD/src/images/bookstore.png
--------------------------------------------------------------------------------
/src/images/luckyCoin.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/liqingwen2015/ituring_small_bookshelf/HEAD/src/images/luckyCoin.png
--------------------------------------------------------------------------------
/src/images/mySelected.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/liqingwen2015/ituring_small_bookshelf/HEAD/src/images/mySelected.png
--------------------------------------------------------------------------------
/src/images/bookSelected.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/liqingwen2015/ituring_small_bookshelf/HEAD/src/images/bookSelected.png
--------------------------------------------------------------------------------
/src/pages/about/about.js:
--------------------------------------------------------------------------------
1 | Page({
2 |
3 | /**
4 | * 页面的初始数据
5 | */
6 | data: {
7 |
8 | },
9 |
10 |
11 | });
--------------------------------------------------------------------------------
/src/pages/logs/logs.wxss:
--------------------------------------------------------------------------------
1 | .log-list {
2 | display: flex;
3 | flex-direction: column;
4 | padding: 40rpx;
5 | }
6 | .log-item {
7 | margin: 10rpx;
8 | }
9 |
--------------------------------------------------------------------------------
/src/pages/logs/logs.wxml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | {{index + 1}}. {{log}}
5 |
6 |
7 |
--------------------------------------------------------------------------------
/src/pages/comment/comment.wxss:
--------------------------------------------------------------------------------
1 | /* pages/comment/comment.wxss */
2 | .comment-container {
3 | display: flex;
4 | flex-direction: column;
5 | padding: 20rpx 0;
6 | }
7 |
8 | .book-name {
9 | padding: 10rpx 30rpx;
10 | }
11 |
12 | .comment-area {
13 | /* margin-top: 20rpx; */
14 | padding: 20rpx 30rpx;
15 | height: 900rpx;
16 | }
--------------------------------------------------------------------------------
/src/pages/logs/logs.js:
--------------------------------------------------------------------------------
1 | //logs.js
2 | const util = require('../../utils/util.js')
3 |
4 | Page({
5 | data: {
6 | logs: []
7 | },
8 | onLoad: function () {
9 | this.setData({
10 | logs: (wx.getStorageSync('logs') || []).map(log => {
11 | return util.formatTime(new Date(log))
12 | })
13 | })
14 | }
15 | })
16 |
--------------------------------------------------------------------------------
/src/pages/index/index.wxss:
--------------------------------------------------------------------------------
1 | /**index.wxss**/
2 | .userinfo {
3 | display: flex;
4 | flex-direction: column;
5 | align-items: center;
6 | }
7 |
8 | .userinfo-avatar {
9 | width: 128rpx;
10 | height: 128rpx;
11 | margin: 20rpx;
12 | border-radius: 50%;
13 | }
14 |
15 | .userinfo-nickname {
16 | color: #aaa;
17 | }
18 |
19 | .usermotto {
20 | margin-top: 200px;
21 | }
--------------------------------------------------------------------------------
/src/utils/file.js:
--------------------------------------------------------------------------------
1 | // 文件
2 |
3 | // 新开页面打开文档,支持格式:doc, xls, ppt, pdf, docx, xlsx, pptx
4 | const openDocument = (filePath) => {
5 | wx.openDocument({
6 | filePath: filePath,
7 | success: function (res) {
8 | //console.log('打开文档成功')
9 | }
10 | })
11 | }
12 |
13 |
14 |
15 | module.exports = {
16 | openDocument: openDocument,
17 |
18 | }
--------------------------------------------------------------------------------
/src/pages/about/about.wxml:
--------------------------------------------------------------------------------
1 |
2 | 小编QQ:408448945
3 | 开始时间:2018-07-14
4 | 最后更新时间:2018-07-18
5 | v1.1:增加功能-历史上的今天
6 | v1.0.1:修复缓存文件名称
7 | v1.0:修复下载功能
8 | 由于作者的水平和智商等原因,请容忍该作品的不完善之处!
9 |
--------------------------------------------------------------------------------
/src/pages/index/index.wxml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | {{userInfo.nickName}}
8 |
9 |
10 |
11 | {{motto}}
12 |
13 |
14 |
--------------------------------------------------------------------------------
/src/utils/util.js:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | const formatTime = date => {
5 | const year = date.getFullYear()
6 | const month = date.getMonth() + 1
7 | const day = date.getDate()
8 | const hour = date.getHours()
9 | const minute = date.getMinutes()
10 | const second = date.getSeconds()
11 |
12 | return [year, month, day].map(formatNumber).join('/') + ' ' + [hour, minute, second].map(formatNumber).join(':')
13 | }
14 |
15 | const formatNumber = n => {
16 | n = n.toString()
17 | return n[1] ? n : '0' + n
18 | }
19 |
20 | module.exports = {
21 | formatTime: formatTime
22 | }
--------------------------------------------------------------------------------
/src/utils/tip.js:
--------------------------------------------------------------------------------
1 | // 提示
2 |
3 | // 显示消息提示框
4 | const showToast = (title, icon = 'none', callback = () => {}) => {
5 | wx.showToast({
6 | title: title,
7 | icon: icon,
8 | duration: 2000,
9 | mask: true,
10 | success: callback
11 | });
12 |
13 | }
14 |
15 | // 显示模态弹窗
16 | const showModal = (title, content, callback = () => {}) => {
17 | wx.showModal({
18 | title: title,
19 | content: content,
20 | success: callback
21 | });
22 |
23 | }
24 |
25 | module.exports = {
26 | showToast: showToast,
27 | showModal: showModal
28 | }
--------------------------------------------------------------------------------
/src/config/const.js:
--------------------------------------------------------------------------------
1 | // Key 名
2 | module.exports = {
3 | // 用户标识
4 | wxUserId: 'WxUserId',
5 |
6 | // 登录标识
7 | loginFlag: 'LoginFlag',
8 |
9 | // 图标
10 | icon: {
11 | success: 'success',
12 | loading: 'loading',
13 | none: 'none'
14 | },
15 |
16 | // url 前缀
17 | urlPrefix: {
18 | server: 'https://api.nidie.com.cn/api/', //服务器
19 | local: 'http://localhost:57196/api/', //本地
20 | test: 'http://localhost:57196/api/', //测试
21 | file: 'https://download.nidie.com.cn/', //文件
22 | image: 'http://www.ituring.com.cn/' //图片
23 | }
24 | };
--------------------------------------------------------------------------------
/src/pages/comment/comment.wxml:
--------------------------------------------------------------------------------
1 |
2 |
17 |
--------------------------------------------------------------------------------
/src/project.config.json:
--------------------------------------------------------------------------------
1 | {
2 | "description": "项目配置文件。",
3 | "packOptions": {
4 | "ignore": []
5 | },
6 | "setting": {
7 | "urlCheck": true,
8 | "es6": true,
9 | "postcss": true,
10 | "minified": true,
11 | "newFeature": true
12 | },
13 | "compileType": "miniprogram",
14 | "libVersion": "2.2.0",
15 | "appid": "",
16 | "projectname": "",
17 | "isGameTourist": false,
18 | "condition": {
19 | "search": {
20 | "current": -1,
21 | "list": []
22 | },
23 | "conversation": {
24 | "current": -1,
25 | "list": []
26 | },
27 | "game": {
28 | "currentL": -1,
29 | "list": []
30 | },
31 | "miniprogram": {
32 | "current": -1,
33 | "list": []
34 | }
35 | }
36 | }
--------------------------------------------------------------------------------
/src/pages/today/today.wxml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 | {{item.year}}
16 | {{item.title}}
17 |
18 |
19 |
20 |
21 |
--------------------------------------------------------------------------------
/src/utils/cache.js:
--------------------------------------------------------------------------------
1 | // http 请求
2 |
3 | // 将数据存储在本地缓存中指定的 key 中,会覆盖掉原来该 key 对应的内容,这是一个异步接口
4 | const set = (key, data) => {
5 | wx.setStorage({
6 | key: key,
7 | data: data
8 | })
9 | }
10 |
11 | // 将 data 存储在本地缓存中指定的 key 中,会覆盖掉原来该 key 对应的内容,这是一个同步接口。
12 | const setSync = (key, data) => {
13 | try {
14 | wx.setStorageSync(key, data)
15 | } catch (e) {
16 | console.log(e);
17 | }
18 | }
19 |
20 | // 从本地缓存中异步获取指定 key 对应的内容。
21 | const get = (key, callback) => {
22 | wx.getStorage({
23 | key: key,
24 | success: callback
25 | })
26 | }
27 |
28 | // 从本地缓存中同步获取指定 key 对应的内容。
29 | const getSync = (key) => {
30 | try {
31 | return wx.getStorageSync(key);
32 | } catch (e) {
33 | console.log(e);
34 | }
35 | }
36 |
37 |
38 | module.exports = {
39 | set: set,
40 | setSync: setSync,
41 | get: get,
42 | getSync: getSync
43 | }
--------------------------------------------------------------------------------
/src/pages/today/today.wxss:
--------------------------------------------------------------------------------
1 |
2 |
3 | .today-container {
4 | /*border: 1px solid black;*/
5 | margin-top: 3rpx;
6 | }
7 |
8 | .today-item {
9 | padding: 20rpx 30rpx;
10 | display: flex;
11 | flex-direction: row;
12 | justify-content: space-between;
13 | align-items: center;
14 | }
15 |
16 | .today-item-hover {
17 | background-color: #e6e6e6;
18 | }
19 |
20 |
21 | .text-header{
22 | display: inline-block;
23 | margin-left: 30rpx;
24 | color: #1e1e1e;
25 | font-size: 32rpx;
26 | font-weight:bold;
27 | }
28 |
29 | .text{
30 | display: inline-block;
31 | margin-left: 30rpx;
32 | color: #1e1e1e;
33 | font-size: 27rpx;
34 | }
35 |
36 | .today-loading {
37 | display: flex;
38 | justify-content: center;
39 | align-items: center;
40 | margin-top: 400rpx;
41 | }
42 |
43 | .loading-container {
44 | width: 250rpx;
45 | /* color: #cdcdcd; */
46 | margin-top: 30rpx;
47 | }
--------------------------------------------------------------------------------
/src/pages/today/today.js:
--------------------------------------------------------------------------------
1 | const api = require('../../config/config.js');
2 | const cache = require('../../utils/cache.js');
3 | const tip = require('../../utils/tip.js');
4 | const http = require('../../utils/http.js');
5 |
6 |
7 |
8 | Page({
9 |
10 | /**
11 | * 页面的初始数据
12 | */
13 | data: {
14 | list: [],
15 | today: '',
16 | isLoading: true
17 | },
18 |
19 | // 加载数据
20 | loadData: function () {
21 | let that = this;
22 | let key = 'Today';
23 |
24 | http.get(api.getTodayOfHistory, function (res) {
25 | that.setData({
26 | list: res.result,
27 | today: res.today,
28 | isLoading: false
29 | });
30 |
31 | cache.set(key, res);
32 | })
33 | },
34 |
35 | onLoad: function () {
36 | //this.loadData();
37 | },
38 |
39 | onShow: function () {
40 | this.loadData();
41 | }
42 | });
--------------------------------------------------------------------------------
/src/config/config.js:
--------------------------------------------------------------------------------
1 | const key = require('const.js');
2 |
3 | // 服务器域名
4 | const baseUrl = key.urlPrefix.server;
5 | //const baseUrl = key.urlPrefix.local;
6 |
7 | //获取首页的图书
8 | const getBooksOfIndex = baseUrl + 'books/v1/index';
9 |
10 | //获取图书列表
11 | const getBooksByShowType = baseUrl + 'books/v1/list';
12 |
13 | //获取图书
14 | const getBook = baseUrl + 'books/v1/detail';
15 |
16 | // 保存用户信息
17 | const saveUserInfo = baseUrl + 'account/v1/save';
18 |
19 | // 提交评论
20 | const submitComment = baseUrl + 'comment/v1/submit';
21 |
22 | // 获取评论
23 | const getComments = baseUrl + 'comment/v1/list';
24 |
25 | // 获取历史上的今天
26 | const getTodayOfHistory = baseUrl + 'home/v1/today';
27 |
28 | module.exports = {
29 | getBooksOfIndex: getBooksOfIndex,
30 | getBooksByShowType: getBooksByShowType,
31 | getBook: getBook,
32 | saveUserInfo: saveUserInfo,
33 | submitComment: submitComment,
34 | getComments: getComments,
35 | getTodayOfHistory: getTodayOfHistory
36 | };
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # 图灵小书架
2 |
3 | ## 项目介绍
4 |
5 | 定时抓取图灵社区官网的首页、最热、推荐和最新等栏目的相关信息进行展示,并且可以下载相关的 PDF 进行查阅...后台免部署,直接将代码引入微信开发者工具会自动连接到服务器进行数据交互和展示...
6 |
7 | - Github:https://github.com/liqingwen2015/ituring_small_bookshelf
8 | - Gitee:https://gitee.com/liqingwen/ituring_small_bookshelf
9 | - 博客园:https://www.cnblogs.com/liqingwen/p/9339504.html
10 | - 百度百科:https://baike.baidu.com/item/%E5%9B%BE%E7%81%B5%E5%B0%8F%E4%B9%A6%E6%9E%B6/56474937?fr=aladdin
11 |
12 | ## 扫描或搜索
13 |
14 | ### 方法一
15 |
16 | 
17 | 
18 |
19 | ### 方法二
20 |
21 | 搜索:【图灵小书架】
22 |
23 | #### 主要功能截图
24 |
25 | 
26 | 
27 | 
28 | 
29 |
30 | #### 软件架构
31 |
32 | 后台采用 .NET WebAPI(EF + AutoMapper + Autofac)
33 |
34 | #### 使用说明
35 |
36 | 1. 打开微信开发者工具
37 | 2. 路径引入 src 文件夹
38 | 3. 输入 APPID 和文件名即可
39 |
40 | #### 版本说明
41 |
42 | v1.1 增加功能-历史上的今天
43 | v1.0.1 修复缓存文件名称
44 | v1.0 正式
45 |
46 |
--------------------------------------------------------------------------------
/src/pages/books/books.wxml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | 最新
5 |
6 |
7 | 热门
8 |
9 |
10 | 推荐
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 | {{item.name}}
19 |
20 |
21 |
22 |
--------------------------------------------------------------------------------
/src/utils/navigator.js:
--------------------------------------------------------------------------------
1 | // 导航
2 |
3 | // Tip
4 | // 1: wx.navigateTo 和 wx.redirectTo 不允许跳转到 tabbar 页面,只能用 wx.switchTab 跳转到 tabbar 页面
5 |
6 | // 保留当前页面,跳转到应用内的某个页面,使用wx.navigateBack可以返回到原页面
7 | const navigateTo = (url, obj) => {
8 | wx.navigateTo({
9 | url: handleUrl(url, obj)
10 | })
11 | }
12 |
13 | // 关闭当前页面,跳转到应用内的某个页面
14 | const redirectTo = (url, obj) => {
15 | wx.redirectTo({
16 | url: url
17 | })
18 | }
19 |
20 | // 跳转到 tabBar 页面,并关闭其他所有非 tabBar 页面
21 | const switchTab = (url) => {
22 | wx.switchTab({
23 | url: url
24 | })
25 | }
26 |
27 | // 处理 url
28 | const handleUrl = (url, obj) => {
29 | if (obj) {
30 | url = url + '?';
31 | for (let key in obj) {
32 | obj[key] = encodeURIComponent(obj[key]);
33 | url += key + '=' + obj[key] + '&';
34 | }
35 |
36 | return url = url.substring(0, url.length - 1);
37 | }
38 | return url;
39 | }
40 |
41 | // 关闭当前页面,返回上一页面或多级页面
42 | const navigateBack = (delta) => {
43 | wx.navigateBack({
44 | delta: delta
45 | })
46 | }
47 |
48 | module.exports = {
49 | navigateTo: navigateTo,
50 | redirectTo: redirectTo,
51 | switchTab: switchTab,
52 | navigateBack: navigateBack
53 | }
--------------------------------------------------------------------------------
/src/pages/my/my.wxss:
--------------------------------------------------------------------------------
1 | /**index.wxss**/
2 |
3 | .user-container {
4 | padding: 50rpx 0;
5 | /*border: 1px solid black;*/
6 | }
7 |
8 | .userinfo {
9 | display: flex;
10 | flex-direction: column;
11 | align-items: center;
12 | }
13 |
14 | .userinfo-avatar {
15 | width: 128rpx;
16 | height: 128rpx;
17 | margin: 20rpx;
18 | border-radius: 50%;
19 | }
20 |
21 | .userinfo-nickname {
22 | color: #aaa;
23 | }
24 |
25 | .tab-container {
26 | /*border: 1px solid black;*/
27 | margin-top: 30rpx;
28 | }
29 |
30 | .tab-item {
31 | padding: 20rpx 30rpx;
32 | display: flex;
33 | flex-direction: row;
34 | justify-content: space-between;
35 | align-items: center;
36 | }
37 |
38 | .tab-item-hover {
39 | background-color: #e6e6e6;
40 | }
41 |
42 | .tab-icon {
43 | width: 30rpx;
44 | height: 30rpx;
45 | }
46 |
47 | .tab-text {
48 | display: inline-block;
49 | margin-left: 20rpx;
50 | color: #1e1e1e;
51 | }
52 |
53 | .tab-arrow {
54 | display: inline-block;
55 | width: 20rpx;
56 | height: 20rpx;
57 | border: 1px solid #cdcdcd;
58 | border-left: none;
59 | border-bottom: none;
60 | transform: rotate(45deg);
61 | }
62 |
63 | .tab-text-unrealized {
64 | float: right;
65 | color: gray;
66 | font-size: 26rpx;
67 | }
--------------------------------------------------------------------------------
/src/app.json:
--------------------------------------------------------------------------------
1 | {
2 | "pages": [
3 |
4 | "pages/home/home",
5 | "pages/today/today",
6 | "pages/commentList/commentList",
7 | "pages/comment/comment",
8 | "pages/my/my",
9 | "pages/detail/detail",
10 | "pages/books/books",
11 | "pages/about/about",
12 | "pages/index/index",
13 | "pages/logs/logs"
14 | ],
15 | "window": {
16 | "backgroundTextStyle": "light",
17 | "navigationBarBackgroundColor": "#fff",
18 | "navigationBarTitleText": "WeChat",
19 | "navigationBarTextStyle": "black"
20 | },
21 | "tabBar": {
22 | "list": [{
23 | "pagePath": "pages/home/home",
24 | "text": "首页",
25 | "iconPath": "images/book.png",
26 | "selectedIconPath": "images/bookSelected.png"
27 | }, {
28 | "pagePath": "pages/books/books",
29 | "text": "图书列表",
30 | "iconPath": "images/book.png",
31 | "selectedIconPath": "images/bookSelected.png"
32 | }, {
33 | "pagePath": "pages/my/my",
34 | "text": "我的",
35 | "iconPath": "images/my.png",
36 | "selectedIconPath": "images/mySelected.png"
37 | }],
38 | "color": "#bfbfbf",
39 | "selectedColor": "#1AAD19"
40 | }
41 | }
--------------------------------------------------------------------------------
/src/pages/commentList/commentList.js:
--------------------------------------------------------------------------------
1 | const api = require('../../config/config.js');
2 | const nvgt = require('../../utils/navigator.js');
3 | const http = require('../../utils/http.js');
4 | const cache = require('../../utils/cache.js');
5 |
6 | Page({
7 | /**
8 | * 页面的初始数据
9 | */
10 | data: {
11 | list: [],
12 | isLoading: true
13 | },
14 |
15 | // 跳转到评论页
16 | goComment: function () {
17 | nvgt.redirectTo('../comment/comment');
18 | },
19 |
20 | /**
21 | * 生命周期函数--监听页面加载
22 | */
23 | onLoad: function (options) {},
24 |
25 |
26 | /**
27 | * 生命周期函数--监听页面初次渲染完成
28 | */
29 | onReady: function () {},
30 |
31 | /**
32 | * 生命周期函数--监听页面显示
33 | */
34 | onShow: function () {
35 | let that = this;
36 | let key = `CommentList`;
37 | http.get(api.getComments, function (data) {
38 | that.setData({
39 | list: data,
40 | isLoading: false
41 | })
42 | cache.set(key, data);
43 | }, function () {
44 | let val = cache.getSync(key);
45 |
46 | if (val) {
47 | that.setData({
48 | list: val,
49 | isLoading: false
50 | });
51 | }
52 | })
53 | }
54 | });
--------------------------------------------------------------------------------
/src/pages/commentList/commentList.wxml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
25 |
26 |
27 |
30 |
31 |
--------------------------------------------------------------------------------
/src/pages/books/books.wxss:
--------------------------------------------------------------------------------
1 | /* pages/books/books.wxss */
2 |
3 | .swiper-container {
4 | /*border: 1px solid red;*/
5 | box-sizing: border-box;
6 | padding: 120rpx 0 50rpx 0;
7 | display: flex;
8 | justify-content: center;
9 | align-items: center;
10 | }
11 |
12 | .book-container {
13 | display: flex;
14 | justify-content: flex-start;
15 | align-items: flex-start;
16 | /* border: 1px solid red; */
17 | /* height: 1000rpx; */
18 | flex-wrap: wrap;
19 | /* background-color: gray; */
20 | align-items: stretch;
21 | }
22 |
23 | .nav {
24 | display: flex;
25 | width: 100%;
26 | align-items: flex-start;
27 | justify-content: flex-start;
28 | /* border-bottom: 1rpx solid gray; */
29 | position: fixed;
30 | height: 100rpx;
31 | background-color: white;
32 | }
33 |
34 | .nav-item {
35 | width: 33.33%;
36 | text-align: center;
37 | padding-top: 20rpx;
38 | padding-bottom: 20rpx;
39 | }
40 |
41 | .nav-item-text {
42 | border-bottom: 3rpx solid green;
43 | }
44 |
45 | .book-container-item {
46 | width: 50%;
47 | height: 500rpx;
48 | display: flex;
49 | flex-direction: column;
50 | align-items: center;
51 | justify-content: center;
52 | }
53 |
54 | .book-image {
55 | height: 380rpx;
56 | width: 80%;
57 | text-align: center;
58 | }
59 |
60 | .book-name {
61 | padding: 20rpx;
62 | font-size: 25rpx;
63 | }
--------------------------------------------------------------------------------
/src/pages/home/home.wxml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 | {{item.name}}
19 | ¥ {{item.price}} 元
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
--------------------------------------------------------------------------------
/src/pages/home/home.wxss:
--------------------------------------------------------------------------------
1 | /* pages/books/books.wxss */
2 |
3 | .swiper-container {
4 | /*border: 1px solid red;*/
5 | box-sizing: border-box;
6 | padding: 120rpx 0 50rpx 0;
7 | display: flex;
8 | justify-content: center;
9 | align-items: center;
10 | }
11 |
12 | .swiper {
13 | width: 750rpx;
14 | height: 800rpx;
15 | }
16 |
17 | .swiper-item {
18 | /*border: 1px solid blue;*/
19 | /* 宽高自动设为100% */
20 | display: flex;
21 | justify-content: center;
22 | align-items: center;
23 | }
24 |
25 | .book-container {
26 | border: 1px solid #e6e6e6;
27 | width: 450rpx;
28 | height: 650rpx;
29 | padding: 30rpx 20rpx;
30 | display: flex;
31 | flex-direction: column;
32 | justify-content: space-around;
33 | align-items: center;
34 | border-radius: 20rpx;
35 | box-shadow: 0 0 10rpx #dbdbdb;
36 | }
37 |
38 | .book-container-hover {
39 | transform: scale(0.96, 0.96);
40 | transition: all 1 ease 0;
41 | }
42 |
43 | .book-image {
44 | /*border: 1px solid #cdcdcd;*/
45 | /*box-shadow: 0 0 10rpx #dcdcdc;*/
46 | }
47 |
48 | .book-image>image {
49 | width: 400rpx;
50 | height: 500rpx;
51 | }
52 |
53 | .book-info {
54 | display: flex;
55 | flex-direction: column;
56 | justify-content: space-around;
57 | align-items: center;
58 | /*border: 1px solid black;*/
59 | margin-top: 20rpx;
60 | }
61 |
62 | .book-name {
63 | color: #1e1e1e;
64 | font-size: 32rpx;
65 | margin-bottom: 8rpx;
66 | }
67 |
68 | .author {
69 | color: #8a8a8a;
70 | font-size: 28rpx;
71 | margin-bottom: 8rpx;
72 | }
73 |
74 | .publisher {
75 | color: #cdcdcd;
76 | font-size: 30rpx;
77 | }
78 |
79 | .donut-container {
80 | padding-top: 400rpx;
81 | }
--------------------------------------------------------------------------------
/src/pages/index/index.js:
--------------------------------------------------------------------------------
1 | const api = require('../../config/config.js');
2 |
3 | //index.js
4 | //获取应用实例
5 | const app = getApp()
6 |
7 | Page({
8 | data: {
9 | motto: 'Hello World',
10 | userInfo: {},
11 | hasUserInfo: false,
12 | canIUse: wx.canIUse('button.open-type.getUserInfo')
13 | },
14 | //事件处理函数
15 | bindViewTap: function () {
16 | wx.navigateTo({
17 | url: '../logs/logs'
18 | })
19 | },
20 | onLoad: function () {
21 | console.log(api.getBooksOfIndex);
22 |
23 | if (app.globalData.userInfo) {
24 | this.setData({
25 | userInfo: app.globalData.userInfo,
26 | hasUserInfo: true
27 | })
28 | } else if (this.data.canIUse) {
29 | // 由于 getUserInfo 是网络请求,可能会在 Page.onLoad 之后才返回
30 | // 所以此处加入 callback 以防止这种情况
31 | app.userInfoReadyCallback = res => {
32 | this.setData({
33 | userInfo: res.userInfo,
34 | hasUserInfo: true
35 | })
36 | }
37 | } else {
38 | // 在没有 open-type=getUserInfo 版本的兼容处理
39 | wx.getUserInfo({
40 | success: res => {
41 | app.globalData.userInfo = res.userInfo
42 | this.setData({
43 | userInfo: res.userInfo,
44 | hasUserInfo: true
45 | })
46 | }
47 | })
48 | }
49 | },
50 | getUserInfo: function (e) {
51 | //console.log(e)
52 | app.globalData.userInfo = e.detail.userInfo
53 | this.setData({
54 | userInfo: e.detail.userInfo,
55 | hasUserInfo: true
56 | })
57 | }
58 | })
--------------------------------------------------------------------------------
/src/pages/commentList/commentList.wxss:
--------------------------------------------------------------------------------
1 |
2 | .comment-container {
3 | padding-top: 30rpx;
4 | }
5 |
6 | .comment-title {
7 | /*border: 1px solid black;*/
8 | display: flex;
9 | justify-content: center;
10 | align-items: center;
11 |
12 | margin-bottom: 30rpx;
13 | }
14 |
15 | .comment-title > text {
16 | font-size: 30rpx;
17 | color: #cdcdcd;
18 | }
19 |
20 | .comment-area {
21 | /*border: 1px solid black;*/
22 |
23 | padding: 20rpx 30rpx;
24 | }
25 |
26 | .comment-item {
27 | display: flex;
28 | flex-direction: row;
29 | justify-content: flex-start;
30 | align-items: flex-start;
31 |
32 | margin-bottom: 20rpx;
33 | }
34 |
35 | .comment-placeholder {
36 | display: flex;
37 | justify-content: center;
38 | align-items: center;
39 |
40 | color: #dcdcdc;
41 | }
42 |
43 | .comment-item:last-child {
44 | margin-bottom: 180rpx;
45 | }
46 |
47 | .avatar-container {
48 | width: 80rpx;
49 | height: 80rpx;
50 | margin-right: 20rpx;
51 | }
52 |
53 | .user-avatar {
54 | width: 80rpx;
55 | height: 80rpx;
56 |
57 | /*border: 1px solid red;*/
58 |
59 | }
60 |
61 | .comment-content {
62 | display: flex;
63 | max-width: 590rpx;
64 | flex-direction: column;
65 | justify-content: flex-start;
66 | align-items: flex-start;
67 | }
68 |
69 | .user-name {
70 | color: #8a8a8a;
71 | font-size: 30rpx;
72 | }
73 |
74 | .user-comment {
75 | display: inline-block;
76 | margin-top: 10rpx;
77 | color: #1e1e1e;
78 | font-size: 35rpx;
79 | }
80 |
81 | .comment-time {
82 | display: inline-block;
83 | margin-top: 10rpx;
84 | color: #cdcdcd;
85 | font-size: 20rpx;
86 | }
87 |
88 | .comment-loading {
89 | display: flex;
90 | justify-content: center;
91 | align-items: center;
92 | margin-top: 300rpx;
93 | }
94 |
95 | .loading-container {
96 | width: 250rpx;
97 | color: #cdcdcd;
98 | margin-top: 30rpx;
99 | }
--------------------------------------------------------------------------------
/src/pages/detail/detail.wxml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 | {{book.name}}
13 | {{book.author}}
14 | ¥ {{book.price}} 元
15 |
16 |
17 |
18 |
19 |
20 |
21 |
33 |
34 |
35 |
38 |
39 |
40 |
41 |
--------------------------------------------------------------------------------
/src/app.wxss:
--------------------------------------------------------------------------------
1 | /**app.wxss**/
2 |
3 | .container {
4 | height: 100%;
5 | display: flex;
6 | flex-direction: column;
7 | align-items: center;
8 | justify-content: space-between;
9 | padding: 100rpx 0;
10 | box-sizing: border-box;
11 | /*border: 1px solid green;*/
12 | }
13 |
14 | page {
15 | background-color: #f2f2f2;
16 | }
17 |
18 | .bg-white {
19 | background-color: #ffffff;
20 | }
21 |
22 | .image-icon {
23 | width: 30rpx;
24 | height: 30rpx;
25 | }
26 |
27 | .border-bottom {
28 | border-bottom: 1px solid #dbdbdb;
29 | }
30 |
31 | /* 修正 text 组件 英文&符号不换行的问题 begin */
32 |
33 | text {
34 | word-wrap: break-all;
35 | word-break: break-word;
36 | text-align: justify;
37 | }
38 |
39 | /* 修正 text 组件 英文&符号不换行的问题 end */
40 |
41 | .fixed-top {
42 | position: fixed;
43 | top: 0rpx;
44 | left: 0rpx;
45 | box-shadow: 0 -5rpx 20rpx #c9c9c9;
46 | }
47 |
48 | .fixed-bottom {
49 | position: fixed;
50 | bottom: 0rpx;
51 | left: 0rpx;
52 | box-shadow: 0 -5rpx 20rpx #c9c9c9;
53 | }
54 |
55 | .block-full-width {
56 | display: block;
57 | width: 100%;
58 | height: 150rpx;
59 | }
60 |
61 | .flex-container {
62 | display: flex;
63 | justify-content: center;
64 | align-items: center;
65 | }
66 |
67 | .full-button {
68 | width: 80%;
69 | }
70 |
71 | /*甜甜圈loading start*/
72 |
73 | @keyframes donut-spin {
74 | 0% {
75 | transform: rotate(0deg);
76 | }
77 | 100% {
78 | transform: rotate(360deg);
79 | }
80 | }
81 |
82 | .donut {
83 | display: inline-block;
84 | border: 4rpx solid rgba(0, 0, 0, 0.1);
85 | border-left-color: #1AAD19;
86 | border-radius: 50%;
87 | width: 60rpx;
88 | height: 60rpx;
89 | animation: donut-spin 0.5s linear infinite;
90 | }
91 |
92 | /*甜甜圈loading end*/
93 |
94 | .donut-container {
95 | padding-top: 500rpx;
96 | text-align: center;
97 | }
--------------------------------------------------------------------------------
/src/utils/http.js:
--------------------------------------------------------------------------------
1 | // http 请求
2 |
3 | const tip = require('tip.js');
4 |
5 | // get
6 | const get = (url, success = () => {}, fail = () => {}) => {
7 | wx.request({
8 | url: url,
9 | method: "GET",
10 | success: function (res) {
11 | if (res.statusCode === 200) {
12 | success(res.data.data);
13 | return true;
14 | }
15 |
16 | console.log(res);
17 | return false;
18 | },
19 | fail: function (err) {
20 | fail();
21 | tip.showToast('貌似网络不好哦!请在网络顺畅的时候重新操作!');
22 | console.log(err);
23 | }
24 | });
25 | }
26 |
27 | /**
28 | * 封装 post
29 | */
30 | const post = (url, data, success = () => {}, fail = () => {}) => {
31 | wx.request({
32 | url: url,
33 | data: data,
34 | method: "POST",
35 | success: function (res) {
36 | if (res.statusCode === 200) {
37 | success();
38 | return true;
39 | }
40 |
41 | console.log(res);
42 | return false;
43 | },
44 | fail: function (err) {
45 | fail();
46 | console.log(err);
47 | tip.showToast('貌似网络不好哦!请在网络顺畅的时候重新操作!');
48 | }
49 | });
50 | }
51 |
52 | // 下载文件资源到本地,客户端直接发起一个 HTTP GET 请求,返回文件的本地临时路径
53 | const downloadFile = (url, success = () => {}, fail = () => {}, complete = () => {}) => {
54 | wx.downloadFile({
55 | url: url,
56 | success: function (res) {
57 | if (res.statusCode === 200) {
58 | success(res.tempFilePath);
59 | return true;
60 | }
61 |
62 | return false;
63 | },
64 | fail: function (err) {
65 | fail();
66 | tip.showToast("貌似失败了,请重试!多次失败请联系开发人员");
67 | console.log(err)
68 | },
69 | complete: function () {
70 | complete();
71 | }
72 | })
73 | }
74 |
75 | module.exports = {
76 | post: post,
77 | get: get,
78 | downloadFile: downloadFile
79 | }
--------------------------------------------------------------------------------
/src/pages/home/home.js:
--------------------------------------------------------------------------------
1 | // pages/books/books.js
2 |
3 | // 获取服务器接口地址
4 | const api = require('../../config/config.js');
5 | const nvgt = require('../../utils/navigator.js');
6 | const http = require('../../utils/http.js');
7 | const cache = require('../../utils/cache.js');
8 |
9 | Page({
10 |
11 | /**
12 | * 页面的初始数据
13 | */
14 | data: {
15 | list: [],
16 | indicatorDots: false, // 是否显示轮播指示点
17 | autoplay: true, // 是否自动播放轮播
18 | interval: 5000, // 轮播间隔
19 | duration: 1000, // 轮播播放延迟
20 | circular: true, // 是否采用衔接滑动
21 | sideMargin: '100rpx', // 幻灯片前后边距
22 | isLoading: true // 是否显示loading态
23 | },
24 |
25 | /**
26 | * 打开书籍详情页面
27 | */
28 | goDetail: function (ev) {
29 | let info = ev.currentTarget.dataset;
30 | nvgt.navigateTo('../detail/detail', info);
31 | },
32 |
33 | // 获取首页的书籍
34 | getBooksOfIndex: function () {
35 | let that = this;
36 | let key = 'BooksOfHome';
37 | var res = cache.getSync(key);
38 |
39 | if (!res) {
40 | http.get(api.getBooksOfIndex, function (res) {
41 | that.setData({
42 | list: res.books,
43 | isLoading: false
44 | });
45 |
46 | cache.set(key, res.books)
47 | });
48 | } else {
49 | that.setData({
50 | list: res,
51 | isLoading: false
52 | });
53 | }
54 | },
55 |
56 | /**
57 | * 生命周期函数--监听页面加载
58 | */
59 | onLoad: function (options) {
60 |
61 | },
62 |
63 | /**
64 | * 生命周期函数--监听页面初次渲染完成
65 | */
66 | onReady: function () {},
67 |
68 | /**
69 | * 生命周期函数--监听页面显示
70 | */
71 | onShow: function () {
72 | let that = this;
73 | if (that.list == null || that.list.length == 0) {
74 | that.getBooksOfIndex();
75 | }
76 | },
77 |
78 | /**
79 | * 设置页面转发信息
80 | */
81 | onShareAppMessage: function (res) {
82 | if (res.from === 'button') {
83 | // 来自页面内转发按钮
84 | console.log(res.target)
85 | }
86 | return {
87 | title: '小书架首页',
88 | path: '/pages/books/books',
89 | imageUrl: '/images/bookstore.png',
90 | success: function (res) {
91 | // 转发成功
92 | console.log('转发成功');
93 | },
94 | fail: function (res) {
95 | // 转发失败
96 | console.log('转发失败')
97 | }
98 | }
99 | }
100 | });
--------------------------------------------------------------------------------
/src/pages/my/my.js:
--------------------------------------------------------------------------------
1 |
2 | const api = require('../../config/config.js');
3 | const nvgt = require('../../utils/navigator.js');
4 | const tip = require('../../utils/tip.js');
5 |
6 | const app = getApp();
7 |
8 |
9 | Page({
10 |
11 | /**
12 | * 页面的初始数据
13 | */
14 | data: {
15 | userInfo: {},
16 | hasLogin: wx.getStorageSync('loginFlag') ? true : false
17 | },
18 |
19 | // 跳转到 关于
20 | goAbout: function () {
21 | nvgt.navigateTo('../about/about');
22 | },
23 |
24 | // 跳转到 评论
25 | goComment: function () {
26 | nvgt.navigateTo('../comment/comment');
27 | },
28 |
29 | // 跳转到 评论列表
30 | goCommentList: function () {
31 | nvgt.navigateTo('../commentList/commentList');
32 |
33 | },
34 |
35 | // 跳转到 历史上的今天
36 | goToday: function () {
37 | nvgt.navigateTo('../today/today');
38 | },
39 |
40 | // 检查登录状态
41 | checkLoginStatus: function () {
42 | let that = this;
43 | let loginFlag = wx.getStorageSync('loginFlag');
44 |
45 | if (loginFlag) {
46 | // 检查 session_key 是否过期
47 | wx.checkSession({
48 | // session_key 有效(未过期)
49 | success: function () {
50 | // 获取用户头像/昵称等信息
51 | that.getUserInfo();
52 | },
53 |
54 | // session_key 已过期
55 | fail: function () {
56 | that.setData({
57 | hasLogin: false
58 | });
59 | }
60 | });
61 |
62 | } else {
63 | that.setData({
64 | hasLogin: false
65 | });
66 | }
67 | },
68 |
69 | /**
70 | * 执行登录操作
71 | */
72 | doLogin: function (e) {
73 | let that = this;
74 |
75 | wx.showLoading({
76 | title: '登录中...',
77 | mask: true
78 | });
79 |
80 | app.doLogin(that.getUserInfo, e.detail.userInfo);
81 | },
82 |
83 | /**
84 | * 从 globalData 中获取 userInfo
85 | */
86 | getUserInfo: function () {
87 | let that = this;
88 | let userInfo = app.globalData.userInfo;
89 |
90 | if (userInfo) {
91 | that.setData({
92 | hasLogin: true,
93 | userInfo: userInfo
94 | });
95 |
96 | wx.hideLoading();
97 |
98 | } else {
99 | console.log('globalData中userInfo为空');
100 | }
101 | },
102 |
103 | onLoad: function () {
104 | this.checkLoginStatus();
105 | },
106 |
107 | onShow: function () {
108 | let that = this;
109 | that.setData({
110 | userInfo: app.globalData.userInfo
111 | });
112 | }
113 | });
--------------------------------------------------------------------------------
/src/pages/detail/detail.js:
--------------------------------------------------------------------------------
1 | // 获取服务器接口地址
2 | const api = require('../../config/config.js');
3 | const key = require('../../config/const.js');
4 | const http = require('../../utils/http.js');
5 | const file = require('../../utils/file.js');
6 | const cache = require('../../utils/cache.js');
7 | const tip = require('../../utils/tip.js');
8 |
9 | Page({
10 | data: {
11 | bookIsBuy: 0,
12 | downloading: false,
13 | book: {},
14 | id: '',
15 | showLoading: true,
16 | isAllowDownload: false, //是否允许下载
17 | isDownloading: false //下载中标识
18 | },
19 |
20 | // 获取书籍
21 | getBook: function (id) {
22 | let that = this;
23 | let key = `Book_${id}`;
24 | let val = cache.getSync(key);
25 | let obj = {
26 | showLoading: false
27 | };
28 |
29 | if (val) {
30 | if (val.pdfUrl && val.pdfUrl.trim() !== '') {
31 | obj.isAllowDownload = true;
32 | }
33 |
34 | obj.book = val;
35 | that.setData(obj);
36 | return;
37 | }
38 |
39 | http.get(api.getBook + `/${id}`, function (data) {
40 | if (data.pdfUrl && data.pdfUrl.trim() !== '') {
41 | obj.isAllowDownload = true;
42 | }
43 |
44 | obj.book = data;
45 | that.setData(obj);
46 |
47 | cache.set(key, data);
48 | });
49 | },
50 |
51 | // 下载
52 | download: function () {
53 | let that = this;
54 |
55 | if (that.data.isDownloading) {
56 | tip.showToast('下载中,请稍安勿躁!!!');
57 | return;
58 | }
59 |
60 | let cachekey = `Book_PDF_${that.data.id}`;
61 | let path = cache.getSync(cachekey);
62 |
63 | if (!path) {
64 | that.setData({
65 | isDownloading: true
66 | });
67 |
68 | let pdfUrl = that.data.book.pdfUrl.split(',');
69 |
70 | http.downloadFile(key.urlPrefix.file + pdfUrl[0],
71 | function (filePath) {
72 | file.openDocument(filePath);
73 | cache.set(cachekey, filePath);
74 | },
75 | function () {
76 | that.setData({
77 | isDownloading: false
78 | });
79 | });
80 |
81 | tip.showToast('已经开始下载,下载完毕后将自动打开,请稍后!!!');
82 | return;
83 | }
84 |
85 | file.openDocument(path);
86 | },
87 |
88 | /**
89 | * 生命周期函数--监听页面加载
90 | */
91 | onLoad: function (options) {
92 | let that = this;
93 | let id = options.id;
94 |
95 | that.getBook(id);
96 | that.setData({
97 | id: id
98 | });
99 | },
100 | });
--------------------------------------------------------------------------------
/src/pages/detail/detail.wxss:
--------------------------------------------------------------------------------
1 | /* pages/detail/detail.wxss */
2 |
3 | .book-container {
4 | /*border: 1px solid black;*/
5 |
6 | display: flex;
7 | flex-direction: row;
8 | justify-content: space-between;
9 | align-items: center;
10 |
11 | padding: 50rpx 30rpx;
12 | }
13 |
14 | .book-info {
15 | /*border: 1px solid red;*/
16 |
17 | display: flex;
18 | flex-direction: row;
19 | align-items: flex-start;
20 | justify-content: space-between;
21 | }
22 |
23 | .book-image {
24 | width: 240rpx;
25 | height: 280rpx;
26 |
27 | box-shadow: 0 0 10rpx #cdcdcd;
28 | }
29 |
30 |
31 | .book-desc {
32 | /*border: 1px solid yellow;*/
33 | display: flex;
34 | flex-direction: column;
35 | justify-content: space-between;
36 | align-items: flex-start;
37 |
38 | padding-left: 30rpx;
39 | }
40 |
41 | .book-main-text {
42 | color: #1e1e1e;
43 | font-size: 35rpx;
44 | }
45 |
46 | .book-text {
47 | color: #8a8a8a;
48 | font-size: 30rpx;
49 | margin-top:15rpx;
50 | }
51 |
52 | .button-area {
53 | /*border: 1px solid blue;*/
54 | }
55 |
56 | .button-area > button {
57 | font-size: 30rpx;
58 | }
59 |
60 |
61 | .comment-container {
62 | padding-top: 30rpx;
63 | }
64 |
65 | .comment-title {
66 | /*border: 1px solid black;*/
67 | display: flex;
68 | justify-content: center;
69 | align-items: center;
70 |
71 | margin-bottom: 30rpx;
72 | }
73 |
74 | .comment-title > text {
75 | font-size: 30rpx;
76 | color: #cdcdcd;
77 | }
78 |
79 | .comment-area {
80 | /*border: 1px solid black;*/
81 |
82 | padding: 20rpx 30rpx;
83 | }
84 |
85 | .comment-item {
86 | display: flex;
87 | flex-direction: row;
88 | justify-content: flex-start;
89 | align-items: flex-start;
90 |
91 | margin-bottom: 20rpx;
92 | }
93 |
94 | .comment-placeholder {
95 | display: flex;
96 | justify-content: center;
97 | align-items: center;
98 |
99 | color: black;
100 | font-size: 30rpx;
101 | }
102 |
103 | .comment-item:last-child {
104 | margin-bottom: 180rpx;
105 | }
106 |
107 | .avatar-container {
108 | width: 80rpx;
109 | height: 80rpx;
110 | margin-right: 20rpx;
111 | }
112 |
113 | .user-avatar {
114 | width: 80rpx;
115 | height: 80rpx;
116 |
117 | /*border: 1px solid red;*/
118 |
119 | }
120 |
121 | .comment-content {
122 | display: flex;
123 | max-width: 590rpx;
124 | flex-direction: column;
125 | justify-content: flex-start;
126 | align-items: flex-start;
127 | }
128 |
129 | .user-name {
130 | color: #8a8a8a;
131 | font-size: 30rpx;
132 | }
133 |
134 | .user-comment {
135 | display: inline-block;
136 | margin-top: 10rpx;
137 | color: #1e1e1e;
138 | font-size: 35rpx;
139 | }
140 |
141 | .comment-time {
142 | display: inline-block;
143 | margin-top: 10rpx;
144 | color: #cdcdcd;
145 | font-size: 20rpx;
146 | }
147 |
148 | .comment-loading {
149 | display: flex;
150 | justify-content: center;
151 | align-items: center;
152 | }
153 |
154 | .loading-container {
155 | width: 250rpx;
156 | color: #cdcdcd;
157 | margin-top: 30rpx;
158 | }
--------------------------------------------------------------------------------
/src/pages/comment/comment.js:
--------------------------------------------------------------------------------
1 | /** pages/comment/comment.js **/
2 |
3 | // 获取服务器接口地址
4 | const api = require('../../config/config.js');
5 | const tip = require('../../utils/tip.js');
6 | const http = require('../../utils/http.js');
7 | const nvgt = require('../../utils/navigator.js');
8 |
9 | Page({
10 |
11 | /**
12 | * 页面的初始数据
13 | */
14 | data: {
15 | comment: '',
16 |
17 | },
18 |
19 | /**
20 | * 用户输入评论
21 | */
22 | inputComment: function (ev) {
23 | let that = this;
24 | that.setData({
25 | comment: ev.detail.value
26 | });
27 | },
28 |
29 | /**
30 | * 检查输入是否为空
31 | */
32 | checkEmpty: function (input) {
33 | return input === '';
34 | },
35 |
36 | /**
37 | * 检查用户是否输入了非法字符
38 | */
39 | checkIllegal: function (input) {
40 | let patern = /[`#^<>:"?{}\/;'[\]]/im;
41 | let _result = patern.test(input);
42 | return _result;
43 | },
44 |
45 | /**
46 | * 检查用户输入
47 | */
48 | checkUserInput: function () {
49 | let that = this;
50 | let comment = that.data.comment;
51 | let showToastFlag = true;
52 | let toastWording = '';
53 |
54 | if (that.checkEmpty(comment)) {
55 | toastWording = '输入不能为空';
56 | } else if (that.checkIllegal(comment)) {
57 |
58 | toastWording = '含有非法字符';
59 | } else if (comment.length > 300) {
60 | toastWording = '长度超出限制';
61 | } else if (comment.length < 5) {
62 | toastWording = '不能少于5个字哦';
63 | } else {
64 | showToastFlag = false;
65 | }
66 |
67 | if (showToastFlag) {
68 | tip.showToast(toastWording);
69 | return false;
70 | } else {
71 | return true;
72 | }
73 | },
74 |
75 | /**
76 | * 提交评论内容
77 | */
78 | submitComment: function (ev) {
79 |
80 | let that = this;
81 |
82 | let formId = ev.detail.formId;
83 |
84 | let userId = wx.getStorageSync('userId');
85 |
86 | if (!userId) {
87 | let toastWording = '请先登录';
88 | tip.showToast(toastWording);
89 | return false;
90 | }
91 |
92 | if (that.checkUserInput()) {
93 | let requestData = {
94 | content: that.data.comment,
95 | wxUserId: userId
96 | };
97 |
98 | http.post(api.submitComment, requestData, function () {
99 | tip.showToast('成功!', 'success');
100 | nvgt.redirectTo('../commentList/commentList');
101 | });
102 |
103 | }
104 | },
105 |
106 | /**
107 | * 生命周期函数--监听页面加载
108 | */
109 | onLoad: function (options) {},
110 |
111 | /**
112 | * 生命周期函数--监听页面初次渲染完成
113 | */
114 | onReady: function () {},
115 |
116 | /**
117 | * 生命周期函数--监听页面显示
118 | */
119 | onShow: function () {;
120 | }
121 | });
--------------------------------------------------------------------------------
/src/pages/my/my.wxml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 | {{userInfo.nickName}}
12 |
13 |
14 |
15 |
16 |
26 |
36 |
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 |
64 |
--------------------------------------------------------------------------------
/src/pages/books/books.js:
--------------------------------------------------------------------------------
1 | // pages/books/books.js
2 |
3 | // 获取服务器接口地址
4 | const api = require('../../config/config.js');
5 | const nvgt = require('../../utils/navigator.js');
6 | const http = require('../../utils/http.js');
7 | // 获取app应用实例
8 | const app = getApp();
9 |
10 |
11 | Page({
12 |
13 | /**
14 | * 页面的初始数据
15 | */
16 | data: {
17 | indicatorDots: false, // 是否显示轮播指示点
18 | autoplay: true, // 是否自动播放轮播
19 | interval: 5000, // 轮播间隔
20 | duration: 1000, // 轮播播放延迟
21 | circular: true, // 是否采用衔接滑动
22 | sideMargin: '100rpx', // 幻灯片前后边距
23 | showLoading: true, // 是否显示loading态
24 | isNewest: true,
25 | isHot: false,
26 | isCommendatory: false,
27 | list: [],
28 | },
29 |
30 | // 切换类型
31 | toggelType(ev) {
32 | let that = this;
33 | let info = ev.currentTarget.dataset;
34 |
35 | let typeObj = {
36 | isNewest: false,
37 | isHot: false,
38 | isCommendatory: false,
39 | showLoading: false
40 | };
41 |
42 | switch (info.type) {
43 | case '1':
44 | typeObj.isNewest = true;
45 | break;
46 | case '2':
47 | typeObj.isHot = true;
48 | break;
49 | case '3':
50 | typeObj.isCommendatory = true;
51 | break;
52 | default:
53 | typeObj.isNewest = true;
54 | break;
55 | }
56 |
57 | that.getList(info.type);
58 | that.setData(typeObj);
59 | },
60 |
61 | // 跳转到详情页面
62 | goDetail: function (ev) {
63 | let info = ev.currentTarget.dataset;
64 | nvgt.navigateTo('../detail/detail', info);
65 | },
66 |
67 | // 获取列表
68 | getList: function (type) {
69 | type = type || 1;
70 | let that = this;
71 |
72 | http.get(that.createRequestUrlOfGetList(type), function (res) {
73 | that.setData({
74 | list: res.books
75 | });
76 | })
77 |
78 | },
79 |
80 | // 生成请求 url
81 | createRequestUrlOfGetList: function (type) {
82 | return api.getBooksByShowType + `/${type}/1`;
83 | },
84 |
85 | /**
86 | * 生命周期函数--监听页面加载
87 | */
88 | onLoad: function (options) {
89 | let that = this;
90 | that.getList();
91 | },
92 |
93 | /**
94 | * 生命周期函数--监听页面初次渲染完成
95 | */
96 | onReady: function () {
97 | },
98 |
99 | /**
100 | * 生命周期函数--监听页面显示
101 | */
102 | onShow: function () {
103 | },
104 |
105 | /**
106 | * 设置页面转发信息
107 | */
108 | onShareAppMessage: function (res) {
109 | console.log(res);
110 |
111 | if (res.from === 'button') {
112 | // 来自页面内转发按钮
113 | console.log(res.target)
114 | }
115 |
116 | return {
117 | title: '图灵书籍',
118 | path: '/pages/home/home',
119 | imageUrl: '/images/bookstore.png',
120 | success: function (res) {
121 | console.log('转发成功');
122 | },
123 | fail: function (res) {
124 | console.log('转发失败')
125 | }
126 | }
127 | }
128 | });
--------------------------------------------------------------------------------
/src/app.js:
--------------------------------------------------------------------------------
1 | //app.js
2 | const api = require('./config/config.js');
3 |
4 | App({
5 | // 小程序启动生命周期
6 | onLaunch: function () {
7 | let that = this;
8 | // 检查登录状态
9 | that.checkLoginStatus();
10 | },
11 |
12 | // 检查本地 storage 中是否有登录态标识
13 | checkLoginStatus: function () {
14 | let that = this;
15 | let loginFlag = wx.getStorageSync('loginFlag');
16 | if (loginFlag) {
17 | // 检查 session_key 是否过期
18 | wx.checkSession({
19 | // session_key 有效(为过期)
20 | success: function () {
21 | // 直接从Storage中获取用户信息
22 | let userStorageInfo = wx.getStorageSync('userInfo');
23 | if (userStorageInfo) {
24 | that.globalData.userInfo = JSON.parse(userStorageInfo);
25 | } else {
26 | that.showInfo('缓存信息缺失');
27 | console.error('登录成功后将用户信息存在Storage的userStorageInfo字段中,该字段丢失');
28 | }
29 |
30 | },
31 | // session_key 过期
32 | fail: function () {
33 | // session_key过期
34 | that.doLogin();
35 | }
36 | });
37 | } else {
38 | // 无登录态
39 | that.doLogin();
40 | }
41 | },
42 |
43 | // 登录动作
44 | doLogin: function (callback = () => {}, userInfo) {
45 |
46 | let that = this;
47 |
48 | if (userInfo) {
49 |
50 | that.globalData.userInfo = userInfo;
51 | wx.setStorageSync('userInfo', JSON.stringify(userInfo));
52 | wx.setStorageSync('loginFlag', "res.skey");
53 | callback();
54 |
55 | wx.login({
56 | success: function (loginRes) {
57 | if (loginRes.code) {
58 |
59 | wx.request({
60 | url: api.saveUserInfo,
61 | data: {
62 | Code: loginRes.code,
63 | NickName: userInfo.nickName,
64 | AvatarUrl: userInfo.avatarUrl,
65 | Gender: userInfo.gender,
66 | City: userInfo.city,
67 | Province: userInfo.province,
68 | Country: userInfo.country,
69 | Language: userInfo.language
70 | },
71 | method: "POST",
72 | success: function (res) {
73 | wx.setStorageSync('userId', res.data.data);
74 | showLoading: false;
75 | },
76 | error: function (err) {
77 | console.log(err);
78 | showLoading: false
79 | }
80 | });
81 |
82 | } else {
83 | // 获取 code 失败
84 | that.showInfo('登录失败');
85 | console.log('调用wx.login获取code失败');
86 | }
87 | },
88 |
89 | fail: function (error) {
90 | // 调用 wx.login 接口失败
91 | that.showInfo('接口调用失败');
92 | console.log(error);
93 | }
94 | });
95 | }
96 |
97 | //console.log(that.globalData.userInfo);
98 | },
99 |
100 | // 检查用户信息授权设置
101 | checkUserInfoPermission: function (callback = () => {}) {
102 | wx.getSetting({
103 | success: function (res) {
104 | if (!res.authSetting['scope.userInfo']) {
105 | wx.openSetting({
106 | success: function (authSetting) {
107 | console.log(authSetting)
108 | }
109 | });
110 | }
111 | },
112 | fail: function (error) {
113 | console.log(error);
114 | }
115 | });
116 | },
117 |
118 |
119 | // 获取用户登录标示 供全局调用
120 | getLoginFlag: function () {
121 | return wx.getStorageSync('loginFlag');
122 | },
123 |
124 | // 获取书籍已下载路径
125 | getDownloadPath: function (key) {
126 | return wx.getStorageSync(key);
127 | },
128 |
129 | // 调用 wx.saveFile 将下载的文件保存在本地
130 | saveDownloadPath: function (key, filePath) {
131 | return new Promise((resolve, reject) => {
132 | wx.saveFile({
133 | tempFilePath: filePath,
134 | success: function (res) {
135 | // 保存成功 在Storage中标记 下次不再下载
136 | let savedFilePath = res.savedFilePath;
137 | wx.setStorageSync(key, savedFilePath);
138 | resolve(savedFilePath);
139 | },
140 | fail: function () {
141 | reject(false);
142 | }
143 | });
144 | })
145 |
146 | },
147 |
148 | // 打开书籍
149 | openBook: function (filePath) {
150 | wx.openDocument({
151 | filePath: filePath,
152 | success: function (res) {
153 | console.log('打开文档成功')
154 | },
155 | fail: function (error) {
156 | console.log(error);
157 | }
158 | });
159 | },
160 |
161 | // app全局数据
162 | globalData: {
163 | userInfo: null
164 | }
165 | });
--------------------------------------------------------------------------------