├── README.md
├── app.js
├── app.json
├── app.wxss
├── img
├── book.png
├── chapter.png
├── edit.png
├── icon.png
├── mybook.png
├── ok.png
├── otherIcon.png
├── pullDown.png
├── pullDowned.png
├── refresh.png
├── refresh1.png
├── search.png
├── selectedBook.png
├── selectedMybook.png
└── selectedSearch.png
├── pages
├── bookCats
│ ├── bookCats.js
│ ├── bookCats.json
│ ├── bookCats.wxml
│ └── bookCats.wxss
├── bookCity
│ ├── bookCity.js
│ ├── bookCity.json
│ ├── bookCity.wxml
│ └── bookCity.wxss
├── bookshelf
│ ├── bookshelf.js
│ ├── bookshelf.json
│ ├── bookshelf.wxml
│ └── bookshelf.wxss
├── details
│ ├── details.js
│ ├── details.json
│ ├── details.wxml
│ └── details.wxss
├── help
│ ├── help.js
│ ├── help.json
│ ├── help.wxml
│ └── help.wxss
├── rank
│ ├── rank.js
│ ├── rank.json
│ ├── rank.wxml
│ └── rank.wxss
├── reader
│ ├── reader.js
│ ├── reader.json
│ ├── reader.wxml
│ └── reader.wxss
├── search
│ ├── search.js
│ ├── search.json
│ ├── search.wxml
│ └── search.wxss
└── wxParse
│ ├── html2json.js
│ ├── htmlparser.js
│ ├── showdown.js
│ ├── wxDiscode.js
│ ├── wxParse.js
│ ├── wxParse.json
│ ├── wxParse.wxml
│ └── wxParse.wxss
├── project.config.json
└── utils
└── util.js
/README.md:
--------------------------------------------------------------------------------
1 | # 免费小说阅读器
2 |
3 | ### 使用源码请先star一下。
4 |
5 | ### 项目介绍
6 |
7 | * 全网免费小说,功能齐全,书架、分类、各大排行榜,搜索、详情页,评论、阅读、夜间模式,字体大小,目录。
8 |
9 | * 小说是自动更新的,数据来源第三方API,无依赖库。
10 |
11 | * 学习到的东西很多,强大的文字排版功能。
12 |
13 | * 搜索,分类,排行榜的可以点击添加到书架。
14 |
15 | * 只需 要修改小程序appid和在小程序公众号中添加服务器域名(开发工具有添加域名提示),就可以发布小程序了。
16 |
17 | * 使用问题咨询QQ:903363777
18 |
19 | ### 项目运行截图
20 |
21 | 
22 |
23 | 
24 |
25 | 
26 |
27 | 
28 |
29 | 
30 |
31 | ### 小程序二维码
32 |
33 | 
34 |
--------------------------------------------------------------------------------
/app.js:
--------------------------------------------------------------------------------
1 | //app.js
2 | App({
3 | onLaunch: function () {
4 | // 展示本地存储能力
5 | var logs = wx.getStorageSync('logs') || []
6 | logs.unshift(Date.now())
7 | wx.setStorageSync('logs', logs)
8 |
9 | // 登录
10 | wx.login({
11 | success: res => {
12 | // 发送 res.code 到后台换取 openId, sessionKey, unionId
13 | }
14 | })
15 | // 获取用户信息
16 | wx.getSetting({
17 | success: res => {
18 | if (res.authSetting['scope.userInfo']) {
19 | // 已经授权,可以直接调用 getUserInfo 获取头像昵称,不会弹框
20 | wx.getUserInfo({
21 | success: res => {
22 | // 可以将 res 发送给后台解码出 unionId
23 | this.globalData.userInfo = res.userInfo
24 |
25 | // 由于 getUserInfo 是网络请求,可能会在 Page.onLoad 之后才返回
26 | // 所以此处加入 callback 以防止这种情况
27 | if (this.userInfoReadyCallback) {
28 | this.userInfoReadyCallback(res)
29 | }
30 | }
31 | })
32 | }
33 | }
34 | })
35 | },
36 | globalData: {
37 | userInfo: null
38 | }
39 | })
--------------------------------------------------------------------------------
/app.json:
--------------------------------------------------------------------------------
1 | {
2 | "pages": [
3 | "pages/bookshelf/bookshelf",
4 | "pages/details/details",
5 | "pages/bookCity/bookCity",
6 | "pages/bookCats/bookCats",
7 | "pages/reader/reader",
8 | "pages/search/search",
9 | "pages/rank/rank",
10 | "pages/help/help"
11 | ],
12 | "window": {
13 | "backgroundTextStyle": "light",
14 | "navigationBarBackgroundColor": "#fff",
15 | "navigationBarTitleText": "免费小说阅读器",
16 | "navigationBarTextStyle": "black"
17 | },
18 | "tabBar": {
19 | "color": "#333",
20 | "selectedColor": "#cb1c36",
21 | "backgroundColor": "#fff",
22 | "list": [
23 | {
24 | "iconPath": "img/mybook.png",
25 | "selectedIconPath": "img/selectedMybook.png",
26 | "pagePath": "pages/bookshelf/bookshelf",
27 | "text": "书架"
28 | },
29 | {
30 | "iconPath": "img/book.png",
31 | "selectedIconPath": "img/selectedBook.png",
32 | "pagePath": "pages/bookCity/bookCity",
33 | "text": "书城"
34 | },
35 | {
36 | "iconPath": "img/search.png",
37 | "selectedIconPath": "img/selectedSearch.png",
38 | "pagePath": "pages/search/search",
39 | "text": "搜索"
40 | }
41 | ]
42 | }
43 | }
--------------------------------------------------------------------------------
/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 | box-sizing: border-box;
10 | position: relative;
11 | }
12 |
--------------------------------------------------------------------------------
/img/book.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kesixin/ReadWechatApp/b49fbda9ae0699bf26eb74e2a406aa3631a625e4/img/book.png
--------------------------------------------------------------------------------
/img/chapter.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kesixin/ReadWechatApp/b49fbda9ae0699bf26eb74e2a406aa3631a625e4/img/chapter.png
--------------------------------------------------------------------------------
/img/edit.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kesixin/ReadWechatApp/b49fbda9ae0699bf26eb74e2a406aa3631a625e4/img/edit.png
--------------------------------------------------------------------------------
/img/icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kesixin/ReadWechatApp/b49fbda9ae0699bf26eb74e2a406aa3631a625e4/img/icon.png
--------------------------------------------------------------------------------
/img/mybook.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kesixin/ReadWechatApp/b49fbda9ae0699bf26eb74e2a406aa3631a625e4/img/mybook.png
--------------------------------------------------------------------------------
/img/ok.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kesixin/ReadWechatApp/b49fbda9ae0699bf26eb74e2a406aa3631a625e4/img/ok.png
--------------------------------------------------------------------------------
/img/otherIcon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kesixin/ReadWechatApp/b49fbda9ae0699bf26eb74e2a406aa3631a625e4/img/otherIcon.png
--------------------------------------------------------------------------------
/img/pullDown.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kesixin/ReadWechatApp/b49fbda9ae0699bf26eb74e2a406aa3631a625e4/img/pullDown.png
--------------------------------------------------------------------------------
/img/pullDowned.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kesixin/ReadWechatApp/b49fbda9ae0699bf26eb74e2a406aa3631a625e4/img/pullDowned.png
--------------------------------------------------------------------------------
/img/refresh.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kesixin/ReadWechatApp/b49fbda9ae0699bf26eb74e2a406aa3631a625e4/img/refresh.png
--------------------------------------------------------------------------------
/img/refresh1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kesixin/ReadWechatApp/b49fbda9ae0699bf26eb74e2a406aa3631a625e4/img/refresh1.png
--------------------------------------------------------------------------------
/img/search.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kesixin/ReadWechatApp/b49fbda9ae0699bf26eb74e2a406aa3631a625e4/img/search.png
--------------------------------------------------------------------------------
/img/selectedBook.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kesixin/ReadWechatApp/b49fbda9ae0699bf26eb74e2a406aa3631a625e4/img/selectedBook.png
--------------------------------------------------------------------------------
/img/selectedMybook.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kesixin/ReadWechatApp/b49fbda9ae0699bf26eb74e2a406aa3631a625e4/img/selectedMybook.png
--------------------------------------------------------------------------------
/img/selectedSearch.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kesixin/ReadWechatApp/b49fbda9ae0699bf26eb74e2a406aa3631a625e4/img/selectedSearch.png
--------------------------------------------------------------------------------
/pages/bookCats/bookCats.js:
--------------------------------------------------------------------------------
1 | // pages/bookCats/bookCats.js
2 | const api = require('../../utils/api.js');
3 | Page({
4 |
5 | /**
6 | * 页面的初始数据
7 | */
8 | data: {
9 | winHeight: "",//窗口高度
10 | STATIC_HOST: '',
11 | gender: '',
12 | major: '',
13 | currentType: 'hot',
14 | typeList: [
15 | {
16 | id: 'hot',
17 | name: '热门'
18 | },
19 | {
20 | id: 'new',
21 | name: '新书'
22 | },
23 | {
24 | id: 'reputation',
25 | name: '好评'
26 | },
27 | {
28 | id: 'over',
29 | name: '完结'
30 | },
31 | {
32 | id: 'monthly',
33 | name: 'VIP'
34 | }
35 | ],
36 | currentMinor: '全部',
37 | showMinor: true,
38 | minorList: [],
39 | bookListTop: 164, //scroll-view的相对top
40 | books: {},
41 | tagColors: ['#FF8C00', '#00CED1', '#FF4500'],
42 | start: 0, //分页起始
43 | loadMore: true, //防止多次加载
44 | loadedAll: false, //已加载全部
45 | scrollTop: 0 //scroll-view 滚动条位置
46 | },
47 |
48 | getIndexBooks: function (gender, type, major, minor, start) {
49 | wx.request({
50 | url: api.classification.getCatsBooks(gender, type, major, minor, start),
51 | success: res => {
52 | wx.hideLoading();
53 | if (res.data.books.length === 0) {
54 | this.setData({
55 | loadedAll: true
56 | })
57 | } else {
58 | if (start !== 0) {
59 | this.data.books.books = this.data.books.books.concat(res.data.books);
60 | this.setData({
61 | books: this.data.books,
62 | loadMore: true
63 | });
64 | } else {
65 | this.setData({
66 | books: res.data,
67 | start: 0,
68 | scrollTop: 0
69 | });
70 | }
71 | }
72 | }
73 | })
74 | },
75 |
76 | loadMore: function () {
77 | if (this.data.loadMore) {
78 | wx.showLoading({
79 | title: '加载中',
80 | mask: true
81 | });
82 | this.setData({
83 | start: this.data.start + 20,
84 | loadMore: false
85 | });
86 |
87 | let minor = this.data.currentMinor === '全部' ? '' : this.data.currentMinor;
88 | this.getIndexBooks(this.data.gender, this.data.currentType, this.data.major, minor, this.data.start);
89 | }
90 | },
91 |
92 | switchType: function (e) {
93 | wx.showLoading({
94 | title: '加载中',
95 | mask: true
96 | });
97 | this.setData({
98 | currentType: e.target.dataset.typeid
99 | });
100 | let minor = this.data.currentMinor === '全部' ? '' : this.data.currentMinor;
101 | this.getIndexBooks(this.data.gender, this.data.currentType, this.data.major, minor, 0);
102 | },
103 |
104 | switchMinor: function (e) {
105 | wx.showLoading({
106 | title: '加载中',
107 | mask: true
108 | });
109 | this.setData({
110 | currentMinor: e.target.dataset.typeid
111 | });
112 | console.log(this.data.currentMinor)
113 | let minor = this.data.currentMinor === '全部' ? '' : this.data.currentMinor;
114 | this.getIndexBooks(this.data.gender, this.data.currentType, this.data.major, minor, 0);
115 | },
116 | /**
117 | * 生命周期函数--监听页面加载
118 | */
119 | onLoad: function (options) {
120 | wx.showLoading({
121 | title: '加载中',
122 | mask: true
123 | });
124 | // 高度自适应
125 | wx.getSystemInfo({
126 | success: (res) => {
127 | var clientHeight = res.windowHeight,
128 | clientWidth = res.windowWidth,
129 | rpxR = 750 / clientWidth;
130 | var calc = clientHeight * rpxR - 180;
131 | this.setData({
132 | winHeight: calc
133 | });
134 | }
135 | });
136 | wx.setNavigationBarTitle({
137 | title: options.major,
138 | });
139 | wx.getStorage({
140 | key: 'minor',
141 | success: res => {
142 | let data = res.data[options.gender];
143 | for (let i = 0; i < data.length; i++) {
144 | if (data[i].major === options.major) {
145 | data[i].mins.unshift('全部');
146 | if (data[i].mins.length === 1) {
147 | this.setData({
148 | showMinor: false,
149 | bookListTop: 82,
150 | winHeight: this.data.winHeight + 80
151 | });
152 | }
153 | this.setData({
154 | STATIC_HOST: api.STATIC_HOST,
155 | minorList: data[i].mins
156 | });
157 | }
158 | }
159 | },
160 | });
161 | this.setData({
162 | gender: options.gender,
163 | major: options.major
164 | });
165 | this.getIndexBooks(options.gender, 'hot', options.major, '', 0);
166 | }
167 | })
--------------------------------------------------------------------------------
/pages/bookCats/bookCats.json:
--------------------------------------------------------------------------------
1 | {
2 | "navigationBarTitleText": "免费小说",
3 | "backgroundTextStyle": "light",
4 | "navigationBarBackgroundColor": "#cb1c36",
5 | "navigationBarTextStyle": "#f2f2f2"
6 | }
--------------------------------------------------------------------------------
/pages/bookCats/bookCats.wxml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | {{item.name}}
7 |
8 |
9 |
10 |
11 | {{item}}
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 | {{book.title}}
20 | {{book.author}}
21 | {{book.shortIntro}}
22 | {{book.tags[tag]}}
23 |
24 |
25 | 已加载全部
26 |
27 |
--------------------------------------------------------------------------------
/pages/bookCats/bookCats.wxss:
--------------------------------------------------------------------------------
1 | /* pages/bookCats/bookCats.wxss */
2 | .bookCats {
3 | background: #f7f7f7;
4 | width: 100%;
5 | }
6 |
7 | .type_wrap {
8 | position: fixed;
9 | top: 0;
10 | width: 100%;
11 | z-index: 100;
12 | background: #fff;
13 | }
14 |
15 | .type,.minor {
16 | padding-left: 20rpx;
17 | border-bottom: 1px #eee solid;
18 | width: 100%;
19 | }
20 |
21 | .type {
22 | display: flex;
23 | }
24 |
25 | .minor {
26 | white-space: nowrap;
27 | }
28 |
29 | ::-webkit-scrollbar {
30 | width: 0;
31 | height: 0;
32 | color: transparent;
33 | }
34 |
35 | .type-item,.minor-item {
36 | line-height: 80rpx;
37 | font-size: 14px;
38 | color: #666;
39 | margin-right: 30rpx;
40 | }
41 |
42 | .minor-item {
43 | display: inline-block;
44 | }
45 |
46 | .active {
47 | color: #cb1c36;
48 | }
49 |
50 | .bookList {
51 | background: #fff;
52 | position: relative;
53 | padding: 0 30rpx;
54 | width: 92%;
55 | }
56 |
57 | .book_item {
58 | border-bottom: 1px #eee solid;
59 | position: relative;
60 | height: 335rpx;
61 | }
62 |
63 | .book_item image {
64 | width: 190rpx;
65 | height: 275rpx;
66 | position: absolute;
67 | left: 0;
68 | top: 30rpx;
69 | }
70 |
71 | .book_info {
72 | position: absolute;
73 | right: 0;
74 | top: 30rpx;
75 | width: 475rpx;
76 | }
77 |
78 | .book_title {
79 | color: #333;
80 | font-size: 15px;
81 | font-weight: bold;
82 | display: block;
83 | margin-bottom: 10rpx;
84 | }
85 |
86 | .book_site,.book_desc {
87 | color: #999;
88 | font-size: 12px;
89 | line-height: 40rpx;
90 | display: block;
91 | margin-bottom: 10rpx;
92 | }
93 |
94 | .book_desc {
95 | overflow : hidden;
96 | text-overflow: ellipsis;
97 | display: -webkit-box;
98 | -webkit-line-clamp: 3;
99 | -webkit-box-orient: vertical;
100 | }
101 |
102 | .book_tag {
103 | display: inline-block;
104 | }
105 |
106 | .book_tag_item {
107 | display: inline-block;
108 | color: #fff;
109 | font-size: 12px;
110 | padding: 0 8rpx;
111 | line-height: 40rpx;
112 | border-radius: 5rpx;
113 | margin-right: 10rpx;
114 | }
115 |
116 | .loadedAll {
117 | text-align: center;
118 | line-height: 50rpx;
119 | color: #666;
120 | font-size: 15px;
121 | }
--------------------------------------------------------------------------------
/pages/bookCity/bookCity.js:
--------------------------------------------------------------------------------
1 | // pages/bookCity/bookCity.js
2 | const api = require('../../utils/api.js')
3 |
4 | Page({
5 | data: {
6 | STATIC_HOST: '',
7 | winHeight: "",//窗口高度
8 | currentTab: 0, //预设当前项的值
9 | majorList: {},
10 | rankCategory: {},
11 | openMaleOther: false, //控制列表伸缩
12 | openFemaleOther: false
13 | },
14 | // 滚动切换标签样式
15 | switchTab: function (e) {
16 | this.setData({
17 | currentTab: e.detail.current
18 | });
19 | },
20 | // 点击标题切换当前页时改变样式
21 | swichNav: function (e) {
22 | var cur = e.target.dataset.current;
23 | if (this.data.currentTaB == cur) { return false; }
24 | else {
25 | this.setData({
26 | currentTab: cur
27 | })
28 | }
29 | },
30 | //展开当前其他排行榜
31 | toggleList: function (e) {
32 | let id = e.target.dataset.id;
33 | if (id === '0') {
34 | this.setData({
35 | openMaleOther: !this.data.openMaleOther
36 | });
37 | } else if (id === '1') {
38 | this.setData({
39 | openFemaleOther: !this.data.openFemaleOther
40 | });
41 | }
42 | },
43 | //获取一级分类及数目
44 | getCats: function () {
45 | wx.request({
46 | url: api.classification.getCats,
47 | success: (res) => {
48 | this.setData({
49 | majorList: res.data
50 | });
51 | }
52 | })
53 | },
54 | //获取二级分类
55 | getMinor: function () {
56 | wx.request({
57 | url: api.classification.getMinor,
58 | success: function (res) {
59 | wx.hideLoading();
60 | wx.setStorage({
61 | key: 'minor',
62 | data: res.data,
63 | })
64 | }
65 | });
66 | },
67 | //获取排行
68 | getRankCategory: function () {
69 | wx.request({
70 | url: api.rank.rankCategory,
71 | success: res => {
72 | for (let key in res.data) { //对于有别人家的排行榜的特殊处理 将追书替换为轻读
73 | for (let i = 0; i < res.data[key].length; i++) {
74 | res.data[key][i].title = res.data[key][i].title.replace('追书', '轻读');
75 | if (res.data[key][i].collapse) {
76 | res.data[key].splice(i, 0, {
77 | title: '别人家的排行榜',
78 | key: 'isOther',
79 | collapse: true,
80 | cover: '../../img/otherIcon.png'
81 | });
82 | break;
83 | }
84 | }
85 | }
86 | this.setData({
87 | rankCategory: res.data
88 | });
89 | }
90 | })
91 | },
92 | onLoad: function () {
93 | this.setData({
94 | STATIC_HOST: api.STATIC_HOST
95 | });
96 | wx.showLoading({
97 | title: '加载中',
98 | mask: true
99 | })
100 | this.getCats();
101 | this.getMinor();
102 | this.getRankCategory();
103 | // 高度自适应
104 | wx.getSystemInfo({
105 | success: (res) => {
106 | var clientHeight = res.windowHeight,
107 | clientWidth = res.windowWidth,
108 | rpxR = 750 / clientWidth;
109 | var calc = clientHeight * rpxR - 80;
110 | this.setData({
111 | winHeight: calc
112 | });
113 | }
114 | });
115 | }
116 | })
--------------------------------------------------------------------------------
/pages/bookCity/bookCity.json:
--------------------------------------------------------------------------------
1 | {
2 | "navigationBarTitleText": "书城",
3 | "backgroundTextStyle": "light",
4 | "navigationBarBackgroundColor": "#cb1c36",
5 | "navigationBarTextStyle": "#f2f2f2"
6 | }
--------------------------------------------------------------------------------
/pages/bookCity/bookCity.wxml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
7 | 分类
8 | 排行
9 |
10 |
11 |
14 |
15 |
16 |
17 | 男生
18 |
19 |
20 | {{item.name}}
21 | {{item.bookCount}}本
22 |
23 |
24 |
25 |
26 | 女生
27 |
28 |
29 | {{item.name}}
30 | {{item.bookCount}}本
31 |
32 |
33 |
34 |
43 |
44 | 出版
45 |
46 |
47 | {{item.name}}
48 | {{item.bookCount}}本
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 | 男生
58 |
59 |
60 |
61 | {{item.title}}
62 |
63 |
64 |
65 |
66 | 女生
67 |
68 |
69 |
70 | {{item.title}}
71 |
72 |
73 |
74 |
86 |
87 |
88 |
89 |
--------------------------------------------------------------------------------
/pages/bookCity/bookCity.wxss:
--------------------------------------------------------------------------------
1 | /* pages/bookCity/bookCity.wxss */
2 |
3 | .tab-h {
4 | height: 80rpx;
5 | width: 100%;
6 | box-sizing: border-box;
7 | overflow: hidden;
8 | line-height: 80rpx;
9 | background: #f7f7f7;
10 | font-size: 16px;
11 | white-space: nowrap;
12 | position: fixed;
13 | top: 0;
14 | left: 0;
15 | z-index: 99;
16 | }
17 |
18 | /* .tab-item { 有书单
19 | display: inline-block;
20 | width: 33.3%;
21 | text-align: center;
22 | } */
23 |
24 | .tab-item {
25 | display: inline-block;
26 | width: 50%;
27 | text-align: center;
28 | }
29 |
30 | .tab-item.active {
31 | color: #ec304c;
32 | position: relative;
33 | }
34 |
35 | /* .tab-item.active:after { 有书单
36 | content: "";
37 | display: block;
38 | height: 4rpx;
39 | width: 52rpx;
40 | background: #ec304c;
41 | position: absolute;
42 | bottom: 0;
43 | left: 98rpx;
44 | border-radius: 16rpx;
45 | } */
46 |
47 | .tab-item.active:after {
48 | content: "";
49 | display: block;
50 | height: 4rpx;
51 | width: 52rpx;
52 | background: #ec304c;
53 | position: absolute;
54 | bottom: 0;
55 | left: 160rpx;
56 | border-radius: 16rpx;
57 | }
58 |
59 | .tab-content {
60 | margin-top: 80rpx;
61 | }
62 |
63 | .scroll-h {
64 | height: 100%;
65 | }
66 |
67 | .Cats, .rank_item {
68 | width: 100%;
69 | }
70 |
71 | .bookCat, .bookRank {
72 | color: #999;
73 | font-size: 15px;
74 | line-height: 100rpx;
75 | text-align: left;
76 | padding-left: 20rpx;
77 | }
78 |
79 | .Cats view {
80 | display: flex;
81 | justify-content: flex-start;
82 | flex-direction: row;
83 | flex-wrap: wrap;
84 | }
85 |
86 | .rank_item {
87 | overflow: hidden;
88 | transition: .6s all ease-in-out;
89 | }
90 |
91 | .rank_item .rank_item_item {
92 | width: 95%;
93 | border-bottom: 1px #eee solid;
94 | height: 90rpx;
95 | line-height: 90rpx;
96 | display: flex;
97 | flex-direction: row;
98 | margin-left: 5%;
99 | }
100 |
101 | .rank_item_item .rank_icon {
102 | width: 55rpx;
103 | height: 55rpx;
104 | position: relative;
105 | top: 18rpx;
106 | }
107 |
108 | .rank_item_item view {
109 | font-size: 15px;
110 | color: #333;
111 | height: 90rpx;
112 | line-height: 90rpx;
113 | margin-left: 20rpx;
114 | }
115 |
116 | .rank_item_item .pulldown_icon {
117 | width: 35rpx;
118 | height: 35rpx;
119 | position: relative;
120 | top: 32rpx;
121 | left: 345rpx;
122 | }
123 |
124 | .catBlock {
125 | height: 120rpx;
126 | display: flex;
127 | width: 33.3%;
128 | flex-direction: column;
129 | text-align: center;
130 | border: 1px #f7f7f7 solid;
131 | box-sizing: border-box;
132 | }
133 |
134 | .catName {
135 | font-size: 15px;
136 | color: #333;
137 | font-weight: bold;
138 | margin-top: 15rpx;
139 | }
140 |
141 | .catCount {
142 | font-size: 12px;
143 | margin-top: 10rpx;
144 | color: #999;
145 | }
146 |
--------------------------------------------------------------------------------
/pages/bookshelf/bookshelf.js:
--------------------------------------------------------------------------------
1 | //index.js
2 | //获取应用实例
3 | const app = getApp()
4 | const api = require('../../utils/api.js');
5 | Page({
6 | data: {
7 | STATIC_HOST: '',
8 | userInfo: {},
9 | bookShelfData: [],
10 | hasUpdate: [],
11 | isEdit: false
12 | },
13 |
14 | edit: function () {
15 | this.setData({
16 | isEdit: !this.data.isEdit
17 | });
18 | },
19 |
20 | delete: function (e) {
21 | let i = e.target.dataset.id;
22 | this.data.bookShelfData.splice(i,1);
23 | wx.getStorage({
24 | key: 'bookShelfData',
25 | success: function(res) {
26 | res.data.splice(i, 1);
27 | wx.setStorage({
28 | key: 'bookShelfData',
29 | data: res.data,
30 | })
31 | },
32 | })
33 | this.setData({
34 | bookShelfData: this.data.bookShelfData
35 | });
36 | },
37 |
38 | getlasterChapter: function () {
39 | for (let i = 0; i < this.data.bookShelfData.length; i++) {
40 | wx.request({
41 | url: api.book.bookChaptersBookId(this.data.bookShelfData[i].bookInfo.id),
42 | success: res => {
43 | wx.hideLoading();
44 | //如果有更新就将最近更新的时间刷新进去,初次与加入书架时比较
45 | if (Date.parse(this.data.bookShelfData[i].bookInfo.laterChapter) + 60 * 60 * 24 <= Date.parse(res.data.mixToc.chaptersUpdated)) {
46 | this.data.bookShelfData[i].bookInfo.laterChapter = res.data.mixToc.chaptersUpdated;
47 | wx.setStorage({
48 | key: 'bookShelfData',
49 | data: this.data.bookShelfData,
50 | })
51 | this.data.hasUpdate[i] = 1;
52 | this.setData({
53 | hasUpdate: this.data.hasUpdate
54 | });
55 | }
56 | }
57 | })
58 | }
59 | wx.hideLoading();
60 | },
61 | getShelfInfo: function () {
62 | wx.getStorage({ //获取书架信息
63 | key: 'bookShelfData',
64 | success: res => {
65 | this.setData({
66 | STATIC_HOST: api.STATIC_HOST,
67 | bookShelfData: res.data
68 | });
69 | for (let i = 0;i < res.data.length; i++) {
70 | this.data.hasUpdate.push(0); //用数组表示是否有更新, 1 有 0 无
71 | this.setData({
72 | hasUpdate: this.data.hasUpdate
73 | });
74 | }
75 | this.getlasterChapter();
76 | },
77 | fail: function () {
78 | wx.hideLoading();
79 | wx.setStorage({
80 | key: 'bookShelfData',
81 | data: [],
82 | })
83 | }
84 | })
85 | },
86 | onLoad: function () {
87 | /*wx.getUserInfo({
88 | success: res => {
89 | app.globalData.userInfo = res.userInfo
90 | this.setData({
91 | userInfo: res.userInfo,
92 | hasUserInfo: true
93 | })
94 | }
95 | });*/
96 | },
97 | onShow: function () {
98 | wx.showLoading({
99 | title: '加载中',
100 | mask: true
101 | });
102 | this.setData({
103 | hasUpdate: []
104 | });
105 | this.getShelfInfo();
106 | }
107 | })
--------------------------------------------------------------------------------
/pages/bookshelf/bookshelf.json:
--------------------------------------------------------------------------------
1 | {
2 | "navigationBarTitleText": "免费小说",
3 | "backgroundTextStyle": "light",
4 | "navigationBarBackgroundColor": "#cb1c36",
5 | "navigationBarTextStyle": "#f2f2f2"
6 | }
--------------------------------------------------------------------------------
/pages/bookshelf/bookshelf.wxml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | 帮助
7 |
8 |
9 |
10 | 主人还没收藏书籍哦,请去书城收藏吧!
11 |
12 |
13 | 有更新
14 |
15 |
16 | {{item.bookInfo.title}}
17 | 读到第{{item.readNum}}章
18 |
19 |
20 |
--------------------------------------------------------------------------------
/pages/bookshelf/bookshelf.wxss:
--------------------------------------------------------------------------------
1 | /**index.wxss**/
2 |
3 | .userinfo {
4 | display: flex;
5 | flex-direction: row;
6 | padding: 20rpx 0;
7 | width: 100%;
8 | border-bottom: 20rpx #f7f7f7 solid;
9 | position: relative;
10 | }
11 |
12 | .userinfo-avatar {
13 | width: 128rpx;
14 | height: 128rpx;
15 | margin: 20rpx;
16 | border-radius: 50%;
17 | }
18 |
19 | .userbookinfo {
20 | height: 100rpx;
21 | position: relative;
22 | top: 20rpx;
23 | }
24 |
25 | .userinfo-nickname {
26 | color: #222;
27 | font-size: 18px;
28 | display: block;
29 | line-height: 80rpx;
30 | }
31 |
32 | .booksNum {
33 | color: #666;
34 | font-size: 13px;
35 | display: block;
36 | line-height: 30rpx;
37 | }
38 |
39 | .booksNum text {
40 | color: #cb1c36;
41 | }
42 |
43 |
44 |
45 | .bookshelfContainer {
46 | padding: 30rpx 0;
47 | margin: 0 80rpx;
48 | display: flex;
49 | flex-direction: row;
50 | flex-wrap: wrap;
51 | width: 92%;
52 | margin-top: 20rpx;
53 | }
54 |
55 | .operation {
56 | width: 100%;
57 | margin-bottom: 40rpx;
58 | display: flex;
59 | flex-direction: row;
60 | justify-content: space-between;
61 | }
62 |
63 | .edit, .refresh1 {
64 | width: 50rpx;
65 | height: 50rpx;
66 | }
67 | .help {
68 | line-height: 60rpx;
69 | font-size: 15px;
70 | color: #666;
71 | position: absolute;
72 | top: 80rpx;
73 | transform: translateY(-50%);
74 | right: 120rpx;
75 | border: 1px #999 solid;
76 | border-radius: 20%;
77 | text-align: center;
78 | width: 105rpx;
79 | }
80 |
81 | .bookshelf_item {
82 | position: relative;
83 | width: 30%;
84 | margin: 0 30rpx 30rpx 0;
85 | }
86 |
87 | .noMargin {
88 | margin-right: 0;
89 | }
90 |
91 | .bookshelf_item image {
92 | width: 210rpx;
93 | height: 300rpx;
94 | margin: 0 auto;
95 | }
96 |
97 | .deletIcon {
98 | position: absolute;
99 | right: 0;
100 | top: 0;
101 | z-index: 20;
102 | }
103 |
104 | .bookshelf_item .name {
105 | color: #222;
106 | font-size: 15px;
107 | }
108 |
109 | .readNum {
110 | color: #999;
111 | font-size: 13px;
112 | }
113 |
114 | .hasUpdate {
115 | color: #fff;
116 | background: #cb1c36;
117 | width: 90rpx;
118 | height: 40rpx;
119 | text-align: center;
120 | line-height: 40rpx;
121 | font-size: 12px;
122 | position: absolute;
123 | top: 0;
124 | right: 0;
125 | z-index: 10;
126 | }
127 |
128 | .noBooks {
129 | margin-top: 60rpx;
130 | text-align: center;
131 | color: #333;
132 | font-size: 16px;
133 | width: 100%;
134 | }
135 |
136 | @keyframes delete {
137 | 0% {
138 | transform: rotate(0deg);
139 | }
140 |
141 | 25% {
142 | transform: rotate(-1deg);
143 | }
144 |
145 | 50% {
146 | transform: rotate(0deg);
147 | }
148 |
149 | 75% {
150 | transform: rotate(1deg);
151 | }
152 |
153 | 100% {
154 | transform: rotate(0deg);
155 | }
156 | }
157 |
158 | .deletAnimation {
159 | animation: delete 1s linear infinite;
160 | }
161 |
162 |
--------------------------------------------------------------------------------
/pages/details/details.js:
--------------------------------------------------------------------------------
1 | // pages/details/details.js
2 | const api = require('../../utils/api.js');
3 | Page({
4 |
5 | /**
6 | * 页面的初始数据
7 | */
8 |
9 | data: {
10 | STATIC_HOST: '',
11 | bookInfo: {},
12 | book_rate: 0, //书籍评分
13 | showInfoContent: true,
14 | allRecommendBooks: [],//全部推荐书籍
15 | showRecommendBooks: [], //随机展示的三本推荐书籍
16 | shortReviews: {},
17 | addedShelf: false
18 | },
19 |
20 | showTab: function (event) {
21 | this.setData({
22 | showInfoContent: !!parseInt(event.target.dataset.id)
23 | });
24 | },
25 |
26 | addShelf: function () {
27 | if (this.data.addedShelf) {
28 | return
29 | }
30 | let shelfData = {
31 | bookInfo: {
32 | id: this.data.bookInfo._id,
33 | title: this.data.bookInfo.title,
34 | cover: this.data.bookInfo.cover,
35 | laterChapter: this.data.bookInfo.updated
36 | },
37 | readNum: 1,
38 | laterScrollTop: 0 //上次滑动的距离
39 | };
40 | wx.getStorage({
41 | key: 'bookShelfData',
42 | success: res => {
43 | res.data.unshift(shelfData);
44 | wx.setStorage({
45 | key: 'bookShelfData',
46 | data: res.data,
47 | });
48 | this.setData({
49 | addedShelf: true
50 | });
51 | },
52 | })
53 | },
54 |
55 | getBookInfo: function (book_id) {
56 | wx.request({
57 | url: api.book.bookInfo(book_id),
58 | success: res => {
59 | wx.hideLoading();
60 | let score = Math.floor(res.data.rating.score / 2);
61 | this.setData({
62 | bookInfo: res.data,
63 | book_rate: score
64 | });
65 | }
66 | })
67 | },
68 |
69 | getRelatedRecommendedBooks: function (book_id) {
70 | wx.request({
71 | url: api.book.relatedRecommendedBooks(book_id),
72 | success: res => {
73 | this.setData({
74 | allRecommendBooks: res.data.books
75 | });
76 | this.randomRecommendBooks();
77 | }
78 | })
79 | },
80 |
81 | randomRecommendBooks: function () { //在所有推荐书籍中随机选出三本展示
82 | this.setData({
83 | showRecommendBooks: []
84 | });
85 | let recommendBooksLen = this.data.allRecommendBooks.length;
86 | let randomIndex;
87 | for (let i = 0; i < 3; i++) {
88 | let newRandom = Math.floor(Math.random() * recommendBooksLen);
89 | if (newRandom === randomIndex) {
90 | i--;
91 | break;
92 | }
93 | randomIndex = newRandom;
94 | this.data.showRecommendBooks.push(this.data.allRecommendBooks[randomIndex])
95 | }
96 | this.setData({
97 | showRecommendBooks: this.data.showRecommendBooks
98 | });
99 | },
100 |
101 | getBookShortReviews(book_id) {
102 | wx.request({
103 | url: api.comment.shortReviews(book_id),
104 | success: res => {
105 | this.setData({
106 | shortReviews: res.data
107 | });
108 | }
109 | })
110 | },
111 | /**
112 | * 生命周期函数--监听页面加载
113 | */
114 | onLoad: function (options) {
115 | wx.showLoading({
116 | title: '加载中',
117 | mask: true
118 | });
119 | wx.getStorage({ //检查此书是否加入书架
120 | key: 'bookShelfData',
121 | success: res => {
122 | res.data.forEach(item => {
123 | if (item.bookInfo.id === options.book_id) {
124 | this.setData({
125 | addedShelf: true
126 | });
127 | return;
128 | }
129 | });
130 | },
131 | });
132 | this.setData({
133 | STATIC_HOST: api.STATIC_HOST
134 | });
135 | this.getBookInfo(options.book_id);
136 | this.getRelatedRecommendedBooks(options.book_id);
137 | this.getBookShortReviews(options.book_id);
138 | },
139 |
140 | /**
141 | * 生命周期函数--监听页面初次渲染完成
142 | */
143 | onReady: function () {
144 | wx.hideLoading();
145 | },
146 |
147 | /**
148 | * 生命周期函数--监听页面显示
149 | */
150 | onShow: function () {
151 |
152 | },
153 |
154 | /**
155 | * 生命周期函数--监听页面隐藏
156 | */
157 | onHide: function () {
158 |
159 | },
160 |
161 | /**
162 | * 生命周期函数--监听页面卸载
163 | */
164 | onUnload: function () {
165 |
166 | },
167 |
168 | /**
169 | * 页面相关事件处理函数--监听用户下拉动作
170 | */
171 | onPullDownRefresh: function () {
172 |
173 | },
174 |
175 | /**
176 | * 页面上拉触底事件的处理函数
177 | */
178 | onReachBottom: function () {
179 |
180 | },
181 |
182 | /**
183 | * 用户点击右上角分享
184 | */
185 | onShareAppMessage: function () {
186 |
187 | }
188 | })
189 |
--------------------------------------------------------------------------------
/pages/details/details.json:
--------------------------------------------------------------------------------
1 | {
2 | "navigationBarTitleText": "详情",
3 | "backgroundTextStyle": "light",
4 | "navigationBarBackgroundColor": "#cb1c36",
5 | "navigationBarTextStyle": "#f2f2f2"
6 | }
--------------------------------------------------------------------------------
/pages/details/details.wxml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 | {{bookInfo.title}}
10 | {{bookInfo.author}}
11 |
12 | 开始阅读
13 | {{addedShelf ? '已加入书架' : '加入书架'}}
14 |
15 |
16 |
17 |
18 | ★
19 |
20 | 更新至
21 | {{bookInfo.lastChapter}}
22 |
23 |
24 |
25 | 详情
26 | 评价({{shortReviews.total}})
27 |
28 |
29 |
30 | 简介: {{bookInfo.longIntro}}
31 |
32 |
33 | 总目录({{bookInfo.chaptersCount}}章)
34 |
35 |
36 | 看过这本书的人还在看
37 | 换一换
38 |
39 |
40 |
41 |
42 | {{item.title}}
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 | {{item.author.nickname}}
52 | {{item.content}}
53 |
54 |
55 |
56 |
57 |
58 |
--------------------------------------------------------------------------------
/pages/details/details.wxss:
--------------------------------------------------------------------------------
1 | /* pages/details/details.wxss */
2 |
3 | .details {
4 | display: flex;
5 | flex-direction: column;
6 | align-items: center;
7 | background: #f7f7f7;
8 | }
9 |
10 | .background {
11 | width: 100%;
12 | border-bottom: 1px #eee solid;
13 | }
14 |
15 | .background .top {
16 | background-color: #cb1c36;
17 | width: 100%;
18 | height: 150rpx;
19 | }
20 |
21 | .background .bottom {
22 | background-color: #fff;
23 | width: 100%;
24 | height: 400rpx;
25 | }
26 |
27 | .bookInfo {
28 | display: flex;
29 | justify-content: center;
30 | flex-direction: column;
31 | position: absolute;
32 | top: 10rpx;
33 | }
34 |
35 | .bookInfo image {
36 | width: 250rpx;
37 | height: 350rpx;
38 | margin: 0 auto;
39 | box-shadow: 0 2px 5px 0 #888;
40 | }
41 |
42 | .bookTitle {
43 | color: #11212e;
44 | font-size: 18px;
45 | font-weight: bold;
46 | text-align: center;
47 | display: block;
48 | margin-top: 20rpx;
49 | }
50 |
51 | .bookSite {
52 | color: #999;
53 | font-size: 15px;
54 | text-align: center;
55 | display: block;
56 | margin: 20rpx 0;
57 | }
58 |
59 | .infoBtn {
60 | display: flex;
61 | justify-content: space-around;
62 | }
63 |
64 | .startRead, .addReader {
65 | width: 250rpx;
66 | line-height: 80rpx;
67 | font-size: 15px;
68 | border-radius: 50rpx;
69 | text-align: center;
70 | }
71 |
72 | .startRead {
73 | background-color: #ec304c;
74 | color: #f2f2f2;
75 | margin-right: 35rpx;
76 | }
77 |
78 | .addReader {
79 | background-color: #fff;
80 | color: #666;
81 | margin-left: 35rpx;
82 | box-shadow: 0 0 1px 1px #eee;
83 | }
84 |
85 | .bookMsg {
86 | padding: 65rpx 0 900rpx 0;
87 | position: relative;
88 | }
89 |
90 | .rate {
91 | display: flex;
92 | flex-direction: row;
93 | justify-content: center;
94 | }
95 |
96 | .rate_item {
97 | font-size: 20px;
98 | color: #999;
99 | margin-right: 15rpx;
100 | }
101 |
102 | .rate_active {
103 | color: #ec304c;
104 | }
105 |
106 | .lastChapter {
107 | font-size: 13px;
108 | color: #333;
109 | text-align: center;
110 | width: 100%;
111 | }
112 |
113 | .lastChapter text {
114 | color: #40e0d0;
115 | }
116 |
117 | .info_commit {
118 | position: absolute;
119 | bottom: 75rpx;
120 | left: 50%;
121 | transform: translateX(-50%);
122 | background-color: #fff;
123 | width: 680rpx;
124 | }
125 |
126 | .info_commit .tab {
127 | width: 100%;
128 | display: flex;
129 | justify-content: space-between;
130 | line-height: 80rpx;
131 | border-bottom: 1px #eee solid;
132 | }
133 |
134 | .info_commit .tab_item {
135 | width: 50%;
136 | text-align: center;
137 | font-size: 15px;
138 | color: #666;
139 | }
140 |
141 | .info_commit .tab_item.active {
142 | color: #ec304c;
143 | position: relative;
144 | }
145 |
146 | .info_commit .tab_item.active:after {
147 | content: "";
148 | display: block;
149 | height: 4rpx;
150 | width: 52rpx;
151 | background: #ec304c;
152 | position: absolute;
153 | bottom: 0;
154 | left: 144rpx;
155 | border-radius: 16rpx;
156 | }
157 |
158 | .commit_content, .info_content {
159 | height: 700rpx;
160 | }
161 |
162 | .info_desc {
163 | font-size: 13px;
164 | color: #333;
165 | line-height: 45rpx;
166 | margin: 20rpx 30rpx;
167 | }
168 |
169 | .openChapter {
170 | display: block;
171 | line-height: 60rpx;
172 | font-size: 13px;
173 | color: #666;
174 | text-align: center;
175 | background: #f7f7f7;
176 | width: 92%;
177 | margin: 0 auto;
178 | }
179 |
180 | .openChapter image {
181 | width: 32rpx;
182 | height: 32rpx;
183 | position: relative;
184 | top: 6rpx;
185 | }
186 |
187 | .Recommend {
188 | margin: 50rpx 30rpx 20rpx 30rpx;
189 | }
190 |
191 | .re_topic {
192 | display: flex;
193 | justify-content: space-between;
194 | flex-direction: row;
195 | }
196 |
197 | .re_title, .re_refresh {
198 | font-size: 15px;
199 | }
200 |
201 | .re_title {
202 | width: 50%;
203 | color: #333;
204 | }
205 |
206 | .re_refresh {
207 | width: 22%;
208 | background: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAEAAAABACAYAAACqaXHeAAAFVklEQVR4Xu1aTXraSBB9JWYmyzgniHOC2CcwLAzZxT5BMMw+9glCThB7PwJ8guBdwIuQEwxzgtgnGNgNjKXK192S3EII1PoB/6Dv8wKrVd3v9euqruomPPOHnjl+bAnYKuCZM7BdAs9cAFsnuF0C2yWwRga4frgHsl6DeE92S9gDaAfMQ/mbaQR2b6l7PVrXsApfAnxSew/CEYAyCLuJgDGPAerBokv665sip6CnMAK4Wf0AplY8aJ6AoWaa6CAWH+MGxC2yB5dFcJA7AdysHoHpSxg4TwD0pNTd/3vUHY4XgeH6u11YThlkCcW8D7fhEcg6y1sRuRLAjVoHhLo28Fuw26L2ddd09rhe3oH1+xHIagF4HXzP3KL24LOpvbj2uRAgZ67kfgVIOTcgNfD5gSoi/jgF4RSgl977IZzpcZySTMjJh4Bm7RzAR6/jKzjTeh6D04F4RAxB9Fb9n0dwZpWs/eRCgBxOs9oF44baAyHZQh5JQumFWE6ef+AR2YP9LJ3lRkCWQZh+K8kGfVBCQJfa/RNTG377R0mAUlytFyiBcUbtvliGxs/jJUA5R+UTxMbJnb1J4w8eLQFSBX++K4P5u+cUL8ke6CE4kRoeNQGB8/X9gUNvqPvtJhFyr5ERAR7jb8nuX5h0UmRbtQfhn2lVkJiAkNwyet68CQmiAvOY2oNXJvYTESDTWIu+g2hHM35Bdv/UpLOi2sr8A/TVU8Ex2QMRIRI9KwmIAe/15Z6k2ecnGplhI25WRQottspGE7OUgDB4kdEFe/H74fHDIIEbVRESD8D8g9qDclL+YgmIgHe4jJL1tzTMLLKxo/sYzJV1VnEWgeNGtQWiT+Id2f2VyvZtLGy4EPxvJVG6UjGXqII7Z4wSDaUq5EZksyRwoyYyxi+ZCVgEXsxuKAp48Va29VWRU3a2SrrcrMmscz4ULxqfbotPDg+oc/1j3n5EAdyo/byv5nDgUfUOdIlx47AOsjqe4SHZ/coqEGnfhwhn/qxnniECiCp65Ugr1EQcZJQAmdtzHcynuodfJjEO6gE8IXugh8q0WGO/40Z1FNQENAccp4BQlWqONKmkpCMMdzB9NZ94yPd3uDHdiibt328XKYw47r5cotpewFdouETHC3OFdATMScwURNb2ainoDtjah+XW9SiQBLyZAvQ99wOI/SEShANmTPx9AEDCj/mZ4RXZfVFlXvgkVoAM/yl3W1lnPO77OQccbcb8D9xZeVmdwJAAvwqTvRaXFymxJCQAb7QEpAL0kJci984L9LydUI1QDnT1zPs2zBSgqrL/yo8XhJSiACaxq6XEK2Wv2zMiQPkBbxlkqMMlAZSmjQjFpkdn5gTodbgHpoI0pBkToHyBl3qKH95GJE3nD+GbdASos8CRqg/kc0S1KTJSEeCpIMi/s57ObAq8cRhcGn7WVCgVuUCaA5A4klMrQKpAP51RPeR2bL1owN72tyPuEmU5D8wUBiMqiJAgfIJ1nHdWqG6eoBNUpnPKRzIpwCcjemytTm3hTs+yylVdm+FPoZsnGQ5D5ycwFwICIrS6nLdbFHeBzuHylWnRVJXmrI/hKzc8gcNlU1vLnGyuBCi/IGbM7UZufonbXuAeWOTx7hhcuvWXibo/iJewaBdMZYBFxVmrLMkbZedwZ+dZFVWoAnTjXgVJnBzN3fYyDnoXcKatvIH7o8hdAVEnKdfwkTer8fcB7z+8BeTN0R6c2bAo4GsjIErI4R7EGYPr7AIk/sawSF2YvPtvVDTgtS0BY6Fv6IPCl8CGcCXudktAYqqeaMOtAp7oxCaGtVVAYqqeaMOtAp7oxCaG9QvrvMZfXd+MCQAAAABJRU5ErkJggg==") no-repeat left center;
209 | background-size: 45rpx 45rpx;
210 | color: #ff6347;
211 | text-align: right;
212 | }
213 |
214 | .re_books {
215 | display: flex;
216 | flex-direction: row;
217 | justify-content: space-between;
218 | margin-top: 20rpx;
219 | }
220 |
221 | .re_bookItem {
222 | flex-direction: column;
223 | width: 33.3%;
224 | }
225 |
226 | .re_bookItem image {
227 | width: 190rpx;
228 | height: 275rpx;
229 | }
230 |
231 | .re_bookTitle {
232 | color: #333;
233 | font-size: 12px;
234 | text-align: center;
235 | }
236 |
237 | .review_item {
238 | position: relative;
239 | margin: 30rpx 20rpx;
240 | }
241 |
242 | .review_item image {
243 | width: 100rpx;
244 | height: 100rpx;
245 | border-radius: 50%;
246 | vertical-align: top;
247 | }
248 |
249 | .review_info {
250 | display: inline-block;
251 | width: 79%;
252 | margin-left: 30rpx;
253 | }
254 |
255 | .review_site {
256 | color: #ff6347;
257 | font-size: 14px;
258 | line-height: 50rpx;
259 | }
260 |
261 | .review_content {
262 | color: #666;
263 | font-size: 12px;
264 | line-height: 40rpx;
265 | }
--------------------------------------------------------------------------------
/pages/help/help.js:
--------------------------------------------------------------------------------
1 | // pages/help/help.js
2 | Page({
3 | /**
4 | * 页面的初始数据
5 | */
6 | data: {
7 | helpList: [{
8 | title: '此小程序能阅读哪些书籍?',
9 | content: '目前可以阅读几乎全网的书籍,如果遇到“还没有给主人搬到此书,去看看别的吧”这样的提示,这说明此书籍无法阅读,欢迎阅读其它书籍或者去正版网站购买阅读。'
10 | },
11 | {
12 | title: '进入阅读模式如何调出菜单?',
13 | content: '进入阅读模式中,点击屏幕中央可以呼出菜单,目前提供了夜间转换、护眼转换、目录查看和字体设置,后期还会加入新功能。'
14 | },
15 | {
16 | title: '以后会收费吗',
17 | content: '承诺永远不会向主人索要小费,希望主人永远支持,也会竭尽全力给主人提供更好的服务。'
18 | },
19 | {
20 | title: '免责声明',
21 | content: '您在使用轻读书屋之前请无比仔细阅读并理解本声明,您可以选择不使用本小程序,但如果您使用本小程序,您的使用将被视为对本声明内容的全部认可。免费读书屋是一款提供网络小说即使更新阅读的小程序,为广大小说爱好者提供一种方便快捷舒适的试读体验。致力于最大程度的减少读者在自行搜索过程中的毫无意义的时间浪费,通过专业的搜索展示不同网站中的网络小说新章节。当您点击搜索一本书时,本小程序将会对该书名以关键词的形式提交到第三方网站或者搜索引擎(百度谷歌等)第三方网站反馈内容与本小程序无关以不承担任何法律责任。第三方搜索引擎结果根据您提交的关键词自动搜索并获得阅读,并不代表我们赞成赞成第三方网站的内容,您应该对使用搜索引擎的搜索结果自行承担风险。我们不做任何形式的保证。我们建议阅读正版,任何单位或者个人认为通过本小程序搜索连接到的第三方网页内容可能涉嫌侵犯其网络传播权,应该及时向我们提供书面通知,我们收到法律文件后尽快断开相关连接内容。'
22 | }]
23 | },
24 | })
--------------------------------------------------------------------------------
/pages/help/help.json:
--------------------------------------------------------------------------------
1 | {
2 | "navigationBarTitleText": "帮助",
3 | "backgroundTextStyle": "light",
4 | "navigationBarBackgroundColor": "#cb1c36",
5 | "navigationBarTextStyle": "#f2f2f2"
6 | }
--------------------------------------------------------------------------------
/pages/help/help.wxml:
--------------------------------------------------------------------------------
1 |
2 |
3 | 常见问题与声明
4 |
5 | {{item.title}}
6 | {{item.content}}
7 |
8 |
9 |
--------------------------------------------------------------------------------
/pages/help/help.wxss:
--------------------------------------------------------------------------------
1 | /* pages/help/help.wxss */
2 | .help_title {
3 | font-size: 20px;
4 | height: 60rpx;
5 | line-height: 60rpx;
6 | width: 100%;
7 | text-indent: 30rpx;
8 | color: #333;
9 | font-weight: bold;
10 | }
11 | .help_item {
12 | width: 92%;
13 | }
14 |
15 | .help_item .item_title {
16 | margin-left: 30rpx;
17 | font-size: 16px;
18 | width: 100%;
19 | color: #333;
20 | border-bottom: 1px #f7f7f7 solid;
21 | line-height: 80rpx;
22 | height: 80rpx;
23 | }
24 |
25 | .help_item .item_content {
26 | width: 100%;
27 | margin-left: 30rpx;
28 | font-size: 14px;
29 | line-height: 55rpx;
30 | color: #666;
31 | text-indent: 57rpx;
32 | border-bottom: 1px #f7f7f7 solid;
33 | }
--------------------------------------------------------------------------------
/pages/rank/rank.js:
--------------------------------------------------------------------------------
1 | // pages/rank/rank.js
2 | const api = require('../../utils/api.js');
3 | Page({
4 |
5 | /**
6 | * 页面的初始数据
7 | */
8 | data: {
9 | STATIC_HOST: '',
10 | winHeight: "",//窗口高度
11 | currentTab: 0, //预设当前项的值
12 | weekRank: [],
13 | monthRank: [],
14 | totalRank: []
15 | },
16 |
17 | // 滚动切换标签样式
18 | switchTab: function (e) {
19 | this.setData({
20 | currentTab: e.detail.current
21 | });
22 | },
23 | // 点击标题切换当前页时改变样式
24 | swichNav: function (e) {
25 | var cur = e.target.dataset.current;
26 | if (this.data.currentTaB == cur) { return false; }
27 | else {
28 | this.setData({
29 | currentTab: cur
30 | })
31 | }
32 | },
33 |
34 | getRankList: function (ids) {
35 | for (let i = 0; i < ids.length; i++) {
36 | if (i == 0 && ids[i] !== 'undefined') {
37 | wx.request({
38 | url: api.rank.rankInfo(ids[i]),
39 | success: res => {
40 | wx.setNavigationBarTitle({
41 | title: res.data.ranking.title,
42 | });
43 | this.setData({
44 | weekRank: res.data.ranking.books
45 | });
46 | wx.hideLoading();
47 | }
48 | })
49 | }
50 | if (i == 1 && ids[i] !== 'undefined') {
51 | wx.request({
52 | url: api.rank.rankInfo(ids[i]),
53 | success: res => {
54 | this.setData({
55 | monthRank: res.data.ranking.books
56 | });
57 | }
58 | })
59 | }
60 | if (i == 2 && ids[i] !== 'undefined') {
61 | wx.request({
62 | url: api.rank.rankInfo(ids[i]),
63 | success: res => {
64 | this.setData({
65 | totalRank: res.data.ranking.books
66 | });
67 | }
68 | })
69 | }
70 | }
71 | },
72 |
73 | /**
74 | * 生命周期函数--监听页面加载
75 | */
76 | onLoad: function (options) {
77 | this.setData({
78 | STATIC_HOST: api.STATIC_HOST
79 | });
80 | wx.showLoading({
81 | title: '加载中',
82 | mask: true
83 | })
84 | let ids = options.id.split('|');
85 | this.getRankList(ids);
86 | // 高度自适应
87 | wx.getSystemInfo({
88 | success: (res) => {
89 | var clientHeight = res.windowHeight,
90 | clientWidth = res.windowWidth,
91 | rpxR = 750 / clientWidth;
92 | var calc = clientHeight * rpxR;
93 | this.setData({
94 | winHeight: calc
95 | });
96 | }
97 | });
98 | },
99 |
100 | /**
101 | * 生命周期函数--监听页面初次渲染完成
102 | */
103 | onReady: function () {
104 |
105 | },
106 |
107 | /**
108 | * 生命周期函数--监听页面显示
109 | */
110 | onShow: function () {
111 |
112 | },
113 |
114 | /**
115 | * 生命周期函数--监听页面隐藏
116 | */
117 | onHide: function () {
118 |
119 | },
120 |
121 | /**
122 | * 生命周期函数--监听页面卸载
123 | */
124 | onUnload: function () {
125 |
126 | },
127 |
128 | /**
129 | * 页面相关事件处理函数--监听用户下拉动作
130 | */
131 | onPullDownRefresh: function () {
132 |
133 | },
134 |
135 | /**
136 | * 页面上拉触底事件的处理函数
137 | */
138 | onReachBottom: function () {
139 |
140 | },
141 |
142 | /**
143 | * 用户点击右上角分享
144 | */
145 | onShareAppMessage: function () {
146 |
147 | }
148 | })
--------------------------------------------------------------------------------
/pages/rank/rank.json:
--------------------------------------------------------------------------------
1 | {
2 | "navigationBarTitleText": "书城"
3 | }
--------------------------------------------------------------------------------
/pages/rank/rank.wxml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | 周榜
6 | 月榜
7 | 总榜
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 | {{book.title}}
16 | {{book.author}}
17 | {{book.shortIntro}}
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 | {{book.title}}
30 | {{book.author}}
31 | {{book.shortIntro}}
32 |
33 |
34 |
35 |
36 |
--------------------------------------------------------------------------------
/pages/rank/rank.wxss:
--------------------------------------------------------------------------------
1 | /* pages/rank/rank.wxss */
2 |
3 | .tab-h {
4 | height: 80rpx;
5 | width: 100%;
6 | box-sizing: border-box;
7 | overflow: hidden;
8 | line-height: 80rpx;
9 | background: #f7f7f7;
10 | font-size: 16px;
11 | white-space: nowrap;
12 | position: fixed;
13 | top: 0;
14 | left: 0;
15 | z-index: 99;
16 | }
17 |
18 | .tab-item {
19 | display: inline-block;
20 | width: 33.3%;
21 | text-align: center;
22 | }
23 |
24 | .tab-item.active {
25 | color: #ec304c;
26 | position: relative;
27 | }
28 |
29 | .tab-item.active:after {
30 | content: "";
31 | display: block;
32 | height: 4rpx;
33 | width: 52rpx;
34 | background: #ec304c;
35 | position: absolute;
36 | bottom: 0;
37 | left: 98rpx;
38 | border-radius: 16rpx;
39 | }
40 |
41 | .tab-content {
42 | margin-top: 80rpx;
43 | }
44 |
45 | .scroll-h {
46 | height: 100%;
47 | width: 92%;
48 | margin: 0 4%;
49 | }
50 |
51 | .book_item {
52 | border-bottom: 1px #eee solid;
53 | position: relative;
54 | height: 335rpx;
55 | }
56 |
57 | .book_item image {
58 | width: 190rpx;
59 | height: 275rpx;
60 | position: absolute;
61 | left: 0;
62 | top: 30rpx;
63 | }
64 |
65 | .book_info {
66 | position: absolute;
67 | right: 0;
68 | top: 30rpx;
69 | width: 475rpx;
70 | }
71 |
72 | .book_title {
73 | color: #333;
74 | font-size: 15px;
75 | font-weight: bold;
76 | display: block;
77 | margin-bottom: 10rpx;
78 | }
79 |
80 | .book_site, .book_desc {
81 | color: #999;
82 | font-size: 12px;
83 | line-height: 40rpx;
84 | display: block;
85 | margin-bottom: 10rpx;
86 | }
87 |
88 | .book_desc {
89 | overflow: hidden;
90 | text-overflow: ellipsis;
91 | display: -webkit-box;
92 | -webkit-line-clamp: 3;
93 | -webkit-box-orient: vertical;
94 | }
95 |
--------------------------------------------------------------------------------
/pages/reader/reader.js:
--------------------------------------------------------------------------------
1 | // pages/reader/reader.js
2 | const api = require('../../utils/api.js')
3 | const WxParse = require('../wxParse/wxParse.js');
4 | Page({
5 | /**
6 | * 页面的初始数据
7 | */
8 | data: {
9 | showPage: false,//请求到数据显示界面
10 | clientWidth: "",
11 | clientHeight: "",
12 | winHeight: "",//窗口高度
13 | book_id: '',
14 | scrollTop: 0,
15 | bookSources: [],
16 | bookChapters: {},
17 | indexPage: 0, //当前章节
18 | indexChapterContent: {}, //当前阅读的内容
19 | readerCss: {
20 | titleSize: 20,
21 | contentSize: 16,
22 | color: '#333', //夜间 #424952
23 | lineHeight: 60,
24 | backgroundColor: '#fff' //#C7EDCC 护眼色 #080C10 黑夜
25 | },
26 | showMenu: false,
27 | showChapter: false,
28 | isDark: false,
29 | isHuyan: false
30 | },
31 |
32 | toggleDark: function () {
33 | this.setData({
34 | isDark: !this.data.isDark
35 | });
36 | if (this.data.isDark) {
37 | wx.setNavigationBarColor({
38 | frontColor: '#ffffff',
39 | backgroundColor: '#080C10'
40 | });
41 | this.data.readerCss.color = '#696969';
42 | this.data.readerCss.backgroundColor = '#080C10';
43 | this.setData({
44 | isHuyan: false,
45 | readerCss: this.data.readerCss
46 | });
47 | } else {
48 | wx.setNavigationBarColor({
49 | frontColor: '#ffffff',
50 | backgroundColor: '#cb1c36'
51 | });
52 | this.data.readerCss.color = '#333';
53 | this.data.readerCss.backgroundColor = '#fff';
54 | this.setData({
55 | isHuyan: false,
56 | readerCss: this.data.readerCss
57 | });
58 | }
59 | },
60 |
61 | toggleHuyan: function () {
62 | this.setData({
63 | isHuyan: !this.data.isHuyan
64 | });
65 | if (this.data.isHuyan) {
66 | wx.setNavigationBarColor({
67 | frontColor: '#ffffff',
68 | backgroundColor: '#000000'
69 | });
70 | this.data.readerCss.color = '#333';
71 | this.data.readerCss.backgroundColor = '#C7EDCC';
72 | this.setData({
73 | isDark: false,
74 | readerCss: this.data.readerCss
75 | });
76 | } else {
77 | wx.setNavigationBarColor({
78 | frontColor: '#ffffff',
79 | backgroundColor: '#cb1c36'
80 | });
81 | this.data.readerCss.color = '#333';
82 | this.data.readerCss.backgroundColor = '#fff';
83 | this.setData({
84 | isDark: false,
85 | readerCss: this.data.readerCss
86 | });
87 | }
88 | },
89 |
90 | incSize: function () {
91 | if (this.data.readerCss.titleSize === 30) {
92 | return
93 | }
94 | this.data.readerCss.titleSize = this.data.readerCss.titleSize + 5;
95 | this.data.readerCss.lineHeight = this.data.readerCss.lineHeight + 10;
96 | this.data.readerCss.contentSize = this.data.readerCss.contentSize + 5;
97 | this.setData({
98 | readerCss: this.data.readerCss
99 | });
100 | },
101 |
102 | decSize: function () {
103 | if (this.data.readerCss.titleSize === 20) {
104 | return
105 | }
106 | this.data.readerCss.titleSize = this.data.readerCss.titleSize - 5;
107 | this.data.readerCss.contentSize = this.data.readerCss.contentSize - 5;
108 | this.data.readerCss.lineHeight = this.data.readerCss.lineHeight - 10;
109 | this.setData({
110 | readerCss: this.data.readerCss
111 | });
112 | },
113 |
114 | getBookSources: function (book_id) {
115 | wx.request({
116 | url: api.book.bookSources(book_id),
117 | success: res => {
118 | this.setData({
119 | bookSources: res.data
120 | });
121 | this.getBookChapters(this.data.bookSources[1] ? this.data.bookSources[1]._id : this.data.bookSources[0]._id);
122 | }
123 | })
124 | },
125 |
126 | getBookChapters: function (source_id) {
127 | wx.request({
128 | url: api.book.bookChapters(source_id),
129 | success: res => {
130 | this.setData({
131 | bookChapters: res.data
132 | });
133 | this.getChapterContent(this.data.bookChapters.chapters[this.data.indexPage].link);
134 | }
135 | })
136 | },
137 |
138 | getChapterContent: function (link) {
139 | wx.showLoading({
140 | title: '加载中',
141 | mask: true
142 | })
143 | wx.request({
144 | url: api.book.chapterContent(link),
145 | success: res => {
146 | wx.hideLoading();
147 | if (res.data.chapter.cpContent) {
148 | let bodyArray = res.data.chapter.cpContent.split(/\n/).map((item) => { //给每个段落加开头空格 ,方案改为修改wxParse.wxss
149 | return item
150 | });
151 | res.data.chapter.cpContent = bodyArray.join('
');
152 | }
153 | let bodyArray = res.data.chapter.body.split(/\n/).map((item) => {
154 | return item
155 | });
156 | res.data.chapter.body = bodyArray.join('
');
157 | this.setData({
158 | showPage: true,
159 | showChapter: false, //关闭目录
160 | indexChapterContent: res.data
161 | });
162 | //存储当前读到哪一章
163 | wx.getStorage({
164 | key: 'bookShelfData',
165 | success: res => {
166 | let data = res.data;
167 | for (let i = 0; i < data.length; i++) {
168 | if (this.data.book_id === data[i].bookInfo.id) {
169 | data[i].readNum = this.data.indexPage + 1;
170 | data[i].laterScrollTop = this.data.scrollTop
171 | wx.setStorage({
172 | key: 'bookShelfData',
173 | data: data,
174 | })
175 | }
176 | }
177 | },
178 | });
179 | //使用Wxparse格式化小说内容 对收费的显示文字 后期换接口处理
180 | WxParse.wxParse('article', 'html', this.data.indexChapterContent.chapter.cpContent ? '小轻还没有给主人搬到此书,去看看别的吧' : this.data.indexChapterContent.chapter.body, this);
181 | //等到渲染页面后调节scrollTop
182 | this.setData({
183 | scrollTop: this.data.scrollTop
184 | })
185 | }
186 | })
187 | },
188 |
189 | goPrev: function () {
190 | if (this.data.indexPage === 0) {
191 | wx.showToast({
192 | title: '已到第一章',
193 | icon: 'loading',
194 | mask: true
195 | });
196 | }
197 | this.setData({
198 | indexPage: this.data.indexPage - 1,
199 | scrollTop: 0
200 | });
201 | if (this.data.bookChapters.chapters[this.data.indexPage]) {
202 | this.getChapterContent(this.data.bookChapters.chapters[this.data.indexPage].link);
203 | }
204 | },
205 |
206 | goNext: function () {
207 | if (this.data.indexPage === this.data.bookChapters.chapters.length - 1) { //当前在最后一章
208 | wx.showToast({
209 | title: '已到最新章节',
210 | icon: 'loading',
211 | mask: true
212 | });
213 | return;
214 | }
215 | this.setData({
216 | indexPage: this.data.indexPage + 1,
217 | scrollTop: 0
218 | });
219 | if (this.data.bookChapters.chapters[this.data.indexPage]) {
220 | this.getChapterContent(this.data.bookChapters.chapters[this.data.indexPage].link);
221 | }
222 | },
223 | //点击中央打开菜单
224 | openMenu: function (event) {
225 | let xMid = this.data.clientWidth / 2;
226 | let yMid = this.data.clientHeight / 2;
227 | let x = event.detail.x;
228 | let y = event.detail.y;
229 | if ((x > xMid - 100 && x < xMid + 100) && (y < yMid + 100 && y > yMid - 100)) {
230 | this.setData({
231 | showMenu: !this.data.showMenu
232 | });
233 | }
234 | },
235 |
236 | getScrollTop: function (event) { //设置读取到文章的具体什么位置
237 |
238 | // this.setData({
239 | // scrollTop: event.detail.scrollTop
240 | // });
241 | //存储读到章节的什么位置
242 | wx.getStorage({
243 | key: 'bookShelfData',
244 | success: res => {
245 | let data = res.data;
246 | for (let i = 0; i < data.length; i++) {
247 | if (this.data.book_id === data[i].bookInfo.id) {
248 | data[i].laterScrollTop = event.detail.scrollTop;
249 | wx.setStorage({
250 | key: 'bookShelfData',
251 | data: data,
252 | })
253 | }
254 | }
255 | },
256 | });
257 | },
258 |
259 | showChapter: function () {
260 | this.setData({
261 | showChapter: !this.data.showChapter
262 | });
263 | },
264 |
265 | pickChapter: function (event) {
266 | this.setData({
267 | indexPage: event.target.dataset.indexpage,
268 | scrollTop: 0
269 | });
270 | this.getChapterContent(event.target.dataset.link);
271 | },
272 |
273 | /**
274 | * 生命周期函数--监听页面加载
275 | */
276 | onLoad: function (options) {
277 | this.setData({
278 | book_id: options.book_id
279 | });
280 |
281 | let bookShelfData = wx.getStorageSync('bookShelfData'); //利用缓存实现阅读记录和书架
282 | if (bookShelfData.length !== 0) {
283 | for (let i = 0; i < bookShelfData.length; i++) {
284 | if (bookShelfData[i].bookInfo.id === options.book_id) {
285 | this.setData({ //上次读到哪
286 | indexPage: bookShelfData[i].readNum - 1,
287 | scrollTop: bookShelfData[i].laterScrollTop
288 | });
289 | break;
290 | }
291 | }
292 | }
293 |
294 | wx.setNavigationBarTitle({ //设置标题
295 | title: options.book_title,
296 | });
297 |
298 | wx.getSystemInfo({
299 | success: (res) => {
300 | var clientHeight = res.windowHeight,
301 | clientWidth = res.windowWidth,
302 | rpxR = 750 / clientWidth;
303 | var calc = clientHeight * rpxR;
304 | this.setData({
305 | clientHeight: clientHeight,
306 | clientWidth: clientWidth,
307 | winHeight: calc
308 | });
309 | }
310 | });
311 | wx.getStorage({
312 | key: 'isAlerted',
313 | success: (res) => {
314 | let data = res.data;
315 | if (!data) {
316 | wx.showModal({
317 | title: '提示',
318 | content: '点击呼出菜单',
319 | success: (res) => {
320 | if (res.confirm) {
321 | wx.setStorage({
322 | key: 'isAlerted',
323 | value: true
324 | });
325 | }
326 | }
327 | });
328 | }
329 | }
330 | });
331 |
332 | setTimeout(() => {
333 | wx.hideLoading();
334 | this.getBookSources(options.book_id);
335 | }, 2000);
336 | }
337 | });
338 |
--------------------------------------------------------------------------------
/pages/reader/reader.json:
--------------------------------------------------------------------------------
1 | {
2 | "navigationBarTitleText": "闲暇阅读",
3 | "backgroundTextStyle": "light",
4 | "navigationBarBackgroundColor": "#cb1c36",
5 | "navigationBarTextStyle": "#f2f2f2"
6 | }
--------------------------------------------------------------------------------
/pages/reader/reader.wxml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | {{bookChapters.chapters[indexPage].title}}
8 |
9 |
10 |
11 |
12 |
13 | 上一章
14 | 下一章
15 |
16 |
17 |
24 |
25 |
26 | 目录
27 | 收起
28 |
29 | {{item.title}}
30 |
31 |
--------------------------------------------------------------------------------
/pages/reader/reader.wxss:
--------------------------------------------------------------------------------
1 | /* pages/reader/reader.wxss */
2 | @import "../wxParse/wxParse.wxss";
3 |
4 | ::-webkit-scrollbar {
5 | width: 0;
6 | height: 0;
7 | color: transparent;
8 | }
9 |
10 | .read_container {
11 | margin: 0 30rpx;
12 | width: 92%;
13 | }
14 |
15 | .chapter_title {
16 | font-weight: bold;
17 | border-bottom: 1px #eee solid;
18 | width: 100%;
19 | padding: 20rpx 0;
20 | }
21 |
22 | .chapter_content {
23 | margin-top: 20rpx;
24 | }
25 |
26 | .chapterLink {
27 | display: flex;
28 | flex-direction: row;
29 | justify-content: center;
30 | padding: 30rpx 0 80rpx 0;
31 | }
32 |
33 | .prev, .next {
34 | width: 150rpx;
35 | line-height: 60rpx;
36 | font-size: 15px;
37 | text-align: center;
38 | border: 1px #eee solid;
39 | background: #ec304c;
40 | color: #fff;
41 | }
42 |
43 | .prev {
44 | border-radius: 30rpx 0 0 30rpx;
45 | }
46 |
47 | .next {
48 | border-radius: 0 30rpx 30rpx 0;
49 | }
50 |
51 | .menu {
52 | position: fixed;
53 | bottom: 0;
54 | width: 100%;
55 | display: flex;
56 | flex-direction: row;
57 | justify-content: space-around;
58 | background: rgba(0, 0, 0, 0.9);
59 | height: 85rpx;
60 | font-size: 15px;
61 | color: #fff;
62 | line-height: 85rpx;
63 | z-index: 10;
64 | }
65 |
66 | .chapterContainer {
67 | width: 100%;
68 | position: fixed;
69 | top: 0;
70 | left: 0;
71 | z-index: 20;
72 | background: #fff;
73 | }
74 |
75 | .chapter_topic {
76 | font-size: 18px;
77 | font-weight: bold;
78 | color: #333;
79 | width: 95%;
80 | margin: 30rpx 30rpx 0 30rpx;
81 | display: flex;
82 | direction: row;
83 | justify-content: space-between;
84 | }
85 |
86 | .chapter_topic_hide {
87 | color: #fff;
88 | width: 11%;
89 | background: #ec304c;
90 | border-radius: 30rpx 0 0 30rpx;
91 | font-size: 13px;
92 | font-weight: normal;
93 | text-align: center;
94 | line-height: 50rpx;
95 | }
96 |
97 | .chapter_item {
98 | font-size: 14px;
99 | color: #666;
100 | width: 95%;
101 | margin-left: 30rpx;
102 | border-bottom: 1px #eee solid;
103 | line-height: 75rpx;
104 | height: 75rpx;
105 | }
106 |
--------------------------------------------------------------------------------
/pages/search/search.js:
--------------------------------------------------------------------------------
1 | // pages/search/search.js
2 | const api = require('../../utils/api.js')
3 | Page({
4 |
5 | /**
6 | * 页面的初始数据
7 | */
8 | data: {
9 | winHeight: "",//窗口高度
10 | STATIC_HOST: '',
11 | scrollTop: 0,
12 | hotWords: [],
13 | showHotWords: [], //随机显示六个热词
14 | hotWordBackgoundColor: ['#FFC0CB', '#7B68EE', '#FF69B4', '#66CDAA', '#FA8072', '#228B22'],
15 | showSearchContent: false,
16 | searchValue: '',
17 | searchRes: {},
18 | historyWords: []
19 | },
20 |
21 | getHotWords: function () {
22 | wx.request({
23 | url: api.book.hotWord,
24 | success: res => {
25 | this.setData({
26 | hotWords: res.data.hotWords
27 | });
28 | this.randomHotWord();
29 | }
30 | })
31 | },
32 |
33 | randomHotWord: function () {
34 | this.setData({
35 | showHotWords: []
36 | });
37 | let hotWordLen = this.data.hotWords.length;
38 | let randomIndex;
39 | for (let i = 0; i < 6; i++) {
40 | let newRandom = Math.floor(Math.random() * hotWordLen);
41 | if (newRandom === randomIndex) {
42 | i--;
43 | break;
44 | }
45 | randomIndex = newRandom;
46 | this.data.showHotWords.push(this.data.hotWords[randomIndex])
47 | }
48 | this.setData({
49 | showHotWords: this.data.showHotWords
50 | });
51 | },
52 |
53 | hotWordSearch: function (event) { //点击热词搜索
54 | this.setData({
55 | searchValue: event.target.dataset.word
56 | });
57 | this.search(event.target.dataset.word);
58 | },
59 |
60 | searchInput: function (event) { //手动清空搜索栏关闭搜索容器
61 | this.setData({
62 | searchValue: event.detail.value
63 | });
64 | if (event.detail.value.length === 0) {
65 | this.setData({
66 | showSearchContent: false
67 | });
68 | }
69 | },
70 |
71 | clearInput: function () { //清空搜索栏关闭搜索容器
72 | this.setData({
73 | searchValue: '',
74 | showSearchContent: false
75 | });
76 | },
77 |
78 | search: function (word) {
79 | wx.showLoading({
80 | title: '搜索中',
81 | mask: true
82 | });
83 | let indexWord = word.detail ? word.detail.value : word;
84 | wx.getStorage({
85 | key: 'searchHistory',
86 | success: res => {
87 | for (let i = 0; i < res.data.length; i++) { //已有记录删除重复的
88 | if (word === res.data[i]) {
89 | res.data.splice(i,1);
90 | break;
91 | }
92 | }
93 | res.data.unshift(indexWord);
94 | wx.setStorage({
95 | key: 'searchHistory',
96 | data: res.data,
97 | });
98 | this.setData({
99 | historyWords: res.data
100 | });
101 | }
102 | })
103 | wx.request({
104 | url: api.book.bookSearch(indexWord),
105 | success: res => {
106 | this.setData({
107 | showSearchContent: true,
108 | searchRes: res.data,
109 | scrollTop: 0
110 | });
111 | wx.hideLoading();
112 | }
113 | })
114 | },
115 |
116 | clearHistory: function () {
117 | wx.setStorage({
118 | key: 'searchHistory',
119 | data: []
120 | });
121 | this.setData({
122 | historyWords: []
123 | });
124 | },
125 |
126 | /**
127 | * 生命周期函数--监听页面加载
128 | */
129 | onLoad: function (options) {
130 | // 高度自适应
131 | wx.getSystemInfo({
132 | success: (res) => {
133 | var clientHeight = res.windowHeight,
134 | clientWidth = res.windowWidth,
135 | rpxR = 750 / clientWidth;
136 | var calc = clientHeight * rpxR - 140;
137 | this.setData({
138 | STATIC_HOST: api.STATIC_HOST,
139 | winHeight: calc
140 | });
141 | }
142 | });
143 |
144 | wx.getStorage({
145 | key: 'searchHistory',
146 | success: res => {
147 | this.setData({
148 | historyWords: res.data
149 | });
150 | },
151 | fail: () => {
152 | wx.setStorage({
153 | key: 'searchHistory',
154 | data: [],
155 | })
156 | }
157 | })
158 |
159 | this.getHotWords();
160 | }
161 | })
--------------------------------------------------------------------------------
/pages/search/search.json:
--------------------------------------------------------------------------------
1 | {
2 | "navigationBarTitleText": "搜索",
3 | "backgroundTextStyle": "light",
4 | "navigationBarBackgroundColor": "#cb1c36",
5 | "navigationBarTextStyle": "#f2f2f2"
6 | }
--------------------------------------------------------------------------------
/pages/search/search.wxml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 | 大家都在搜
10 | 换一换
11 |
12 |
13 | {{item}}
14 |
15 |
16 |
17 |
18 | 搜索历史
19 | 清空
20 |
21 |
22 | {{item}}
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 | {{book.title}}
32 | {{book.author}}
33 | {{book.shortIntro}}
34 | 最近收藏: {{book.latelyFollower}}
35 |
36 |
37 |
38 |
--------------------------------------------------------------------------------
/pages/search/search.wxss:
--------------------------------------------------------------------------------
1 | /* pages/search/search.wxss */
2 |
3 | .searchContainer {
4 | padding-top: 30rpx;
5 | position: relative;
6 | }
7 |
8 | .searchIcon {
9 | position: absolute;
10 | top: 50rpx;
11 | left: 195rpx;
12 | z-index: 20;
13 | }
14 |
15 | .clearIcon {
16 | position: absolute;
17 | top: 45rpx;
18 | right: 45rpx;
19 | z-index: 20;
20 | }
21 |
22 | .searchContainer input {
23 | background: #efefef;
24 | text-align: center;
25 | color: #333;
26 | font-size: 15px;
27 | height: 70rpx;
28 | line-height: 70rpx;
29 | outline: none;
30 | border-radius: 25rpx;
31 | width: 92%;
32 | margin: 0 auto;
33 | }
34 |
35 | .placerStyle {
36 | color: #999;
37 | font: 14px;
38 | }
39 |
40 | .hotWord, .historyWord {
41 | width: 92%;
42 | margin: 30rpx 30rpx 12rpx 30rpx;
43 | }
44 |
45 | .hot_topic, .history_topic {
46 | display: flex;
47 | justify-content: space-between;
48 | flex-direction: row;
49 | margin-bottom: 20rpx;
50 | }
51 |
52 | .hot_title, .hot_refresh, .history_title, .history_clear {
53 | font-size: 15px;
54 | }
55 |
56 | .hot_title, .history_title {
57 | width: 50%;
58 | color: #333;
59 | }
60 |
61 | .hot_refresh, .history_clear {
62 | width: 20%;
63 | color: #ff6347;
64 | text-align: right;
65 | }
66 |
67 | .history_clear {
68 | text-align: center;
69 | text-indent: 10px;
70 | }
71 |
72 | .hot_refresh {
73 | background: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAEAAAABACAYAAACqaXHeAAAFVklEQVR4Xu1aTXraSBB9JWYmyzgniHOC2CcwLAzZxT5BMMw+9glCThB7PwJ8guBdwIuQEwxzgtgnGNgNjKXK192S3EII1PoB/6Dv8wKrVd3v9euqruomPPOHnjl+bAnYKuCZM7BdAs9cAFsnuF0C2yWwRga4frgHsl6DeE92S9gDaAfMQ/mbaQR2b6l7PVrXsApfAnxSew/CEYAyCLuJgDGPAerBokv665sip6CnMAK4Wf0AplY8aJ6AoWaa6CAWH+MGxC2yB5dFcJA7AdysHoHpSxg4TwD0pNTd/3vUHY4XgeH6u11YThlkCcW8D7fhEcg6y1sRuRLAjVoHhLo28Fuw26L2ddd09rhe3oH1+xHIagF4HXzP3KL24LOpvbj2uRAgZ67kfgVIOTcgNfD5gSoi/jgF4RSgl977IZzpcZySTMjJh4Bm7RzAR6/jKzjTeh6D04F4RAxB9Fb9n0dwZpWs/eRCgBxOs9oF44baAyHZQh5JQumFWE6ef+AR2YP9LJ3lRkCWQZh+K8kGfVBCQJfa/RNTG377R0mAUlytFyiBcUbtvliGxs/jJUA5R+UTxMbJnb1J4w8eLQFSBX++K4P5u+cUL8ke6CE4kRoeNQGB8/X9gUNvqPvtJhFyr5ERAR7jb8nuX5h0UmRbtQfhn2lVkJiAkNwyet68CQmiAvOY2oNXJvYTESDTWIu+g2hHM35Bdv/UpLOi2sr8A/TVU8Ex2QMRIRI9KwmIAe/15Z6k2ecnGplhI25WRQottspGE7OUgDB4kdEFe/H74fHDIIEbVRESD8D8g9qDclL+YgmIgHe4jJL1tzTMLLKxo/sYzJV1VnEWgeNGtQWiT+Id2f2VyvZtLGy4EPxvJVG6UjGXqII7Z4wSDaUq5EZksyRwoyYyxi+ZCVgEXsxuKAp48Va29VWRU3a2SrrcrMmscz4ULxqfbotPDg+oc/1j3n5EAdyo/byv5nDgUfUOdIlx47AOsjqe4SHZ/coqEGnfhwhn/qxnniECiCp65Ugr1EQcZJQAmdtzHcynuodfJjEO6gE8IXugh8q0WGO/40Z1FNQENAccp4BQlWqONKmkpCMMdzB9NZ94yPd3uDHdiibt328XKYw47r5cotpewFdouETHC3OFdATMScwURNb2ainoDtjah+XW9SiQBLyZAvQ99wOI/SEShANmTPx9AEDCj/mZ4RXZfVFlXvgkVoAM/yl3W1lnPO77OQccbcb8D9xZeVmdwJAAvwqTvRaXFymxJCQAb7QEpAL0kJci984L9LydUI1QDnT1zPs2zBSgqrL/yo8XhJSiACaxq6XEK2Wv2zMiQPkBbxlkqMMlAZSmjQjFpkdn5gTodbgHpoI0pBkToHyBl3qKH95GJE3nD+GbdASos8CRqg/kc0S1KTJSEeCpIMi/s57ObAq8cRhcGn7WVCgVuUCaA5A4klMrQKpAP51RPeR2bL1owN72tyPuEmU5D8wUBiMqiJAgfIJ1nHdWqG6eoBNUpnPKRzIpwCcjemytTm3hTs+yylVdm+FPoZsnGQ5D5ycwFwICIrS6nLdbFHeBzuHylWnRVJXmrI/hKzc8gcNlU1vLnGyuBCi/IGbM7UZufonbXuAeWOTx7hhcuvWXibo/iJewaBdMZYBFxVmrLMkbZedwZ+dZFVWoAnTjXgVJnBzN3fYyDnoXcKatvIH7o8hdAVEnKdfwkTer8fcB7z+8BeTN0R6c2bAo4GsjIErI4R7EGYPr7AIk/sawSF2YvPtvVDTgtS0BY6Fv6IPCl8CGcCXudktAYqqeaMOtAp7oxCaGtVVAYqqeaMOtAp7oxCaG9QvrvMZfXd+MCQAAAABJRU5ErkJggg==") no-repeat left center;
74 | background-size: 45rpx 45rpx;
75 | }
76 |
77 | .history_clear {
78 | background: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAEAAAABACAYAAACqaXHeAAADqUlEQVR4Xu2bzXHaUBCAd0VmcgwdxKkguILgg8G3pAMrkAJwBXYqsAuICKkgzs3gQ0gFhgpCOjDHTII2I+GZgJHf210JLQz4yur9fFppP733jLDjf7jj84c9gLIygMJ6FSrPT4Go6uwTYYzR4LqscZWWAdRufAXAd6yJIR7hp5shKzZnUCkAKDw5gAr9FIx1iFH/SBCvDi0HQKtxAYjnolHO8BX2biaiaxTB5QBoN+4AsCYaH8EZdvtXomsUwV4A9OGkDhRfiiegGEyhlxD0IP59hr3hvatdJwAKj2tQCe4KHVipjdEIo8GhHkC7mZSjt6WOuejOPBXFnQGtxhAQ3xQ9plLbI/qI3cHFU33uAbjuRvoOeFZxm1upt1PR2V+YuMqptwooutyqS/YAOLcrVVmcveTEbkwM/Rn7HCAZKysDSKOy1iSYKs0EcBwCBp+t5yTpH6M+a26soLkO03fJAIxjf2HUP+CMgQdA/jnL6Xt9MUQ/sDuoczpgAUgaonaTOA1uRgx9wWgQcsYiAZB8m29HJfDo7yIYPgDudwHRGAAWP0GrgPh66W6sxgAgJs/sAmCaAsFo6TqEGgC+8N5Zit9j97bnjeOWwfkj0OgB4Km30UdfX5kv0IwvtJVSm/EcE/cmCNYUJRnAW9baBABMB2CLUJoBrWYHEC63IQO4DiADwHUB+wxgO4AMAHd5zBqAwAFEANguYA0A4BtGfd4GjKQKPFSCe28ZsgYgcAB5BnDKkDkA2X4Cuww+PAL+VWJrAAIH0GSA3wWsAcziQ+zdLhuko3bLMoDjAsYAJA4gzwCOC5gCoClGA9EqtiwDOC5gCUDoAOIMYLmAJQChAygBNNwuYAlA6AA6AD4XMAUgcwAdAN+OsSUAoQPoAPj2CCwBCB1ACcCzLmAIQOoAOgA+FzADIHcAHQCfC1gBUDiACoDXBawAKBwgBwCHC1gBUDiAHoDLBcwAyB1AD8DlAlYAFA6gB+ByASsACgfIAcDhAkYANA6gB+ByARMAOgdYDwCADsTx/yWpIEgOST8+9Lwck44kCAFhYUubRhBTZ2k1K8CrzDPLSgdQA/C6gGMNbi0/2QDwrAusZaZPNKp0gJwZwNwuLwOEsgLkA7Ap54ZypH8uAOl7oGV9fI6mMAtqef61RrQqnJXNcwjp29l/dKXIxyE5ZhNTKNkEyeo+N4A0E+aPQweIaqtnfQqcdTJpxAlQfM09A+TrvRAAvk42+fc9gE2+O2WMbecz4B8h9ZluKgkn/QAAAABJRU5ErkJggg==") no-repeat left center;
79 | background-size: 45rpx 45rpx;
80 | }
81 |
82 | .hotWordContent {
83 | display: flex;
84 | flex-direction: row;
85 | flex-wrap: wrap;
86 | }
87 |
88 | .hotWord_item {
89 | font-size: 13px;
90 | padding: 10rpx 18rpx;
91 | text-align: center;
92 | margin: 0 18rpx 18rpx 0;
93 | color: #fff;
94 | }
95 |
96 | .historyWord_item {
97 | font-size: 13px;
98 | color: #333;
99 | height: 70rpx;
100 | line-height: 70rpx;
101 | border-bottom: 1px #f7f7f7 solid;
102 | }
103 |
104 | .bookList {
105 | background: #fff;
106 | position: relative;
107 | padding: 0 30rpx;
108 | width: 92%;
109 | top: 40rpx;
110 | }
111 |
112 | .book_item {
113 | border-bottom: 1px #eee solid;
114 | position: relative;
115 | height: 335rpx;
116 | }
117 |
118 | .book_item image {
119 | width: 190rpx;
120 | height: 275rpx;
121 | position: absolute;
122 | left: 0;
123 | top: 30rpx;
124 | }
125 |
126 | .book_info {
127 | position: absolute;
128 | right: 0;
129 | top: 30rpx;
130 | width: 475rpx;
131 | }
132 |
133 | .book_title {
134 | color: #333;
135 | font-size: 15px;
136 | font-weight: bold;
137 | display: block;
138 | margin-bottom: 10rpx;
139 | }
140 |
141 | .book_site,.book_desc {
142 | color: #999;
143 | font-size: 12px;
144 | line-height: 40rpx;
145 | display: block;
146 | margin-bottom: 10rpx;
147 | }
148 |
149 | .book_desc {
150 | overflow : hidden;
151 | text-overflow: ellipsis;
152 | display: -webkit-box;
153 | -webkit-line-clamp: 3;
154 | -webkit-box-orient: vertical;
155 | }
156 |
157 | .book_follower {
158 | font-size: 12px;
159 | line-height: 40rpx;
160 | color: #ff6347;
161 | }
162 |
--------------------------------------------------------------------------------
/pages/wxParse/html2json.js:
--------------------------------------------------------------------------------
1 | /**
2 | * html2Json 改造来自: https://github.com/Jxck/html2json
3 | *
4 | *
5 | * author: Di (微信小程序开发工程师)
6 | * organization: WeAppDev(微信小程序开发论坛)(http://weappdev.com)
7 | * 垂直微信小程序开发交流社区
8 | *
9 | * github地址: https://github.com/icindy/wxParse
10 | *
11 | * for: 微信小程序富文本解析
12 | * detail : http://weappdev.com/t/wxparse-alpha0-1-html-markdown/184
13 | */
14 |
15 | var __placeImgeUrlHttps = "https";
16 | var __emojisReg = '';
17 | var __emojisBaseSrc = '';
18 | var __emojis = {};
19 | var wxDiscode = require('./wxDiscode.js');
20 | var HTMLParser = require('./htmlparser.js');
21 | // Empty Elements - HTML 5
22 | var empty = makeMap("area,base,basefont,br,col,frame,hr,img,input,link,meta,param,embed,command,keygen,source,track,wbr");
23 | // Block Elements - HTML 5
24 | var block = makeMap("br,a,code,address,article,applet,aside,audio,blockquote,button,canvas,center,dd,del,dir,div,dl,dt,fieldset,figcaption,figure,footer,form,frameset,h1,h2,h3,h4,h5,h6,header,hgroup,hr,iframe,ins,isindex,li,map,menu,noframes,noscript,object,ol,output,p,pre,section,script,table,tbody,td,tfoot,th,thead,tr,ul,video");
25 |
26 | // Inline Elements - HTML 5
27 | var inline = makeMap("abbr,acronym,applet,b,basefont,bdo,big,button,cite,del,dfn,em,font,i,iframe,img,input,ins,kbd,label,map,object,q,s,samp,script,select,small,span,strike,strong,sub,sup,textarea,tt,u,var");
28 |
29 | // Elements that you can, intentionally, leave open
30 | // (and which close themselves)
31 | var closeSelf = makeMap("colgroup,dd,dt,li,options,p,td,tfoot,th,thead,tr");
32 |
33 | // Attributes that have their values filled in disabled="disabled"
34 | var fillAttrs = makeMap("checked,compact,declare,defer,disabled,ismap,multiple,nohref,noresize,noshade,nowrap,readonly,selected");
35 |
36 | // Special Elements (can contain anything)
37 | var special = makeMap("wxxxcode-style,script,style,view,scroll-view,block");
38 | function makeMap(str) {
39 | var obj = {}, items = str.split(",");
40 | for (var i = 0; i < items.length; i++)
41 | obj[items[i]] = true;
42 | return obj;
43 | }
44 |
45 | function q(v) {
46 | return '"' + v + '"';
47 | }
48 |
49 | function removeDOCTYPE(html) {
50 | return html
51 | .replace(/<\?xml.*\?>\n/, '')
52 | .replace(/<.*!doctype.*\>\n/, '')
53 | .replace(/<.*!DOCTYPE.*\>\n/, '');
54 | }
55 |
56 | function trimHtml(html) {
57 | return html
58 | .replace(/\r?\n+/g, '')
59 | .replace(//ig, '')
60 | .replace(/\/\*.*?\*\//ig, '')
61 | .replace(/[ ]+
189 | // add to parents
190 | var parent = bufArray[0] || results;
191 | if (parent.nodes === undefined) {
192 | parent.nodes = [];
193 | }
194 | parent.nodes.push(node);
195 | } else {
196 | bufArray.unshift(node);
197 | }
198 | },
199 | end: function (tag) {
200 | //debug(tag);
201 | // merge into parent tag
202 | var node = bufArray.shift();
203 | if (node.tag !== tag) console.error('invalid state: mismatch end tag');
204 |
205 | //当有缓存source资源时于于video补上src资源
206 | if(node.tag === 'video' && results.source){
207 | node.attr.src = results.source;
208 | delete results.source;
209 | }
210 |
211 | if (bufArray.length === 0) {
212 | results.nodes.push(node);
213 | } else {
214 | var parent = bufArray[0];
215 | if (parent.nodes === undefined) {
216 | parent.nodes = [];
217 | }
218 | parent.nodes.push(node);
219 | }
220 | },
221 | chars: function (text) {
222 | //debug(text);
223 | var node = {
224 | node: 'text',
225 | text: text,
226 | textArray:transEmojiStr(text)
227 | };
228 |
229 | if (bufArray.length === 0) {
230 | node.index = index.toString()
231 | index += 1
232 | results.nodes.push(node);
233 | } else {
234 | var parent = bufArray[0];
235 | if (parent.nodes === undefined) {
236 | parent.nodes = [];
237 | }
238 | node.index = parent.index + '.' + parent.nodes.length
239 | parent.nodes.push(node);
240 | }
241 | },
242 | comment: function (text) {
243 | //debug(text);
244 | // var node = {
245 | // node: 'comment',
246 | // text: text,
247 | // };
248 | // var parent = bufArray[0];
249 | // if (parent.nodes === undefined) {
250 | // parent.nodes = [];
251 | // }
252 | // parent.nodes.push(node);
253 | },
254 | });
255 | return results;
256 | };
257 |
258 | function transEmojiStr(str){
259 | // var eReg = new RegExp("["+__reg+' '+"]");
260 | // str = str.replace(/\[([^\[\]]+)\]/g,':$1:')
261 |
262 | var emojiObjs = [];
263 | //如果正则表达式为空
264 | if(__emojisReg.length == 0 || !__emojis){
265 | var emojiObj = {}
266 | emojiObj.node = "text";
267 | emojiObj.text = str;
268 | array = [emojiObj];
269 | return array;
270 | }
271 | //这个地方需要调整
272 | str = str.replace(/\[([^\[\]]+)\]/g,':$1:')
273 | var eReg = new RegExp("[:]");
274 | var array = str.split(eReg);
275 | for(var i = 0; i < array.length; i++){
276 | var ele = array[i];
277 | var emojiObj = {};
278 | if(__emojis[ele]){
279 | emojiObj.node = "element";
280 | emojiObj.tag = "emoji";
281 | emojiObj.text = __emojis[ele];
282 | emojiObj.baseSrc= __emojisBaseSrc;
283 | }else{
284 | emojiObj.node = "text";
285 | emojiObj.text = ele;
286 | }
287 | emojiObjs.push(emojiObj);
288 | }
289 |
290 | return emojiObjs;
291 | }
292 |
293 | function emojisInit(reg='',baseSrc="/wxParse/emojis/",emojis){
294 | __emojisReg = reg;
295 | __emojisBaseSrc=baseSrc;
296 | __emojis=emojis;
297 | }
298 |
299 | module.exports = {
300 | html2json: html2json,
301 | emojisInit:emojisInit
302 | };
303 |
304 |
--------------------------------------------------------------------------------
/pages/wxParse/htmlparser.js:
--------------------------------------------------------------------------------
1 | /**
2 | *
3 | * htmlParser改造自: https://github.com/blowsie/Pure-JavaScript-HTML5-Parser
4 | *
5 | * author: Di (微信小程序开发工程师)
6 | * organization: WeAppDev(微信小程序开发论坛)(http://weappdev.com)
7 | * 垂直微信小程序开发交流社区
8 | *
9 | * github地址: https://github.com/icindy/wxParse
10 | *
11 | * for: 微信小程序富文本解析
12 | * detail : http://weappdev.com/t/wxparse-alpha0-1-html-markdown/184
13 | */
14 | // Regular Expressions for parsing tags and attributes
15 | var startTag = /^<([-A-Za-z0-9_]+)((?:\s+[a-zA-Z_:][-a-zA-Z0-9_:.]*(?:\s*=\s*(?:(?:"[^"]*")|(?:'[^']*')|[^>\s]+))?)*)\s*(\/?)>/,
16 | endTag = /^<\/([-A-Za-z0-9_]+)[^>]*>/,
17 | attr = /([a-zA-Z_:][-a-zA-Z0-9_:.]*)(?:\s*=\s*(?:(?:"((?:\\.|[^"])*)")|(?:'((?:\\.|[^'])*)')|([^>\s]+)))?/g;
18 |
19 | // Empty Elements - HTML 5
20 | var empty = makeMap("area,base,basefont,br,col,frame,hr,img,input,link,meta,param,embed,command,keygen,source,track,wbr");
21 |
22 | // Block Elements - HTML 5
23 | var block = makeMap("a,address,code,article,applet,aside,audio,blockquote,button,canvas,center,dd,del,dir,div,dl,dt,fieldset,figcaption,figure,footer,form,frameset,h1,h2,h3,h4,h5,h6,header,hgroup,hr,iframe,ins,isindex,li,map,menu,noframes,noscript,object,ol,output,p,pre,section,script,table,tbody,td,tfoot,th,thead,tr,ul,video");
24 |
25 | // Inline Elements - HTML 5
26 | var inline = makeMap("abbr,acronym,applet,b,basefont,bdo,big,br,button,cite,del,dfn,em,font,i,iframe,img,input,ins,kbd,label,map,object,q,s,samp,script,select,small,span,strike,strong,sub,sup,textarea,tt,u,var");
27 |
28 | // Elements that you can, intentionally, leave open
29 | // (and which close themselves)
30 | var closeSelf = makeMap("colgroup,dd,dt,li,options,p,td,tfoot,th,thead,tr");
31 |
32 | // Attributes that have their values filled in disabled="disabled"
33 | var fillAttrs = makeMap("checked,compact,declare,defer,disabled,ismap,multiple,nohref,noresize,noshade,nowrap,readonly,selected");
34 |
35 | // Special Elements (can contain anything)
36 | var special = makeMap("wxxxcode-style,script,style,view,scroll-view,block");
37 |
38 | function HTMLParser(html, handler) {
39 | var index, chars, match, stack = [], last = html;
40 | stack.last = function () {
41 | return this[this.length - 1];
42 | };
43 |
44 | while (html) {
45 | chars = true;
46 |
47 | // Make sure we're not in a script or style element
48 | if (!stack.last() || !special[stack.last()]) {
49 |
50 | // Comment
51 | if (html.indexOf("");
53 |
54 | if (index >= 0) {
55 | if (handler.comment)
56 | handler.comment(html.substring(4, index));
57 | html = html.substring(index + 3);
58 | chars = false;
59 | }
60 |
61 | // end tag
62 | } else if (html.indexOf("") == 0) {
63 | match = html.match(endTag);
64 |
65 | if (match) {
66 | html = html.substring(match[0].length);
67 | match[0].replace(endTag, parseEndTag);
68 | chars = false;
69 | }
70 |
71 | // start tag
72 | } else if (html.indexOf("<") == 0) {
73 | match = html.match(startTag);
74 |
75 | if (match) {
76 | html = html.substring(match[0].length);
77 | match[0].replace(startTag, parseStartTag);
78 | chars = false;
79 | }
80 | }
81 |
82 | if (chars) {
83 | index = html.indexOf("<");
84 | var text = ''
85 | while (index === 0) {
86 | text += "<";
87 | html = html.substring(1);
88 | index = html.indexOf("<");
89 | }
90 | text += index < 0 ? html : html.substring(0, index);
91 | html = index < 0 ? "" : html.substring(index);
92 |
93 | if (handler.chars)
94 | handler.chars(text);
95 | }
96 |
97 | } else {
98 |
99 | html = html.replace(new RegExp("([\\s\\S]*?)<\/" + stack.last() + "[^>]*>"), function (all, text) {
100 | text = text.replace(/|/g, "$1$2");
101 | if (handler.chars)
102 | handler.chars(text);
103 |
104 | return "";
105 | });
106 |
107 |
108 | parseEndTag("", stack.last());
109 | }
110 |
111 | if (html == last)
112 | throw "Parse Error: " + html;
113 | last = html;
114 | }
115 |
116 | // Clean up any remaining tags
117 | parseEndTag();
118 |
119 | function parseStartTag(tag, tagName, rest, unary) {
120 | tagName = tagName.toLowerCase();
121 |
122 | if (block[tagName]) {
123 | while (stack.last() && inline[stack.last()]) {
124 | parseEndTag("", stack.last());
125 | }
126 | }
127 |
128 | if (closeSelf[tagName] && stack.last() == tagName) {
129 | parseEndTag("", tagName);
130 | }
131 |
132 | unary = empty[tagName] || !!unary;
133 |
134 | if (!unary)
135 | stack.push(tagName);
136 |
137 | if (handler.start) {
138 | var attrs = [];
139 |
140 | rest.replace(attr, function (match, name) {
141 | var value = arguments[2] ? arguments[2] :
142 | arguments[3] ? arguments[3] :
143 | arguments[4] ? arguments[4] :
144 | fillAttrs[name] ? name : "";
145 |
146 | attrs.push({
147 | name: name,
148 | value: value,
149 | escaped: value.replace(/(^|[^\\])"/g, '$1\\\"') //"
150 | });
151 | });
152 |
153 | if (handler.start) {
154 | handler.start(tagName, attrs, unary);
155 | }
156 |
157 | }
158 | }
159 |
160 | function parseEndTag(tag, tagName) {
161 | // If no tag name is provided, clean shop
162 | if (!tagName)
163 | var pos = 0;
164 |
165 | // Find the closest opened tag of the same type
166 | else {
167 | tagName = tagName.toLowerCase();
168 | for (var pos = stack.length - 1; pos >= 0; pos--)
169 | if (stack[pos] == tagName)
170 | break;
171 | }
172 | if (pos >= 0) {
173 | // Close all the open elements, up the stack
174 | for (var i = stack.length - 1; i >= pos; i--)
175 | if (handler.end)
176 | handler.end(stack[i]);
177 |
178 | // Remove the open elements from the stack
179 | stack.length = pos;
180 | }
181 | }
182 | };
183 |
184 |
185 | function makeMap(str) {
186 | var obj = {}, items = str.split(",");
187 | for (var i = 0; i < items.length; i++)
188 | obj[items[i]] = true;
189 | return obj;
190 | }
191 |
192 | module.exports = HTMLParser;
193 |
--------------------------------------------------------------------------------
/pages/wxParse/wxDiscode.js:
--------------------------------------------------------------------------------
1 | // HTML 支持的数学符号
2 | function strNumDiscode(str){
3 | str = str.replace(/∀/g, '∀');
4 | str = str.replace(/∂/g, '∂');
5 | str = str.replace(/&exists;/g, '∃');
6 | str = str.replace(/∅/g, '∅');
7 | str = str.replace(/∇/g, '∇');
8 | str = str.replace(/∈/g, '∈');
9 | str = str.replace(/∉/g, '∉');
10 | str = str.replace(/∋/g, '∋');
11 | str = str.replace(/∏/g, '∏');
12 | str = str.replace(/∑/g, '∑');
13 | str = str.replace(/−/g, '−');
14 | str = str.replace(/∗/g, '∗');
15 | str = str.replace(/√/g, '√');
16 | str = str.replace(/∝/g, '∝');
17 | str = str.replace(/∞/g, '∞');
18 | str = str.replace(/∠/g, '∠');
19 | str = str.replace(/∧/g, '∧');
20 | str = str.replace(/∨/g, '∨');
21 | str = str.replace(/∩/g, '∩');
22 | str = str.replace(/∩/g, '∪');
23 | str = str.replace(/∫/g, '∫');
24 | str = str.replace(/∴/g, '∴');
25 | str = str.replace(/∼/g, '∼');
26 | str = str.replace(/≅/g, '≅');
27 | str = str.replace(/≈/g, '≈');
28 | str = str.replace(/≠/g, '≠');
29 | str = str.replace(/≤/g, '≤');
30 | str = str.replace(/≥/g, '≥');
31 | str = str.replace(/⊂/g, '⊂');
32 | str = str.replace(/⊃/g, '⊃');
33 | str = str.replace(/⊄/g, '⊄');
34 | str = str.replace(/⊆/g, '⊆');
35 | str = str.replace(/⊇/g, '⊇');
36 | str = str.replace(/⊕/g, '⊕');
37 | str = str.replace(/⊗/g, '⊗');
38 | str = str.replace(/⊥/g, '⊥');
39 | str = str.replace(/⋅/g, '⋅');
40 | return str;
41 | }
42 |
43 | //HTML 支持的希腊字母
44 | function strGreeceDiscode(str){
45 | str = str.replace(/Α/g, 'Α');
46 | str = str.replace(/Β/g, 'Β');
47 | str = str.replace(/Γ/g, 'Γ');
48 | str = str.replace(/Δ/g, 'Δ');
49 | str = str.replace(/Ε/g, 'Ε');
50 | str = str.replace(/Ζ/g, 'Ζ');
51 | str = str.replace(/Η/g, 'Η');
52 | str = str.replace(/Θ/g, 'Θ');
53 | str = str.replace(/Ι/g, 'Ι');
54 | str = str.replace(/Κ/g, 'Κ');
55 | str = str.replace(/Λ/g, 'Λ');
56 | str = str.replace(/Μ/g, 'Μ');
57 | str = str.replace(/Ν/g, 'Ν');
58 | str = str.replace(/Ξ/g, 'Ν');
59 | str = str.replace(/Ο/g, 'Ο');
60 | str = str.replace(/Π/g, 'Π');
61 | str = str.replace(/Ρ/g, 'Ρ');
62 | str = str.replace(/Σ/g, 'Σ');
63 | str = str.replace(/Τ/g, 'Τ');
64 | str = str.replace(/Υ/g, 'Υ');
65 | str = str.replace(/Φ/g, 'Φ');
66 | str = str.replace(/Χ/g, 'Χ');
67 | str = str.replace(/Ψ/g, 'Ψ');
68 | str = str.replace(/Ω/g, 'Ω');
69 |
70 | str = str.replace(/α/g, 'α');
71 | str = str.replace(/β/g, 'β');
72 | str = str.replace(/γ/g, 'γ');
73 | str = str.replace(/δ/g, 'δ');
74 | str = str.replace(/ε/g, 'ε');
75 | str = str.replace(/ζ/g, 'ζ');
76 | str = str.replace(/η/g, 'η');
77 | str = str.replace(/θ/g, 'θ');
78 | str = str.replace(/ι/g, 'ι');
79 | str = str.replace(/κ/g, 'κ');
80 | str = str.replace(/λ/g, 'λ');
81 | str = str.replace(/μ/g, 'μ');
82 | str = str.replace(/ν/g, 'ν');
83 | str = str.replace(/ξ/g, 'ξ');
84 | str = str.replace(/ο/g, 'ο');
85 | str = str.replace(/π/g, 'π');
86 | str = str.replace(/ρ/g, 'ρ');
87 | str = str.replace(/ς/g, 'ς');
88 | str = str.replace(/σ/g, 'σ');
89 | str = str.replace(/τ/g, 'τ');
90 | str = str.replace(/υ/g, 'υ');
91 | str = str.replace(/φ/g, 'φ');
92 | str = str.replace(/χ/g, 'χ');
93 | str = str.replace(/ψ/g, 'ψ');
94 | str = str.replace(/ω/g, 'ω');
95 | str = str.replace(/ϑ/g, 'ϑ');
96 | str = str.replace(/ϒ/g, 'ϒ');
97 | str = str.replace(/ϖ/g, 'ϖ');
98 | str = str.replace(/·/g, '·');
99 | return str;
100 | }
101 |
102 | //
103 |
104 | function strcharacterDiscode(str){
105 | // 加入常用解析
106 | str = str.replace(/ /g, ' ');
107 | str = str.replace(/"/g, "'");
108 | str = str.replace(/&/g, '&');
109 | // str = str.replace(/</g, '‹');
110 | // str = str.replace(/>/g, '›');
111 |
112 | str = str.replace(/</g, '<');
113 | str = str.replace(/>/g, '>');
114 | str = str.replace(/•/g, '•');
115 |
116 | return str;
117 | }
118 |
119 | // HTML 支持的其他实体
120 | function strOtherDiscode(str){
121 | str = str.replace(/Œ/g, 'Œ');
122 | str = str.replace(/œ/g, 'œ');
123 | str = str.replace(/Š/g, 'Š');
124 | str = str.replace(/š/g, 'š');
125 | str = str.replace(/Ÿ/g, 'Ÿ');
126 | str = str.replace(/ƒ/g, 'ƒ');
127 | str = str.replace(/ˆ/g, 'ˆ');
128 | str = str.replace(/˜/g, '˜');
129 | str = str.replace(/ /g, '');
130 | str = str.replace(/ /g, '');
131 | str = str.replace(/ /g, '');
132 | str = str.replace(//g, '');
133 | str = str.replace(//g, '');
134 | str = str.replace(//g, '');
135 | str = str.replace(//g, '');
136 | str = str.replace(/–/g, '–');
137 | str = str.replace(/—/g, '—');
138 | str = str.replace(/‘/g, '‘');
139 | str = str.replace(/’/g, '’');
140 | str = str.replace(/‚/g, '‚');
141 | str = str.replace(/“/g, '“');
142 | str = str.replace(/”/g, '”');
143 | str = str.replace(/„/g, '„');
144 | str = str.replace(/†/g, '†');
145 | str = str.replace(/‡/g, '‡');
146 | str = str.replace(/•/g, '•');
147 | str = str.replace(/…/g, '…');
148 | str = str.replace(/‰/g, '‰');
149 | str = str.replace(/′/g, '′');
150 | str = str.replace(/″/g, '″');
151 | str = str.replace(/‹/g, '‹');
152 | str = str.replace(/›/g, '›');
153 | str = str.replace(/‾/g, '‾');
154 | str = str.replace(/€/g, '€');
155 | str = str.replace(/™/g, '™');
156 |
157 | str = str.replace(/←/g, '←');
158 | str = str.replace(/↑/g, '↑');
159 | str = str.replace(/→/g, '→');
160 | str = str.replace(/↓/g, '↓');
161 | str = str.replace(/↔/g, '↔');
162 | str = str.replace(/↵/g, '↵');
163 | str = str.replace(/⌈/g, '⌈');
164 | str = str.replace(/⌉/g, '⌉');
165 |
166 | str = str.replace(/⌊/g, '⌊');
167 | str = str.replace(/⌋/g, '⌋');
168 | str = str.replace(/◊/g, '◊');
169 | str = str.replace(/♠/g, '♠');
170 | str = str.replace(/♣/g, '♣');
171 | str = str.replace(/♥/g, '♥');
172 |
173 | str = str.replace(/♦/g, '♦');
174 | str = str.replace(/'/g, '\'');
175 | return str;
176 | }
177 |
178 | function strMoreDiscode(str){
179 | str = str.replace(/\r\n/g,"");
180 | str = str.replace(/\n/g,"");
181 |
182 | str = str.replace(/code/g,"wxxxcode-style");
183 | return str;
184 | }
185 |
186 | function strDiscode(str){
187 | str = strNumDiscode(str);
188 | str = strGreeceDiscode(str);
189 | str = strcharacterDiscode(str);
190 | str = strOtherDiscode(str);
191 | str = strMoreDiscode(str);
192 | return str;
193 | }
194 | function urlToHttpUrl(url,rep){
195 |
196 | var patt1 = new RegExp("^//");
197 | var result = patt1.test(url);
198 | if(result){
199 | url = rep+":"+url;
200 | }
201 | return url;
202 | }
203 |
204 | module.exports = {
205 | strDiscode:strDiscode,
206 | urlToHttpUrl:urlToHttpUrl
207 | }
--------------------------------------------------------------------------------
/pages/wxParse/wxParse.js:
--------------------------------------------------------------------------------
1 | /**
2 | * author: Di (微信小程序开发工程师)
3 | * organization: WeAppDev(微信小程序开发论坛)(http://weappdev.com)
4 | * 垂直微信小程序开发交流社区
5 | *
6 | * github地址: https://github.com/icindy/wxParse
7 | *
8 | * for: 微信小程序富文本解析
9 | * detail : http://weappdev.com/t/wxparse-alpha0-1-html-markdown/184
10 | */
11 |
12 | /**
13 | * utils函数引入
14 | **/
15 | import showdown from './showdown.js';
16 | import HtmlToJson from './html2json.js';
17 | /**
18 | * 配置及公有属性
19 | **/
20 | var realWindowWidth = 0;
21 | var realWindowHeight = 0;
22 | wx.getSystemInfo({
23 | success: function (res) {
24 | realWindowWidth = res.windowWidth
25 | realWindowHeight = res.windowHeight
26 | }
27 | })
28 | /**
29 | * 主函数入口区
30 | **/
31 | function wxParse(bindName = 'wxParseData', type='html', data='
数据不能为空
', target,imagePadding) {
32 | var that = target;
33 | var transData = {};//存放转化后的数据
34 | if (type == 'html') {
35 | transData = HtmlToJson.html2json(data, bindName);
36 |
37 | } else if (type == 'md' || type == 'markdown') {
38 | var converter = new showdown.Converter();
39 | var html = converter.makeHtml(data);
40 | transData = HtmlToJson.html2json(html, bindName);
41 |
42 | }
43 | transData.view = {};
44 | transData.view.imagePadding = 0;
45 | if(typeof(imagePadding) != 'undefined'){
46 | transData.view.imagePadding = imagePadding
47 | }
48 | var bindData = {};
49 | bindData[bindName] = transData;
50 | that.setData(bindData)
51 | that.wxParseImgLoad = wxParseImgLoad;
52 | that.wxParseImgTap = wxParseImgTap;
53 | }
54 | // 图片点击事件
55 | function wxParseImgTap(e) {
56 | var that = this;
57 | var nowImgUrl = e.target.dataset.src;
58 | var tagFrom = e.target.dataset.from;
59 | if (typeof (tagFrom) != 'undefined' && tagFrom.length > 0) {
60 | wx.previewImage({
61 | current: nowImgUrl, // 当前显示图片的http链接
62 | urls: that.data[tagFrom].imageUrls // 需要预览的图片http链接列表
63 | })
64 | }
65 | }
66 |
67 | /**
68 | * 图片视觉宽高计算函数区
69 | **/
70 | function wxParseImgLoad(e) {
71 | var that = this;
72 | var tagFrom = e.target.dataset.from;
73 | var idx = e.target.dataset.idx;
74 | if (typeof (tagFrom) != 'undefined' && tagFrom.length > 0) {
75 | calMoreImageInfo(e, idx, that, tagFrom)
76 | }
77 | }
78 | // 假循环获取计算图片视觉最佳宽高
79 | function calMoreImageInfo(e, idx, that, bindName) {
80 | var temData = that.data[bindName];
81 | if (!temData || temData.images.length == 0) {
82 | return;
83 | }
84 | var temImages = temData.images;
85 | //因为无法获取view宽度 需要自定义padding进行计算,稍后处理
86 | var recal = wxAutoImageCal(e.detail.width, e.detail.height,that,bindName);
87 | // temImages[idx].width = recal.imageWidth;
88 | // temImages[idx].height = recal.imageheight;
89 | // temData.images = temImages;
90 | // var bindData = {};
91 | // bindData[bindName] = temData;
92 | // that.setData(bindData);
93 | var index = temImages[idx].index
94 | var key = `${bindName}`
95 | for (var i of index.split('.')) key+=`.nodes[${i}]`
96 | var keyW = key + '.width'
97 | var keyH = key + '.height'
98 | that.setData({
99 | [keyW]: recal.imageWidth,
100 | [keyH]: recal.imageheight,
101 | })
102 | }
103 |
104 | // 计算视觉优先的图片宽高
105 | function wxAutoImageCal(originalWidth, originalHeight,that,bindName) {
106 | //获取图片的原始长宽
107 | var windowWidth = 0, windowHeight = 0;
108 | var autoWidth = 0, autoHeight = 0;
109 | var results = {};
110 | var padding = that.data[bindName].view.imagePadding;
111 | windowWidth = realWindowWidth-2*padding;
112 | windowHeight = realWindowHeight;
113 | //判断按照那种方式进行缩放
114 | // console.log("windowWidth" + windowWidth);
115 | if (originalWidth > windowWidth) {//在图片width大于手机屏幕width时候
116 | autoWidth = windowWidth;
117 | // console.log("autoWidth" + autoWidth);
118 | autoHeight = (autoWidth * originalHeight) / originalWidth;
119 | // console.log("autoHeight" + autoHeight);
120 | results.imageWidth = autoWidth;
121 | results.imageheight = autoHeight;
122 | } else {//否则展示原来的数据
123 | results.imageWidth = originalWidth;
124 | results.imageheight = originalHeight;
125 | }
126 | return results;
127 | }
128 |
129 | function wxParseTemArray(temArrayName,bindNameReg,total,that){
130 | var array = [];
131 | var temData = that.data;
132 | var obj = null;
133 | for(var i = 0; i < total; i++){
134 | var simArr = temData[bindNameReg+i].nodes;
135 | array.push(simArr);
136 | }
137 |
138 | temArrayName = temArrayName || 'wxParseTemArray';
139 | obj = JSON.parse('{"'+ temArrayName +'":""}');
140 | obj[temArrayName] = array;
141 | that.setData(obj);
142 | }
143 |
144 | /**
145 | * 配置emojis
146 | *
147 | */
148 |
149 | function emojisInit(reg='',baseSrc="/wxParse/emojis/",emojis){
150 | HtmlToJson.emojisInit(reg,baseSrc,emojis);
151 | }
152 |
153 | module.exports = {
154 | wxParse: wxParse,
155 | wxParseTemArray:wxParseTemArray,
156 | emojisInit:emojisInit
157 | }
158 |
159 |
160 |
--------------------------------------------------------------------------------
/pages/wxParse/wxParse.json:
--------------------------------------------------------------------------------
1 | {}
--------------------------------------------------------------------------------
/pages/wxParse/wxParse.wxml:
--------------------------------------------------------------------------------
1 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
23 |
24 |
25 |
26 |
27 |
28 | {{item.text}}
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 | \n
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 |
109 |
110 |
111 |
112 |
113 |
114 |
115 |
116 |
117 |
118 |
119 |
120 |
121 |
122 |
123 |
124 |
125 |
126 |
127 |
128 |
129 |
130 |
131 |
132 |
133 |
134 |
135 |
136 |
137 |
138 |
139 |
144 |
145 |
146 |
147 |
148 |
149 |
150 |
151 |
152 |
153 |
154 |
155 |
156 |
157 |
158 |
159 |
160 |
161 |
162 |
163 |
164 |
165 |
166 |
167 |
168 |
169 |
170 |
171 |
172 |
173 |
174 |
175 |
176 |
177 |
178 |
179 |
180 |
181 |
182 |
183 |
184 |
185 |
186 |
187 |
188 |
189 |
190 |
191 |
192 |
193 |
194 |
195 |
196 |
197 |
198 |
199 |
200 |
201 |
202 |
203 |
204 |
205 |
206 |
207 |
208 |
209 |
210 |
211 |
212 |
213 |
214 |
215 |
216 |
221 |
222 |
223 |
224 |
225 |
226 |
227 |
228 |
229 |
230 |
231 |
232 |
233 |
234 |
235 |
236 |
237 |
238 |
239 |
240 |
241 |
242 |
243 |
244 |
245 |
246 |
247 |
248 |
249 |
250 |
251 |
252 |
253 |
254 |
255 |
256 |
257 |
258 |
259 |
260 |
261 |
262 |
263 |
264 |
265 |
266 |
267 |
268 |
269 |
270 |
271 |
272 |
273 |
274 |
275 |
276 |
277 |
278 |
279 |
280 |
281 |
282 |
283 |
284 |
285 |
286 |
287 |
288 |
289 |
290 |
291 |
292 |
297 |
298 |
299 |
300 |
301 |
302 |
303 |
304 |
305 |
306 |
307 |
308 |
309 |
310 |
311 |
312 |
313 |
314 |
315 |
316 |
317 |
318 |
319 |
320 |
321 |
322 |
323 |
324 |
325 |
326 |
327 |
328 |
329 |
330 |
331 |
332 |
333 |
334 |
335 |
336 |
337 |
338 |
339 |
340 |
341 |
342 |
343 |
344 |
345 |
346 |
347 |
348 |
349 |
350 |
351 |
352 |
353 |
354 |
355 |
356 |
357 |
358 |
359 |
360 |
361 |
362 |
363 |
364 |
365 |
366 |
367 |
368 |
373 |
374 |
375 |
376 |
377 |
378 |
379 |
380 |
381 |
382 |
383 |
384 |
385 |
386 |
387 |
388 |
389 |
390 |
391 |
392 |
393 |
394 |
395 |
396 |
397 |
398 |
399 |
400 |
401 |
402 |
403 |
404 |
405 |
406 |
407 |
408 |
409 |
410 |
411 |
412 |
413 |
414 |
415 |
416 |
417 |
418 |
419 |
420 |
421 |
422 |
423 |
424 |
425 |
426 |
427 |
428 |
429 |
430 |
431 |
432 |
433 |
434 |
435 |
436 |
437 |
438 |
439 |
440 |
441 |
442 |
443 |
444 |
449 |
450 |
451 |
452 |
453 |
454 |
455 |
456 |
457 |
458 |
459 |
460 |
461 |
462 |
463 |
464 |
465 |
466 |
467 |
468 |
469 |
470 |
471 |
472 |
473 |
474 |
475 |
476 |
477 |
478 |
479 |
480 |
481 |
482 |
483 |
484 |
485 |
486 |
487 |
488 |
489 |
490 |
491 |
492 |
493 |
494 |
495 |
496 |
497 |
498 |
499 |
500 |
501 |
502 |
503 |
504 |
505 |
506 |
507 |
508 |
509 |
510 |
511 |
512 |
513 |
514 |
515 |
516 |
517 |
518 |
519 |
520 |
525 |
526 |
527 |
528 |
529 |
530 |
531 |
532 |
533 |
534 |
535 |
536 |
537 |
538 |
539 |
540 |
541 |
542 |
543 |
544 |
545 |
546 |
547 |
548 |
549 |
550 |
551 |
552 |
553 |
554 |
555 |
556 |
557 |
558 |
559 |
560 |
561 |
562 |
563 |
564 |
565 |
566 |
567 |
568 |
569 |
570 |
571 |
572 |
573 |
574 |
575 |
576 |
577 |
578 |
579 |
580 |
581 |
582 |
583 |
584 |
585 |
586 |
587 |
588 |
589 |
590 |
591 |
592 |
593 |
594 |
595 |
600 |
601 |
602 |
603 |
604 |
605 |
606 |
607 |
608 |
609 |
610 |
611 |
612 |
613 |
614 |
615 |
616 |
617 |
618 |
619 |
620 |
621 |
622 |
623 |
624 |
625 |
626 |
627 |
628 |
629 |
630 |
631 |
632 |
633 |
634 |
635 |
636 |
637 |
638 |
639 |
640 |
641 |
642 |
643 |
644 |
645 |
646 |
647 |
648 |
649 |
650 |
651 |
652 |
653 |
654 |
655 |
656 |
657 |
658 |
659 |
660 |
661 |
662 |
663 |
664 |
665 |
666 |
667 |
668 |
669 |
670 |
671 |
676 |
677 |
678 |
679 |
680 |
681 |
682 |
683 |
684 |
685 |
686 |
687 |
688 |
689 |
690 |
691 |
692 |
693 |
694 |
695 |
696 |
697 |
698 |
699 |
700 |
701 |
702 |
703 |
704 |
705 |
706 |
707 |
708 |
709 |
710 |
711 |
712 |
713 |
714 |
715 |
716 |
717 |
718 |
719 |
720 |
721 |
722 |
723 |
724 |
725 |
726 |
727 |
728 |
729 |
730 |
731 |
732 |
733 |
734 |
735 |
736 |
737 |
738 |
739 |
740 |
741 |
742 |
743 |
744 |
745 |
746 |
747 |
752 |
753 |
754 |
755 |
756 |
757 |
758 |
759 |
760 |
761 |
762 |
763 |
764 |
765 |
766 |
767 |
768 |
769 |
770 |
771 |
772 |
773 |
774 |
775 |
776 |
777 |
778 |
779 |
780 |
781 |
782 |
783 |
784 |
785 |
786 |
787 |
788 |
789 |
790 |
791 |
792 |
793 |
794 |
795 |
796 |
797 |
798 |
799 |
800 |
801 |
802 |
803 |
804 |
805 |
806 |
807 |
808 |
809 |
810 |
811 |
812 |
813 |
814 |
815 |
816 |
817 |
818 |
819 |
820 |
821 |
822 |
823 |
828 |
829 |
830 |
831 |
832 |
833 |
834 |
835 |
836 |
837 |
838 |
839 |
840 |
841 |
842 |
843 |
844 |
845 |
846 |
847 |
848 |
849 |
850 |
851 |
852 |
853 |
854 |
855 |
856 |
857 |
858 |
859 |
860 |
861 |
862 |
863 |
864 |
865 |
866 |
867 |
868 |
869 |
870 |
871 |
872 |
873 |
874 |
875 |
876 |
877 |
878 |
879 |
880 |
881 |
882 |
883 |
884 |
885 |
886 |
887 |
888 |
889 |
890 |
891 |
892 |
893 |
894 |
895 |
896 |
897 |
898 |
899 |
904 |
905 |
906 |
907 |
908 |
909 |
910 |
911 |
912 |
913 |
914 |
915 |
916 |
917 |
918 |
919 |
920 |
921 |
922 |
923 |
924 |
925 |
926 |
927 |
928 |
929 |
930 |
931 |
932 |
933 |
934 |
935 |
936 |
937 |
938 |
939 |
940 |
941 |
942 |
943 |
944 |
945 |
946 |
947 |
948 |
949 |
950 |
951 |
952 |
953 |
954 |
955 |
956 |
957 |
958 |
959 |
960 |
961 |
962 |
963 |
964 |
965 |
966 |
967 |
--------------------------------------------------------------------------------
/pages/wxParse/wxParse.wxss:
--------------------------------------------------------------------------------
1 |
2 | /**
3 | * author: Di (微信小程序开发工程师)
4 | * organization: WeAppDev(微信小程序开发论坛)(http://weappdev.com)
5 | * 垂直微信小程序开发交流社区
6 | *
7 | * github地址: https://github.com/icindy/wxParse
8 | *
9 | * for: 微信小程序富文本解析
10 | * detail : http://weappdev.com/t/wxparse-alpha0-1-html-markdown/184
11 | */
12 |
13 | .wxParse{
14 | margin: 0 5px;
15 | font-family: Helvetica,sans-serif;
16 | font-size: 28rpx;
17 | color: #666;
18 | line-height: 1.8;
19 | }
20 | view{
21 | word-break:break-all; overflow:auto;
22 | }
23 | .wxParse-inline{
24 | display: inline;
25 | margin: 0;
26 | padding: 0 0 0 30px;
27 | }
28 | /*//标题 */
29 | .wxParse-div{margin: 0;padding: 0;}
30 | .wxParse-h1{ font-size:2em; margin: .67em 0 }
31 | .wxParse-h2{ font-size:1.5em; margin: .75em 0 }
32 | .wxParse-h3{ font-size:1.17em; margin: .83em 0 }
33 | .wxParse-h4{ margin: 1.12em 0}
34 | .wxParse-h5 { font-size:.83em; margin: 1.5em 0 }
35 | .wxParse-h6{ font-size:.75em; margin: 1.67em 0 }
36 |
37 | .wxParse-h1 {
38 | font-size: 18px;
39 | font-weight: 400;
40 | margin-bottom: .9em;
41 | }
42 | .wxParse-h2 {
43 | font-size: 16px;
44 | font-weight: 400;
45 | margin-bottom: .34em;
46 | }
47 | .wxParse-h3 {
48 | font-weight: 400;
49 | font-size: 15px;
50 | margin-bottom: .34em;
51 | }
52 | .wxParse-h4 {
53 | font-weight: 400;
54 | font-size: 14px;
55 | margin-bottom: .24em;
56 | }
57 | .wxParse-h5 {
58 | font-weight: 400;
59 | font-size: 13px;
60 | margin-bottom: .14em;
61 | }
62 | .wxParse-h6 {
63 | font-weight: 400;
64 | font-size: 12px;
65 | margin-bottom: .04em;
66 | }
67 |
68 | .wxParse-h1, .wxParse-h2, .wxParse-h3, .wxParse-h4, .wxParse-h5, .wxParse-h6, .wxParse-b, .wxParse-strong { font-weight: bolder }
69 |
70 | .wxParse-i,.wxParse-cite,.wxParse-em,.wxParse-var,.wxParse-address{font-style:italic}
71 | .wxParse-pre,.wxParse-tt,.wxParse-code,.wxParse-kbd,.wxParse-samp{font-family:monospace}
72 | .wxParse-pre{white-space:pre}
73 | .wxParse-big{font-size:1.17em}
74 | .wxParse-small,.wxParse-sub,.wxParse-sup{font-size:.83em}
75 | .wxParse-sub{vertical-align:sub}
76 | .wxParse-sup{vertical-align:super}
77 | .wxParse-s,.wxParse-strike,.wxParse-del{text-decoration:line-through}
78 | /*wxparse-自定义个性化的css样式*/
79 | /*增加video的css样式*/
80 | .wxParse-strong,.wxParse-s{display: inline}
81 | .wxParse-a{
82 | color: deepskyblue;
83 | word-break:break-all;
84 | overflow:auto;
85 | }
86 |
87 | .wxParse-video{
88 | text-align: center;
89 | margin: 10px 0;
90 | }
91 |
92 | .wxParse-video-video{
93 | width:100%;
94 | }
95 |
96 | .wxParse-img{
97 | /*background-color: #efefef;*/
98 | overflow: hidden;
99 | }
100 |
101 | .wxParse-blockquote {
102 | margin: 0;
103 | padding:10px 0 10px 5px;
104 | font-family:Courier, Calibri,"宋体";
105 | background:#f5f5f5;
106 | border-left: 3px solid #dbdbdb;
107 | }
108 |
109 | .wxParse-code,.wxParse-wxxxcode-style{
110 | display: inline;
111 | background:#f5f5f5;
112 | }
113 | .wxParse-ul{
114 | margin: 20rpx 10rpx;
115 | }
116 |
117 | .wxParse-li,.wxParse-li-inner{
118 | display: flex;
119 | align-items: baseline;
120 | margin: 10rpx 0;
121 | }
122 | .wxParse-li-text{
123 |
124 | align-items: center;
125 | line-height: 20px;
126 | }
127 |
128 | .wxParse-li-circle{
129 | display: inline-flex;
130 | width: 5px;
131 | height: 5px;
132 | background-color: #333;
133 | margin-right: 5px;
134 | }
135 |
136 | .wxParse-li-square{
137 | display: inline-flex;
138 | width: 10rpx;
139 | height: 10rpx;
140 | background-color: #333;
141 | margin-right: 5px;
142 | }
143 | .wxParse-li-ring{
144 | display: inline-flex;
145 | width: 10rpx;
146 | height: 10rpx;
147 | border: 2rpx solid #333;
148 | border-radius: 50%;
149 | background-color: #fff;
150 | margin-right: 5px;
151 | }
152 |
153 | /*.wxParse-table{
154 | width: 100%;
155 | height: 400px;
156 | }
157 | .wxParse-thead,.wxParse-tfoot,.wxParse-tr{
158 | display: flex;
159 | flex-direction: row;
160 | }
161 | .wxParse-th,.wxParse-td{
162 | display: flex;
163 | width: 580px;
164 | overflow: auto;
165 | }*/
166 |
167 | .wxParse-u {
168 | text-decoration: underline;
169 | }
170 | .wxParse-hide{
171 | display: none;
172 | }
173 | .WxEmojiView{
174 | align-items: center;
175 | }
176 | .wxEmoji{
177 | width: 16px;
178 | height:16px;
179 | }
180 | .wxParse-tr{
181 | display: flex;
182 | border-right:1px solid #e0e0e0;
183 | border-bottom:1px solid #e0e0e0;
184 | border-top:1px solid #e0e0e0;
185 | }
186 | .wxParse-th,
187 | .wxParse-td{
188 | flex:1;
189 | padding:5px;
190 | font-size:28rpx;
191 | border-left:1px solid #e0e0e0;
192 | word-break: break-all;
193 | }
194 | .wxParse-td:last{
195 | border-top:1px solid #e0e0e0;
196 | }
197 | .wxParse-th{
198 | background:#f0f0f0;
199 | border-top:1px solid #e0e0e0;
200 | }
201 | .wxParse-del{
202 | display: inline;
203 | }
204 | .wxParse-figure {
205 | overflow: hidden;
206 | }
207 |
--------------------------------------------------------------------------------
/project.config.json:
--------------------------------------------------------------------------------
1 | {
2 | "description": "项目配置文件。",
3 | "setting": {
4 | "urlCheck": false,
5 | "es6": true,
6 | "postcss": true,
7 | "minified": true,
8 | "newFeature": true,
9 | "autoAudits": false
10 | },
11 | "compileType": "miniprogram",
12 | "libVersion": "1.6.6",
13 | "appid": "wx7ee3890ac20c9d0b",
14 | "projectname": "%E5%B0%8F%E8%AF%B4%E9%98%85%E8%AF%BB%E5%99%A8",
15 | "condition": {
16 | "search": {
17 | "current": -1,
18 | "list": []
19 | },
20 | "conversation": {
21 | "current": -1,
22 | "list": []
23 | },
24 | "miniprogram": {
25 | "current": -1,
26 | "list": [
27 | {
28 | "id": 0,
29 | "name": "debug",
30 | "pathName": "pages/help/help",
31 | "query": "book_id=5816b415b06d1d32157790b1"
32 | }
33 | ]
34 | }
35 | }
36 | }
--------------------------------------------------------------------------------
/utils/util.js:
--------------------------------------------------------------------------------
1 | const formatTime = date => {
2 | const year = date.getFullYear()
3 | const month = date.getMonth() + 1
4 | const day = date.getDate()
5 | const hour = date.getHours()
6 | const minute = date.getMinutes()
7 | const second = date.getSeconds()
8 |
9 | return [year, month, day].map(formatNumber).join('/') + ' ' + [hour, minute, second].map(formatNumber).join(':')
10 | }
11 |
12 | const formatNumber = n => {
13 | n = n.toString()
14 | return n[1] ? n : '0' + n
15 | }
16 |
17 | module.exports = {
18 | formatTime: formatTime
19 | }
20 |
--------------------------------------------------------------------------------