├── .gitignore
├── README.md
├── miniprogram
├── app.js
├── app.json
├── app.wxss
├── component
│ ├── NewWxComment
│ │ ├── NewWxComment.js
│ │ ├── NewWxComment.json
│ │ ├── NewWxComment.wxml
│ │ ├── NewWxComment.wxs
│ │ ├── NewWxComment.wxss
│ │ └── images
│ │ │ ├── about.png
│ │ │ ├── about_active.png
│ │ │ ├── copy_link.png
│ │ │ ├── copy_link_active.png
│ │ │ ├── home.png
│ │ │ ├── home_active.png
│ │ │ ├── like.png
│ │ │ ├── like_active.png
│ │ │ ├── more.png
│ │ │ ├── more_active.png
│ │ │ ├── poster.png
│ │ │ ├── poster_active.png
│ │ │ ├── reward.png
│ │ │ ├── reward_active.png
│ │ │ ├── share.png
│ │ │ └── share_active.png
│ └── WxLogin
│ │ ├── WxLogin.js
│ │ ├── WxLogin.json
│ │ ├── WxLogin.wxml
│ │ ├── WxLogin.wxss
│ │ └── images
│ │ └── login_active.png
├── libs
│ ├── leancloud
│ │ ├── av-weapp-min.js
│ │ └── rest_api_leancloud.js
│ └── scripts
│ │ └── common.js
├── pages
│ ├── index
│ │ ├── index.js
│ │ ├── index.json
│ │ ├── index.wxml
│ │ └── index.wxss
│ └── logs
│ │ ├── logs.js
│ │ ├── logs.json
│ │ ├── logs.wxml
│ │ └── logs.wxss
├── sitemap.json
└── utils
│ └── util.js
├── project.config.json
└── screenshots
├── NewWxComment.png
└── Xiaobaiai.jpg
/.gitignore:
--------------------------------------------------------------------------------
1 | *.swp
2 | *.swo
3 | *.bak
4 | *.bin
5 | *.exe
6 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # NewWxComment
2 |
3 | `NewWxComment`[https://github.com/yicm/NewWxComment](https://github.com/yicm/NewWxComment)是一个微信小程序的评论组件,结合BaaS提供商[LeanCloud](https://leancloud.cn/),无需其他另外的个人或者云服务器,就可以免费使用。解决了需要个人去注册域名、备案、购买云服务器的繁杂问题。且兼容`Valine`[https://github.com/xCss/Valine](https://github.com/xCss/Valine)评论,打通PC端和移动端评论,特别适合使用Valine评论系统且想同时开发小程序文章评论的同学们。
4 |
5 | > ps: 打造这个插件的目的在于本人想要打造一个类似hexo通用博客框架,且是一个移动端的框架,首先采用微信小程序实现,现已完成博文编译器的开发,评论插件的开发(打通PC端Valine插件),微信小程序的经典主题开发(未发布),期待发布经典主题后,有更多开发者加入,开发更多的插件和主题,一起打通PC端和"现在移动端",实现移动端的个人博客;
6 |
7 | > Hexo博客编译器已开源[https://github.com/yicm/HMP](https://github.com/yicm/HMP),直接打通静态博客和微信小程序,Demo可微信搜索`小白AI博客`查看。
8 |
9 | > 先提前“剧透”下经典主题首页,倾心打造:
10 |
11 | 
12 |
13 |
14 | # 特色
15 |
16 | - 独立插件,独立放入小程序项目即可使用
17 | - 打通Valine评论系统,统一PC端和小程序端
18 | - 友好的UI界面和交互界面
19 | - 与微信用户信息绑定,显示微信用户头像和昵称
20 | - 支持文章阅读量统计功能
21 | - 支持评论回复功能,即子评论
22 | - 支持emoji表情显示😉
23 | - 支持评论分页加载
24 | - 支持评论分页参数设置
25 | - 内置获取微信用户公共信息授权
26 | - 支持light/dark两种主题
27 | - 机型兼容友好,包括全面屏iphone11等
28 |
29 | # 已测试通过机型
30 |
31 | - iphone6s plus
32 | - iphone11/xr
33 | - ipad4 pro
34 | - redmi6 pro
35 |
36 | # 屏幕截图
37 |
38 | 下图为`NewWxComment`嵌入式到具体博客中显示的效果。PC端评论效果可以访问网站[https://xiaobaiai.net](https://xiaobaiai.net)
39 |
40 | 
41 |
42 | # 快速入手
43 |
44 | > 注意:下面的前三步也可以参考Valine评论插件方法,如果是Valine已经设置好了,直接跳过前三步;
45 |
46 | 1. 注册LeanCloud账号,并创建过LeanCloud应用;
47 |
48 | 2. 登陆LeanCloud账号,打开链接[https://leancloud.cn/docs/weapp-domains.html](https://leancloud.cn/docs/weapp-domains.html),将显示域名配置到你的微信小程序服务器配置中;
49 |
50 | 3. 设置小程序的 AppID 与 AppSecret
51 | 3.1 登录 微信公众平台,在`设置` > `开发设置` 中获得 AppID 与 AppSecret
52 | 3.2 前往 LeanCloud `控制台` > `组件` > `社交`,保存「微信小程序」的 AppID 与 AppSecret
53 |
54 | 4. 克隆Demo项目NewWxComment(Demo项目已附带NewWxComment组件)
55 |
56 | ```
57 | $ git clone https://github.com/yicm/NewWxComment.git
58 | ```
59 |
60 | 5. 将LeanCloud自己的AppID和AppKey复制到NewWxComment.js对应位置;
61 |
62 | ```
63 | AV.init({
64 | appId: 'your leancloud appid',
65 | appKey: 'your leancloud appkey',
66 | });
67 | ```
68 |
69 | 6. 在小程序index.wxml和index.json文件中已经引入NewWxComment组件
70 |
71 | index.wxml
72 |
73 | ```
74 |
75 | ```
76 |
77 | index.json
78 |
79 | ```
80 | "usingComponents": {
81 | "NewWxComment": "/component/NewWxComment/NewWxComment"
82 | }
83 | ```
84 |
85 | index.js中添加触底才获取评论数据:
86 |
87 | ```
88 | // 到底触发获取评论数据函数
89 | // 添加触发拉取评论函数
90 | onReachBottom: function() {
91 | let newWxComment = this.selectComponent('#NewWxComment');
92 | newWxComment.onReachBottom();
93 | }
94 | ```
95 | 如果评论格数显示不正常,检查app.js `container`样式:
96 |
97 | ```
98 | .container {
99 | padding: 0 24rpx;
100 | background-color: #fff;
101 | font-family: Microsoft YaHei, Helvetica, Arial, sans-serif;
102 | }
103 | ```
104 |
105 | NewWxComment组件属性说明:
106 |
107 | ```bash
108 | articleTitle: 待评论页文章标题
109 | articleURL: 待评论页文章链接(不包含网站域名)
110 | homeURL: 小程序首页路径
111 | pageSize: 评论每页加载条数,默认值5
112 | contentMinLen: 评论最小长度要求,默认值2
113 | contentMaxLen: 评论最大长度限制,默认值300
114 | articleID: 待评论文章唯一ID
115 | websiteURL: PC端网站域名(若无可不填),默认值`https://xiaobaiai.net`
116 | theme: 主题设置,仅支持 light 或者 dark 两个属性值
117 | ```
118 |
119 | # Demo
120 |
121 | 小程序`小白AI博客`引用NewWxComment组件示例:
122 |
123 | 
124 |
125 | # TODO
126 |
127 | - 支持点赞列表
128 | - 支持作者回复高亮标志
129 | - 支持垃圾评论过滤
130 | - 支持海报分享
131 | - 支持赞赏
132 | - ...
133 |
134 | # License
135 |
136 | [Mulan PSL v1](http://license.coscl.org.cn/MulanPSL)
137 |
138 |
139 |
--------------------------------------------------------------------------------
/miniprogram/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 | })
--------------------------------------------------------------------------------
/miniprogram/app.json:
--------------------------------------------------------------------------------
1 | {
2 | "pages": [
3 | "pages/index/index",
4 | "pages/logs/logs"
5 | ],
6 | "window": {
7 | "backgroundTextStyle": "light",
8 | "navigationBarBackgroundColor": "#fff",
9 | "navigationBarTitleText": "WeChat",
10 | "navigationBarTextStyle": "black"
11 | },
12 | "sitemapLocation": "sitemap.json"
13 | }
--------------------------------------------------------------------------------
/miniprogram/app.wxss:
--------------------------------------------------------------------------------
1 | /**app.wxss**/
2 |
3 | .container {
4 | padding: 0 24rpx;
5 | background-color: #fff;
6 | font-family: Microsoft YaHei, Helvetica, Arial, sans-serif;
7 | }
8 |
--------------------------------------------------------------------------------
/miniprogram/component/NewWxComment/NewWxComment.js:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright (c) [2019] [Ethan(yicm1102@gmail.com)]
3 | [NewWxComment] is licensed under the Mulan PSL v1.
4 | You can use this software according to the terms and conditions of the Mulan PSL v1.
5 | You may obtain a copy of Mulan PSL v1 at:
6 | http://license.coscl.org.cn/MulanPSL
7 | THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR
8 | IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR
9 | PURPOSE.
10 | See the Mulan PSL v1 for more details.
11 |
12 | And more:
13 | author: yicm1102@gmail.com
14 | github: https://github.com/yicm/NewWxComment
15 | website: https://xiaobaiai.net
16 | sync valine version: 1.3.6
17 | leanstorage javascript api: https://leancloud.cn/docs/leanstorage_guide-js.html
18 | */
19 | const AV = require('../../libs/leancloud/av-weapp-min.js');
20 | var Common = require('../../libs/scripts/common.js');
21 | // LeanCloud 应用的 ID 和 Key
22 |
23 | AV.init({
24 | appId: 'your leancloud app id',
25 | appKey: 'your leancloud app key',
26 | });
27 |
28 | Component({
29 | /**
30 | * 组件的属性列表
31 | */
32 | properties: {
33 | articleTitle: {
34 | type: String,
35 | value: ''
36 | },
37 | articleURL: {
38 | type: String,
39 | value: ''
40 | },
41 | homeURL: {
42 | type: String,
43 | value: '../index/index'
44 | },
45 | pageSize: {
46 | type: Number,
47 | value: 5
48 | },
49 | theme: {
50 | type: String,
51 | value: 'light' // light & dark
52 | },
53 | contentMinLen: {
54 | // 评论内容至少为多长限制
55 | type: Number,
56 | value: 2
57 | },
58 | contentMaxLen: {
59 | type: Number,
60 | value: 300
61 | },
62 | copyRight: {
63 | type: String,
64 | value: '©2019 小白AI.易名 xiaobaiai.net'
65 | },
66 | articleID: {
67 | type: String,
68 | value: '',
69 | observer: function (newVal, oldVal) {
70 | let that = this;
71 | // console.log(that.data.articleID);
72 | // console.log(newVal);
73 | // 在组件实例进入页面节点树时执行
74 | // this.data生效
75 | // 获取总评论数
76 | this._leanQuery('total');
77 | // 获取点赞数
78 | // TODO
79 |
80 | if (this.data.theme == 'dark') {
81 | this.setData({
82 | isDark: true
83 | })
84 | } else {
85 | this.setData({
86 | isDark: false
87 | })
88 | }
89 | this.fetechPCommentNum();
90 | }
91 | },
92 | websiteURL: {
93 | type: String,
94 | value: 'https://xiaobaiai.net'
95 | }
96 | },
97 |
98 | /**
99 | * 组件的初始数据
100 | */
101 | data: {
102 | // 主题
103 | isDark: false,
104 | // 系统相关
105 | uaInfo: '',
106 | // 赞赏码
107 | praiseQRCodeURL: 'https://gitee.com/yicm/Images/raw/master/common/wx_appreciation_code.jpg',
108 | // 授权相关
109 | showAurButton: false,
110 | isMenuboxShow: false,
111 | isMenuboxLoad: true,
112 | enableComment: true,
113 | menuBackgroup: false,
114 | isLoginPopup: false,
115 | userInfo: {},
116 | // 评论相关
117 | commentTabName: 'Comment',
118 | counterTabName: 'Counter',
119 | placeholder: '评论...',
120 | display: 'block',
121 | commentPNum: 0,
122 | commentCount: 0,
123 | likeCount: 0,
124 | commentCountStr: '',
125 | commentIndex: 1,
126 | isLastPage: false,
127 | isLoading: false,
128 | isFocusing: false,
129 | commentsRawList: [],
130 | commentsList: [],
131 | content: '',
132 | toCommentPid: undefined,
133 | toCommentRid: undefined
134 | },
135 |
136 | /**
137 | * 组件生命周期函数
138 | */
139 | lifetimes: {
140 | created: function () {
141 | // 组件实例刚刚被创建时
142 | console.log("created");
143 | },
144 | attached: function () {
145 | this.getUAInfo();
146 | },
147 | ready: function () {
148 | // 在组件在视图层布局完成后执行
149 | //console.log("ready");
150 | },
151 | detached: function () {
152 | // 在组件实例被从页面节点树移除时执行
153 | //console.log("detached");
154 | },
155 | },
156 | /**
157 | * 组件的方法列表
158 | */
159 | methods: {
160 | showHideMenu: function (e) {
161 | this.setData({
162 | showAurButton: false,
163 | isMenuboxShow: !this.data.isMenuboxShow,
164 | isMenuboxLoad: false,
165 | menuBackgroup: this.data.isMenuboxShow
166 | })
167 | },
168 | // 点击非评论区隐藏功能菜单
169 | hiddenMenubox: function () {
170 | console.log("hiddenMenubox");
171 | this.setData({
172 | isMenuboxShow: false,
173 | menuBackgroup: false
174 | })
175 | },
176 | goHome: function () {
177 | var that = this;
178 | wx.switchTab({
179 | url: that.data.homeURL
180 | })
181 | },
182 | onCreatePoster: function () {
183 | wx.showToast({
184 | title: '敬请期待',
185 | icon: 'none',
186 | duration: 2000
187 | });
188 | },
189 | clickLike: function () {
190 | wx.showToast({
191 | title: '敬请期待',
192 | icon: 'none',
193 | duration: 2000
194 | });
195 | },
196 | aboutWxComment: function () {
197 | let that = this;
198 | wx.showModal({
199 | title: '关于',
200 | content: that.data.websiteURL,
201 | showCancel: false,
202 | confirmText: '记住了',
203 | success(res) {
204 | // nothing to do
205 | }
206 | })
207 | },
208 | praise: function () {
209 | let that = this;
210 | wx.previewImage({
211 | urls: [that.data.praiseQRCodeURL],
212 | current: that.data.praiseQRCodeURL
213 | })
214 | },
215 | copyLink: function () {
216 | let that = this;
217 | if (that.data.websiteURL) {
218 | console.log(that.data.websiteURL + that.data.articleURL);
219 | wx.setClipboardData({
220 | data: that.data.websiteURL + that.data.articleURL,
221 | success: function (res) {
222 | wx.showToast({
223 | title: '复制成功',
224 | icon: 'success',
225 | duration: 2000
226 | });
227 | }
228 | });
229 | } else {
230 | console.log('网站主页域名未设置');
231 | }
232 | },
233 | replay: function (e) {
234 | let that = this;
235 | let id = e.target.dataset.id;
236 | let name = e.target.dataset.name;
237 | let rid = e.target.dataset.rid;
238 | let pid = e.target.dataset.pid;
239 | let commentdate = e.target.dataset.commentdate;
240 | if (id) {
241 | that.data.isFocusing = true;
242 | if (that.data.enableComment) {
243 | that.setData({
244 | toCommentPid: id,
245 | placeholder: "@" + name,
246 | focus: true,
247 | toCommentRid: rid || id,
248 | toUser: name,
249 | commentdate: commentdate
250 | });
251 |
252 | }
253 | } else {
254 | console.log('暂不支持更多嵌套层评论');
255 | }
256 | //console.log('toCommentPid', that.data.toCommentPid);
257 | //console.log('toCommentRid', that.data.toCommentRid);
258 | },
259 | onReplyBlur: function (e) {
260 | let that = this;
261 | console.log('onReplyBlur');
262 | that.data.isFocusing = false;
263 | const text = e.detail.value.trim();
264 | if (text === '') {
265 | that._resetInput();
266 | }
267 | },
268 | onRepleyFocus: function (e) {
269 | console.log('onReplyFocus');
270 | },
271 | getLeanCloudACL: function (read, write) {
272 | let acl = new AV.ACL();
273 | acl.setPublicReadAccess(read);
274 | acl.setPublicWriteAccess(write);
275 | return acl;
276 | },
277 | writeComment: function (content, rid, pid, is_reply, to_user, user_info) {
278 | let that = this;
279 | // 未存在会创建新表
280 | let Ct = AV.Object.extend(that.data.commentTabName);
281 | let commenter = new Ct();
282 | let commentObj = {};
283 | let currentDate = new Date();
284 | console.log('writeComment' + that.data.articleID);
285 | commentObj["nick"] = that.data.userInfo.nickName;
286 | commentObj["mail"] = '';
287 | commentObj["child"] = []
288 | commentObj['link'] = '';
289 | commentObj["url"] = that.data.articleURL;
290 | commentObj['avatar'] = that.data.userInfo.avatarUrl;
291 | commentObj['comment'] = content;
292 |
293 | commenter.set('nick', that.data.userInfo.nickName);
294 | commenter.set('mail', '');
295 | commenter.set('link', '');
296 | commenter.set('ua', that.data.uaInfo);
297 | commenter.set('url', that.data.articleURL);
298 | commenter.set('comment', `
${content}
`);
299 | commenter.set('insertedAt', currentDate);
300 | if (is_reply) {
301 | commentObj["pid"] = pid;
302 | commentObj["rid"] = rid;
303 | commenter.set('rid', rid);
304 | commenter.set('pid', pid);
305 | commenter.set('comment', `@${to_user} , ${content}
`);
306 | }
307 | commenter.setACL(that.getLeanCloudACL(true, false));
308 | const user = AV.User.current();
309 | let targetUser = AV.Object.createWithoutData('_User', user.id);
310 | commenter.set('targetUser', targetUser);
311 |
312 | commenter.save().then(ret => {
313 | if (!is_reply) {
314 | that.setData({
315 | commentPNum: that.data.commentPNum + 1,
316 | commentCountStr: "有" + (that.data.commentCount + 1) + "条评论",
317 | commentCount: that.data.commentCount + 1
318 | })
319 | } else {
320 | that.setData({
321 | commentCountStr: "有" + (that.data.commentCount + 1) + "条评论",
322 | commentCount: that.data.commentCount + 1
323 | })
324 | }
325 |
326 | let buildArray = new Array();
327 | buildArray[0] = ret;
328 | console.log(buildArray);
329 | // 子评论需要对已加载评论重新进行评论树构建
330 | if (is_reply) {
331 | that.buildCommentTree(buildArray, true, true);
332 | } else {
333 | that.buildCommentTree(buildArray, true);
334 | }
335 | }).catch(ex => {
336 | wx.showToast({
337 | title: '评论发生错误...',
338 | icon: 'none',
339 | duration: 2000
340 | })
341 | console.log(ex.code);
342 | console.log(ex.message);
343 | console.log(ex.error);
344 | });
345 | },
346 | // 提交评论
347 | bindFormSubmit: function (e) {
348 | let that = this;
349 | // 判断内容长度是否满足最小要求
350 | let content = e.detail.value.inputComment;
351 | if (content.length <= that.data.contentMinLen) {
352 | wx.showToast({
353 | title: '评论内容长度不够^_^',
354 | icon: 'none',
355 | duration: 2000
356 | })
357 | return;
358 | }
359 |
360 | // 检查授权 & 写入评论
361 | wx.getSetting({
362 | success(res) {
363 | if (!res.authSetting['scope.userInfo']) {
364 | // console.log("没有授权获取用户信息");
365 | that.setData({
366 | showAurButton: true
367 | });
368 | } else {
369 | // console.log("已经授权获取用户信息,开始获取信息");
370 | wx.getUserInfo({
371 | success: function (res) {
372 | that.data.userInfo = res.userInfo;
373 | // LeanCloud 用户一键登录
374 | AV.User.loginWithWeapp().then(user => {
375 | if (user.attributes.nickName !=
376 | that.data.userInfo.nickName ||
377 | user.attributes.avatarUrl !=
378 | that.data.userInfo.avatarUrl) {
379 | // 更新LeanCloud用户信息
380 | console.log('更新LeanCloud用户信息');
381 | that._updateUserInfoInLeanCloud();
382 | }
383 | let is_reply = false;
384 | let rid = that.data.toCommentRid;
385 | let pid = that.data.toCommentPid;
386 | let to_user = that.data.toUser;
387 | let user_info = that.data.userInfo;
388 | if (rid || pid) {
389 | is_reply = true;
390 | }
391 | // 写入评论
392 | that.writeComment(content, rid, pid, is_reply, to_user, user_info);
393 | }).catch(console.error);
394 | }
395 | })
396 | }
397 | },
398 | fail: function () {
399 | console.log("获取用户的当前设置失败");
400 | }
401 | })
402 |
403 | },
404 | onReachBottom: function () {
405 | console.log("达到底部");
406 | let that = this;
407 | //console.log(that.data.commentPNum);
408 | //console.log(that.data.isLastPage);
409 | if (that.data.commentPNum > 0 && !that.data.isLastPage) {
410 | that.fetchCommentDetailData(that.data.commentIndex);
411 | let current_pcomment_showed_num = that.data.commentIndex * that.data.pageSize;
412 | if (current_pcomment_showed_num < that.data.commentPNum) {
413 | that.data.commentIndex = that.data.commentIndex + 1;
414 | } else {
415 | that.setData({
416 | isLastPage: true
417 | });
418 | }
419 | }
420 | },
421 | checkTime: function (s) {
422 | return s < 10 ? '0' + s : s;
423 | },
424 | getLocalDateTimeStr: function (input) {
425 | let that = this;
426 | let d = new Date(input)
427 | let res_date = d.getFullYear() + '-' + that.checkTime((d.getMonth() + 1)) + '-' + that.checkTime(d.getDate());
428 | let res_time = that.checkTime(d.getHours()) + ':' + that.checkTime(d.getMinutes()) + ':' + that.checkTime(d.getSeconds());
429 | return res_date + ' ' + res_time;
430 | },
431 | buildCommentTree: function (source, is_wechat = false, is_reply = false, p_key = 'pid', self_key = 'id', child_key = 'child', root_value = undefined) {
432 | let that = this;
433 | // 整理数据
434 | let new_data = [];
435 | for (let i = 0; i < source.length; i++) {
436 | let item = {};
437 | item["id"] = source[i].id;
438 | item["author_name"] = source[i].attributes.nick;
439 | item["content"] = source[i].attributes.comment;
440 | item["date"] = that.getLocalDateTimeStr(source[i].updatedAt);
441 | item["child"] = []
442 | item["pid"] = source[i].attributes.pid;
443 | item["rid"] = source[i].attributes.rid;
444 | item["url"] = source[i].attributes.url;
445 | // 处理小程序提交评论
446 | if (source[i].attributes.targetUser) {
447 | if (is_wechat && !source[i].attributes.targetUser.attributes.nickName) {
448 | item['avatar'] = that.data.userInfo.avatarUrl;
449 | } else {
450 | item['author_name'] = source[i].attributes.targetUser.attributes.nickName;
451 | item['avatar'] = source[i].attributes.targetUser.attributes.avatarUrl;
452 | }
453 |
454 | }
455 | // 正则处理valine评论内容
456 | if (!item["pid"]) {
457 | item["content"] = item["content"].match(/(.*)<\/p>/)[1];
458 |
459 | } else {
460 | item["content"] = item["content"].match(/<\/a> , (.*)<\/p>/)[1];
461 | }
462 |
463 | new_data.push(item);
464 | }
465 | // 记录所有原始数据
466 | if (new_data) {
467 | that.data.commentsRawList = [].concat(that.data.commentsRawList, new_data);
468 | //console.log(that.data.commentsRawList);
469 | }
470 | if (is_wechat && is_reply) {
471 | new_data = that.data.commentsRawList;
472 | }
473 |
474 | // 生成评论树
475 | let data = JSON.parse(JSON.stringify(new_data));
476 | for (let i = 0; i < data.length; i++) {
477 | let item_i = data[i];
478 | if (item_i[p_key] === root_value) {
479 | continue;
480 | }
481 | for (let j = 0; j < data.length; j++) {
482 | if (i === j) {
483 | continue;
484 | }
485 | let item_j = data[j];
486 | if (item_i[p_key] === item_j[self_key]) {
487 | if (!item_j[child_key] ||
488 | Object.prototype.toString.call(item_j[child_key]) !==
489 | '[object Array]'
490 | ) {
491 | item_j[child_key] = [];
492 | }
493 | item_j[child_key].push(item_i);
494 | break;
495 | }
496 | }
497 | }
498 | let tree_data = data.filter(item => item[p_key] === root_value);
499 |
500 | // set data
501 | if (tree_data) {
502 | if (is_wechat && !is_reply) {
503 | that.setData({
504 | commentsList: [].concat(tree_data, that.data.commentsList)
505 | });
506 | } else if (is_wechat && is_reply) {
507 | that.setData({
508 | commentsList: tree_data
509 | })
510 | } else {
511 | that.setData({
512 | commentsList: [].concat(that.data.commentsList, tree_data)
513 | });
514 | }
515 | }
516 | // 重置输入框状态
517 | console.log('重置输入框状态');
518 | that._resetInput();
519 | },
520 | fetchCommentDetailData: function (no) {
521 | let that = this;
522 | let cq = that._leanQuery(that.data.articleID);
523 | let size = that.data.pageSize;
524 | let all_data = [];
525 | that.setData({
526 | isLoading: true
527 | });
528 | cq.limit(size);
529 | cq.skip((no - 1) * size);
530 | cq.include('targetUser');
531 | cq.find().then(rets => {
532 | let len = rets.length;
533 | let rids = []
534 | for (let i = 0; i < len; i++) {
535 | let ret = rets[i];
536 | rids.push(ret.id)
537 | }
538 | all_data = [].concat(rets);
539 | // load children comment
540 | that._leanQuery(that.data.articleID, rids).find().then(ret => {
541 | let childs = ret || [];
542 | console.log("子评论数:" + childs.length);
543 | all_data = all_data.concat(childs);
544 | //console.log(all_data);
545 | that.buildCommentTree(all_data);
546 | }).catch(ex => {
547 | wx.showToast({
548 | title: '加载评论错误...',
549 | icon: 'none',
550 | duration: 2000
551 | })
552 | console.log(ex.code);
553 | console.log(ex.message);
554 | console.log(ex.error);
555 | })
556 | }).catch(ex => {
557 | wx.showToast({
558 | title: '加载评论出错...',
559 | icon: 'none',
560 | duration: 2000
561 | })
562 | console.log(ex.code);
563 | console.log(ex.message);
564 | console.log(ex.error);
565 | }).finally(function () {
566 | that.setData({
567 | isLoading: false
568 | });
569 | });
570 | },
571 | getUAInfo: function () {
572 | let that = this;
573 | wx.getSystemInfo({
574 | success: function (res) {
575 | if (res.system.includes('Android')) {
576 | that.data.uaInfo = "Mozilla/5.0 (" + res.model + ";" + res.system + ";" + res.language + ") AppleWebKit/537.36 MicroMessenger/" + res.version;
577 | } else {
578 | let system = res.system.replace(/\./g, '_') + " like Mac OS X";
579 | that.data.uaInfo = "Mozilla/5.0 (" + res.model + ";" + system + ";" + res.language + ") AppleWebKit/537.36 MicroMessenger/" + res.version;
580 | }
581 |
582 | console.log(that.data.uaInfo);
583 | },
584 | })
585 | },
586 | fetechPCommentNum: function () {
587 | let that = this;
588 | that._leanQuery(that.data.articleID).count().then(num => {
589 | if (num > 0) {
590 | console.log("父评论总数:" + num);
591 | that.data.commentPNum = num;
592 | } else {
593 | console.log("暂无评论");
594 | that.setData({
595 | isLastPage: true
596 | })
597 | }
598 | }).catch(ex => {
599 | // https://leancloud.cn/docs/error_code.html#hash1389221
600 | // first time to create Counter Class
601 | if (101 == error.code) {
602 | // do something
603 | }
604 | console.log(ex.code);
605 | console.log(ex.message);
606 | console.log(ex.error);
607 | });
608 | },
609 | // 获取评论总数
610 | fetchCommentCount: function () {
611 | let that = this;
612 | let counter_query = new AV.Query(that.data.commentTabName);
613 | counter_query.equalTo('url', that.data.articleID);
614 | counter_query.count().then(function (count) {
615 | console.log('评论总数:' + count);
616 | if (count && count > 0) {
617 | that.setData({
618 | commentCountStr: "有" + count + "条评论",
619 | commentCount: count
620 | });
621 | }
622 | // 更新页面计数和评论数及点赞数
623 | that.updatePageCounter();
624 | },
625 | function (error) {
626 | console.log(error.message);
627 | console.log(error.code);
628 | // https://leancloud.cn/docs/error_code.html#hash1389221
629 | // first time to create Counter Class
630 | if (101 == error.code) {
631 | // 没有评论表,评论为0
632 | that.setData({
633 | isLastPage: true,
634 | commentCountStr: "有0条评论"
635 | });
636 | }
637 | });
638 | },
639 | createPageCounter: function () {
640 | let that = this;
641 | // 未存在会创建新表
642 | let Counter = AV.Object.extend(that.data.counterTabName);
643 | let newCounter = new Counter();
644 | newCounter.setACL(that.getLeanCloudACL(true, true));
645 | newCounter.set('url', that.data.articleID);
646 | newCounter.set('xid', that.data.articleID);
647 | newCounter.set('title', that.data.articleTitle);
648 | newCounter.set('time', 1);
649 | newCounter.set('comments', that.data.commentCount);
650 | newCounter.set('likes', that.data.likeCount);
651 | newCounter.save().then(ret => {
652 | // nothing to do
653 | console.log('初始化页面计数表成功');
654 | }).catch(ex => {
655 | console.log(ex)
656 | wx.showToast({
657 | title: '创建数据表失败',
658 | icon: 'none',
659 | duration: 2000
660 | });
661 | });
662 | },
663 | updatePageCounter: function () {
664 | let that = this;
665 | let query = new AV.Query(that.data.counterTabName);
666 | query.equalTo('url', that.data.articleID);
667 | query.find().then(ret => {
668 | //console.log(ret);
669 | if (ret.length > 0) {
670 | let v = ret[0];
671 | v.increment("time");
672 | v.set('comments', that.data.commentCount);
673 | v.set('likes', that.data.likeCount);
674 | v.save().then(rt => {
675 | // 页面计数更新成功
676 | console.log('页面计数更新成功');
677 | }).catch(ex => {
678 | console.log(ex)
679 | // 页面计数更新失败
680 | console.log('页面计数更新失败');
681 | });
682 | } else {
683 | // 小程序端先于PC端访问,则需要创建该条记录
684 | let Counter = AV.Object.extend(that.data.counterTabName);
685 | let counter = new Counter();
686 | counter.setACL(that.getLeanCloudACL(true, true));
687 | counter.set('url', that.data.articleID);
688 | counter.set('xid', that.data.articleID);
689 | counter.set('title', that.data.articleTitle);
690 | counter.set('time', 1);
691 | counter.set('comments', that.data.commentCount);
692 | counter.set('likes', that.data.likeCount);
693 |
694 | counter.save();
695 | }
696 | }).catch(ex => {
697 | console.log(ex.message);
698 | console.log(ex.code);
699 | if (ex.code == 101) {
700 | console.log('页面计数表未存在,开始创建');
701 | that.createPageCounter();
702 | }
703 | });
704 | },
705 | _resetInput: function () {
706 | let that = this;
707 | that.setData({
708 | toCommentPid: '',
709 | placeholder: "评论...",
710 | toCommentRid: '',
711 | commentdate: "",
712 | content: '',
713 | toUser: ''
714 | });
715 | },
716 | _leanQuery: function (k) {
717 | let that = this;
718 | let len = arguments.length;
719 | if (k === 'total') {
720 | that.fetchCommentCount();
721 | } else if (len == 1) {
722 | let notExist = new AV.Query(that.data.commentTabName);
723 | notExist.doesNotExist('rid');
724 | let isEmpty = new AV.Query(that.data.commentTabName);
725 | isEmpty.equalTo('rid', '');
726 | let q = AV.Query.or(notExist, isEmpty);
727 | if (k === '*') {
728 | q.exists('url');
729 | } else {
730 | q.equalTo('url', decodeURI(k));
731 | }
732 | q.addDescending('createdAt');
733 | q.addDescending('insertedAt');
734 | return q;
735 | } else {
736 | let query = new AV.Query(that.data.commentTabName);
737 | query.containedIn('rid', arguments[1]);
738 | query.addDescending('createdAt');
739 | query.addDescending('insertedAt');
740 | query.include('targetUser');
741 | return query;
742 | }
743 | },
744 | _updateUserInfoInLeanCloud: function () {
745 | // 获得当前登录用户
746 | let that = this;
747 | const user = AV.User.current();
748 | // 调用小程序 API,得到用户信息
749 | wx.getUserInfo({
750 | success: ({
751 | userInfo
752 | }) => {
753 | // 更新当前用户的信息
754 | user.set(userInfo).save().then(user => {
755 | // 成功,此时可在控制台中看到更新后的用户信息
756 | //this.data.login_user_info = user.toJSON();
757 | console.log(user);
758 | }).catch(console.error);
759 | },
760 | fail: function () {
761 | console.log("获取用户信息失败");
762 | }
763 | });
764 | }
765 | } // end of method
766 | })
--------------------------------------------------------------------------------
/miniprogram/component/NewWxComment/NewWxComment.json:
--------------------------------------------------------------------------------
1 | {
2 | "component": true,
3 | "usingComponents": {
4 | "WxLogin": "/component/WxLogin/WxLogin"
5 | }
6 | }
--------------------------------------------------------------------------------
/miniprogram/component/NewWxComment/NewWxComment.wxml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 | 评论交流 {{enableComment?'(点击评论内容可以回复)':''}}
14 |
15 |
16 |
19 |
20 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 | ---我是有底线的---
97 |
98 |
99 |
100 |
101 |
102 |
103 | {{copyRight}}
104 |
105 |
106 |
107 |
108 |
109 |
182 |
183 |
184 |
--------------------------------------------------------------------------------
/miniprogram/component/NewWxComment/NewWxComment.wxs:
--------------------------------------------------------------------------------
1 | /*
2 | * A JavaScript implementation of the RSA Data Security, Inc. MD5 Message
3 | * Digest Algorithm, as defined in RFC 1321.
4 | * Version 2.1 Copyright (C) Paul Johnston 1999 - 2002.
5 | * Other contributors: Greg Holt, Andrew Kepert, Ydnar, Lostinet
6 | * Distributed under the BSD License
7 | * See http://pajhome.org.uk/crypt/md5 for more info.
8 | */
9 |
10 | /*
11 | * Configurable variables. You may need to tweak these to be compatible with
12 | * the server-side, but the defaults work in most cases.
13 | */
14 | var hexcase = 0; /* hex output format. 0 - lowercase; 1 - uppercase */
15 | var b64pad = ""; /* base-64 pad character. "=" for strict RFC compliance */
16 | var chrsz = 8; /* bits per input character. 8 - ASCII; 16 - Unicode */
17 |
18 | /*
19 | * These are the functions you'll usually want to call
20 | * They take string arguments and return either hex or base-64 encoded strings
21 | */
22 | function hex_md5(s) { return binl2hex(core_md5(str2binl(s), s.length * chrsz)); }
23 |
24 | /*
25 | * Perform a simple self-test to see if the VM is working
26 | */
27 | function md5_vm_test() {
28 | return hex_md5("abc") == "900150983cd24fb0d6963f7d28e17f72";
29 | }
30 |
31 | /*
32 | * Calculate the MD5 of an array of little-endian words, and a bit length
33 | */
34 | function core_md5(x, len) {
35 | /* append padding */
36 | x[len >> 5] |= 128 << ((len) % 32);
37 | x[(((len + 64) >>> 9) << 4) + 14] = len;
38 |
39 | var a = 1732584193;
40 | var b = -271733879;
41 | var c = -1732584194;
42 | var d = 271733878;
43 |
44 | for (var i = 0; i < x.length; i += 16) {
45 | var olda = a;
46 | var oldb = b;
47 | var oldc = c;
48 | var oldd = d;
49 |
50 | a = md5_ff(a, b, c, d, x[i + 0], 7, -680876936);
51 | d = md5_ff(d, a, b, c, x[i + 1], 12, -389564586);
52 | c = md5_ff(c, d, a, b, x[i + 2], 17, 606105819);
53 | b = md5_ff(b, c, d, a, x[i + 3], 22, -1044525330);
54 | a = md5_ff(a, b, c, d, x[i + 4], 7, -176418897);
55 | d = md5_ff(d, a, b, c, x[i + 5], 12, 1200080426);
56 | c = md5_ff(c, d, a, b, x[i + 6], 17, -1473231341);
57 | b = md5_ff(b, c, d, a, x[i + 7], 22, -45705983);
58 | a = md5_ff(a, b, c, d, x[i + 8], 7, 1770035416);
59 | d = md5_ff(d, a, b, c, x[i + 9], 12, -1958414417);
60 | c = md5_ff(c, d, a, b, x[i + 10], 17, -42063);
61 | b = md5_ff(b, c, d, a, x[i + 11], 22, -1990404162);
62 | a = md5_ff(a, b, c, d, x[i + 12], 7, 1804603682);
63 | d = md5_ff(d, a, b, c, x[i + 13], 12, -40341101);
64 | c = md5_ff(c, d, a, b, x[i + 14], 17, -1502002290);
65 | b = md5_ff(b, c, d, a, x[i + 15], 22, 1236535329);
66 |
67 | a = md5_gg(a, b, c, d, x[i + 1], 5, -165796510);
68 | d = md5_gg(d, a, b, c, x[i + 6], 9, -1069501632);
69 | c = md5_gg(c, d, a, b, x[i + 11], 14, 643717713);
70 | b = md5_gg(b, c, d, a, x[i + 0], 20, -373897302);
71 | a = md5_gg(a, b, c, d, x[i + 5], 5, -701558691);
72 | d = md5_gg(d, a, b, c, x[i + 10], 9, 38016083);
73 | c = md5_gg(c, d, a, b, x[i + 15], 14, -660478335);
74 | b = md5_gg(b, c, d, a, x[i + 4], 20, -405537848);
75 | a = md5_gg(a, b, c, d, x[i + 9], 5, 568446438);
76 | d = md5_gg(d, a, b, c, x[i + 14], 9, -1019803690);
77 | c = md5_gg(c, d, a, b, x[i + 3], 14, -187363961);
78 | b = md5_gg(b, c, d, a, x[i + 8], 20, 1163531501);
79 | a = md5_gg(a, b, c, d, x[i + 13], 5, -1444681467);
80 | d = md5_gg(d, a, b, c, x[i + 2], 9, -51403784);
81 | c = md5_gg(c, d, a, b, x[i + 7], 14, 1735328473);
82 | b = md5_gg(b, c, d, a, x[i + 12], 20, -1926607734);
83 |
84 | a = md5_hh(a, b, c, d, x[i + 5], 4, -378558);
85 | d = md5_hh(d, a, b, c, x[i + 8], 11, -2022574463);
86 | c = md5_hh(c, d, a, b, x[i + 11], 16, 1839030562);
87 | b = md5_hh(b, c, d, a, x[i + 14], 23, -35309556);
88 | a = md5_hh(a, b, c, d, x[i + 1], 4, -1530992060);
89 | d = md5_hh(d, a, b, c, x[i + 4], 11, 1272893353);
90 | c = md5_hh(c, d, a, b, x[i + 7], 16, -155497632);
91 | b = md5_hh(b, c, d, a, x[i + 10], 23, -1094730640);
92 | a = md5_hh(a, b, c, d, x[i + 13], 4, 681279174);
93 | d = md5_hh(d, a, b, c, x[i + 0], 11, -358537222);
94 | c = md5_hh(c, d, a, b, x[i + 3], 16, -722521979);
95 | b = md5_hh(b, c, d, a, x[i + 6], 23, 76029189);
96 | a = md5_hh(a, b, c, d, x[i + 9], 4, -640364487);
97 | d = md5_hh(d, a, b, c, x[i + 12], 11, -421815835);
98 | c = md5_hh(c, d, a, b, x[i + 15], 16, 530742520);
99 | b = md5_hh(b, c, d, a, x[i + 2], 23, -995338651);
100 |
101 | a = md5_ii(a, b, c, d, x[i + 0], 6, -198630844);
102 | d = md5_ii(d, a, b, c, x[i + 7], 10, 1126891415);
103 | c = md5_ii(c, d, a, b, x[i + 14], 15, -1416354905);
104 | b = md5_ii(b, c, d, a, x[i + 5], 21, -57434055);
105 | a = md5_ii(a, b, c, d, x[i + 12], 6, 1700485571);
106 | d = md5_ii(d, a, b, c, x[i + 3], 10, -1894986606);
107 | c = md5_ii(c, d, a, b, x[i + 10], 15, -1051523);
108 | b = md5_ii(b, c, d, a, x[i + 1], 21, -2054922799);
109 | a = md5_ii(a, b, c, d, x[i + 8], 6, 1873313359);
110 | d = md5_ii(d, a, b, c, x[i + 15], 10, -30611744);
111 | c = md5_ii(c, d, a, b, x[i + 6], 15, -1560198380);
112 | b = md5_ii(b, c, d, a, x[i + 13], 21, 1309151649);
113 | a = md5_ii(a, b, c, d, x[i + 4], 6, -145523070);
114 | d = md5_ii(d, a, b, c, x[i + 11], 10, -1120210379);
115 | c = md5_ii(c, d, a, b, x[i + 2], 15, 718787259);
116 | b = md5_ii(b, c, d, a, x[i + 9], 21, -343485551);
117 |
118 | a = safe_add(a, olda);
119 | b = safe_add(b, oldb);
120 | c = safe_add(c, oldc);
121 | d = safe_add(d, oldd);
122 | }
123 | return [a, b, c, d];
124 |
125 | }
126 |
127 | /*
128 | * These functions implement the four basic operations the algorithm uses.
129 | */
130 | function md5_cmn(q, a, b, x, s, t) {
131 | return safe_add(bit_rol(safe_add(safe_add(a, q), safe_add(x, t)), s), b);
132 | }
133 | function md5_ff(a, b, c, d, x, s, t) {
134 | return md5_cmn((b & c) | ((~b) & d), a, b, x, s, t);
135 | }
136 | function md5_gg(a, b, c, d, x, s, t) {
137 | return md5_cmn((b & d) | (c & (~d)), a, b, x, s, t);
138 | }
139 | function md5_hh(a, b, c, d, x, s, t) {
140 | return md5_cmn(b ^ c ^ d, a, b, x, s, t);
141 | }
142 | function md5_ii(a, b, c, d, x, s, t) {
143 | return md5_cmn(c ^ (b | (~d)), a, b, x, s, t);
144 | }
145 |
146 | /*
147 | * Add integers, wrapping at 2^32. This uses 16-bit operations internally
148 | * to work around bugs in some JS interpreters.
149 | */
150 | function safe_add(x, y) {
151 | var lsw = (x & 65535) + (y & 65535);
152 | var msw = (x >> 16) + (y >> 16) + (lsw >> 16);
153 | return (msw << 16) | (lsw & 65535);
154 | }
155 |
156 | /*
157 | * Bitwise rotate a 32-bit number to the left.
158 | */
159 | function bit_rol(num, cnt) {
160 | return (num << cnt) | (num >>> (32 - cnt));
161 | }
162 |
163 | /*
164 | * Convert a string to an array of little-endian words
165 | * If chrsz is ASCII, characters >255 have their hi-byte silently ignored.
166 | */
167 | function str2binl(str) {
168 | var bin = [];
169 | var mask = (1 << chrsz) - 1;
170 | for (var i = 0; i < str.length * chrsz; i += chrsz)
171 | bin[i >> 5] |= (str.charCodeAt(i / chrsz) & mask) << (i % 32);
172 | return bin;
173 | }
174 |
175 |
176 | /*
177 | * Convert an array of little-endian words to a hex string.
178 | */
179 | function binl2hex(binarray) {
180 | var hex_tab = hexcase ? "0123456789ABCDEF" : "0123456789abcdef";
181 | var str = "";
182 | for (var i = 0; i < binarray.length * 4; i++) {
183 | str += hex_tab.charAt((binarray[i >> 2] >> ((i % 4) * 8 + 4)) & 15) +
184 | hex_tab.charAt((binarray[i >> 2] >> ((i % 4) * 8)) & 15);
185 | }
186 | return str;
187 | }
188 |
189 | module.exports = {
190 | hexMD5: hex_md5
191 | }
--------------------------------------------------------------------------------
/miniprogram/component/NewWxComment/NewWxComment.wxss:
--------------------------------------------------------------------------------
1 | /* component/NewWxComment/NewWxComment.wxss */
2 |
3 | .dark {
4 | background: #000;
5 | color: #fff;
6 | }
7 |
8 | .light {
9 | background: #fff;
10 | background-color: #fff;
11 | color: #484848;
12 | }
13 |
14 | .hide {
15 | display: none;
16 | }
17 |
18 | .show {
19 | display: block;
20 | }
21 |
22 | view {
23 | word-break: break-all;
24 | /* overflow: auto; */
25 | }
26 |
27 | view {
28 | display: block;
29 | }
30 |
31 | .show-hide-view {
32 | margin: 0rpx, 0rpx, 0rpx, 0rpx;
33 | padding: 0rpx, 0rpx, 0rpx, 0rpx;
34 | border: 1rpx;
35 | }
36 |
37 | .content-article-detail {
38 | border-bottom: 1px solid #eee;
39 | margin-top: 40rpx;
40 | margin-bottom: 24px;
41 | }
42 |
43 | .entry-title {
44 | font-size: 48rpx;
45 | line-height: 1.6;
46 | font-weight: bold;
47 | outline: none;
48 | color: #3a4040;
49 | margin-bottom: 24rpx;
50 | }
51 |
52 | .entry-gap-like {
53 | width: 120rpx;
54 | height: 2px;
55 | background-color: #4c4c4c;
56 | margin-bottom: 32rpx;
57 | }
58 |
59 | .entry-gap-zan {
60 | width: 70rpx;
61 | height: 2px;
62 | background-color: #4c4c4c;
63 | margin-bottom: 32rpx;
64 | }
65 |
66 | .entry-summary {
67 | font-size: 32rpx;
68 | line-height: 64rpx;
69 | letter-spacing: 1px;
70 | }
71 |
72 | .entry-summary image {
73 | width: 100% !important;
74 | }
75 |
76 | .entry-date {
77 | font-size: 24rpx;
78 | line-height: 1.6;
79 | color: #959595;
80 | font-weight: normal;
81 | outline: none;
82 | margin-bottom: 30rpx;
83 | border-bottom: 1px solid #eee;
84 | /* border-bottom: 1px solid #ededed; *//* margin-left: 30rpx; */
85 | }
86 |
87 | .entry-date-text {
88 | margin-left: 10rpx;
89 | }
90 |
91 | .entry-icon-text {
92 | margin-left: 10rpx;
93 | }
94 |
95 | .entry-category-text {
96 | margin-left: 20rpx;
97 | }
98 |
99 | /* comment */
100 |
101 | .commentheader {
102 | padding: 20rpx 0;
103 | text-align: left;
104 | font-weight: normal;
105 | font-size: 28rpx;
106 | line-height: 40rpx;
107 | color: #959595;
108 | }
109 |
110 | .commentheader1 {
111 | padding: 5rpx 0;
112 | text-align: left;
113 | font-weight: normal;
114 | font-size: 24rpx;
115 | line-height: 10rpx;
116 | color: red;
117 | }
118 |
119 | .comment {
120 | /* border-bottom: 8px solid #fff; */
121 | /* background-color: #f5f7f7; */
122 | padding: 0 24rpx;
123 | border-radius: 8px;
124 | margin: 8px 0;
125 | }
126 |
127 | .comment-bg {
128 | background-color: #f5f7f7;
129 | }
130 |
131 | .comment-children {
132 | border-top: 1px solid #eee;
133 | margin-left: 40rpx;
134 | }
135 |
136 | .comment-user {
137 | display: flex;
138 | align-items: center;
139 | /* height: 80rpx; */
140 | font-size: 28rpx;
141 | /* line-height: 80rpx; */
142 | font-weight: normal;
143 | outline: none;
144 | color: #959595;
145 | margin: 10rpx 0;
146 | padding-top: 10rpx;
147 | }
148 |
149 | .replay-user {
150 | display: flex;
151 | align-items: center;
152 | /* height: 80rpx; */
153 | font-size: 26rpx;
154 | /* line-height: 80rpx; */
155 | font-weight: normal;
156 | outline: none;
157 | color: #959595;
158 | margin: 10rpx 0;
159 | margin-left: 60rpx;
160 | }
161 |
162 | .comment-user image {
163 | margin-right: 16rpx;
164 | }
165 |
166 | .comment-date {
167 | font-size: 25rpx;
168 | line-height: 1.2;
169 | font-weight: normal;
170 | outline: none;
171 | margin-bottom: 30rpx;
172 | color: #959595;
173 | }
174 |
175 | .comment-response {
176 | color: #4c4c4c;
177 | font-size: 30rpx;
178 | line-height: 1.6rem;
179 | margin-bottom: 50rpx;
180 | }
181 |
182 | .comment-summary {
183 | color: #4c4c4c;
184 | font-size: 28rpx;
185 | line-height: 2rem;
186 | margin-bottom: 10rpx;
187 | margin-left: 60rpx;
188 | }
189 |
190 | .comment-repaly {
191 | color: #757575;
192 | font-size: 30rpx;
193 | line-height: 1.6rem;
194 | margin-bottom: 10rpx;
195 | }
196 |
197 | .comment-post {
198 | color: #757575;
199 | font-size: 30rpx;
200 | line-height: 1.6rem;
201 | margin-bottom: 50rpx;
202 | text-align: center;
203 | display: flex;
204 | flex-direction: row;
205 | }
206 |
207 | .comment-respond {
208 | margin-top: 10rpx;
209 | }
210 |
211 | .comment-reply-title {
212 | font-size: 40rpx;
213 | line-height: 1.5;
214 | color: #21759b;
215 | }
216 |
217 | .comment-fixed {
218 | position: fixed;
219 | bottom: 0;
220 | left: 0;
221 | right: 0;
222 | box-shadow: 0 0 6px rgba(30, 20, 20, 0.1);
223 | z-index: 105;
224 | /*margin-bottom:2rpx; */
225 | }
226 |
227 | .comment-box {
228 | padding: 16rpx 4rpx;
229 | display: flex;
230 | justify-content: center;
231 | }
232 |
233 | .comment-area {
234 | border: 1px solid #ccc;
235 | margin-top: 20rpx;
236 | max-width: 800rpx;
237 | }
238 |
239 | .comment-button {
240 | width: 160rpx;
241 | display: flex !important;
242 | flex-direction: column;
243 | justify-content: center;
244 | margin-right: 22rpx;
245 | border-bottom-left-radius: 0;
246 | border-top-left-radius: 0;
247 | border-top-right-radius: 6px !important;
248 | border-bottom-right-radius: 6px !important;
249 | text-align: center;
250 | padding: 0 2px !important;
251 | font-size: 16px;
252 | height: 70rpx;
253 | /* border: none;
254 | border-radius: 0; */
255 | }
256 |
257 | .comment-button::after {
258 | border: none;
259 | }
260 |
261 | .replay-button {
262 | width: 160rpx;
263 | display: flex !important;
264 | flex-direction: column;
265 | justify-content: center;
266 | margin-right: 0rpx;
267 | text-align: center;
268 | padding: 0px !important;
269 | font-size: 12px;
270 | border-radius: 40rpx;
271 | }
272 |
273 | .replay-button::after {
274 | border: none;
275 | }
276 |
277 | .comment-input {
278 | padding: 2px 3px 2px 10px;
279 | font-size: 16px;
280 | width: 51%;
281 | height: 70rpx;
282 | text-align: left;
283 | /* border: 1px solid #296fd0; */
284 | border-bottom-left-radius: 6px;
285 | border-top-left-radius: 6px;
286 | border-top-right-radius: 0;
287 | border-bottom-right-radius: 0;
288 | }
289 |
290 | .textNoEmpty {
291 | color: red;
292 | }
293 |
294 | .gravatarImg {
295 | /* margin-top: 4px; *//* border-radius: 50%; *//*
296 | opacity: 1;
297 | transform: scale(1);
298 | perspective-origin: top center;
299 | transition: all ease-in-out 0.3s;
300 | */
301 | height: 48rpx;
302 | width: 48rpx;
303 | }
304 |
305 | .more-comment {
306 | font-size: 30rpx;
307 | line-height: 1.8rem;
308 | margin-bottom: 50rpx;
309 | text-align: center;
310 | margin-top: 20rpx;
311 | }
312 |
313 | .img-plus {
314 | width: 48rpx !important;
315 | height: 48rpx !important;
316 | margin-right: 10px;
317 | margin-top: 10rpx;
318 | }
319 |
320 | /* comment end */
321 |
322 | .relatedPost {
323 | position: relative;
324 | text-align: left;
325 | margin: 32rpx 0 60rpx;
326 | /* border-bottom: 1px solid #eee; */
327 | }
328 |
329 | .relatedTitle {
330 | text-align: left;
331 | font-weight: normal;
332 | line-height: 40rpx;
333 | margin-top: 20rpx;
334 | margin-bottom: 20rpx;
335 | font-size: 32rpx;
336 | color: #4c4c4c !important;
337 | }
338 |
339 | .relatedText {
340 | text-align: left;
341 | font-weight: normal;
342 | font-size: 28rpx;
343 | line-height: 60rpx;
344 | color: #4c4c4c !important;
345 | }
346 |
347 | .likePost {
348 | position: relative;
349 | text-align: left;
350 | margin-top: 30rpx;
351 | /* border-bottom: 1px solid #ededed; */
352 | margin-bottom: 60rpx;
353 | }
354 |
355 | .likeTitle {
356 | text-align: left;
357 | font-weight: normal;
358 | /* line-height: 30rpx; */
359 | margin-top: 20rpx;
360 | margin-bottom: 20rpx;
361 | /* margin-left: 280rpx; */
362 | font-size: 28rpx;
363 | color: #959595 !important;
364 | vertical-align: middle;
365 | /* width: 140rpx;
366 | height: 70rpx; *//* border-radius: 35rpx; *//* border: 1rpx solid #c4c4c4; */
367 | position: absolute;
368 | top: 120rpx;
369 | left: 0;
370 | }
371 |
372 | .likeTitle-img {
373 | position: absolute;
374 | top: 120rpx;
375 | left: 160rpx;
376 | }
377 |
378 | .likeText {
379 | text-align: left;
380 | font-weight: normal;
381 | font-size: 26rpx;
382 | line-height: 30rpx;
383 | color: #0000fe !important;
384 | margin: 140rpx 0 20rpx;
385 | }
386 |
387 | .img-like {
388 | width: 50rpx;
389 | height: 50rpx;
390 | display: inline-block;
391 | text-align: center;
392 | margin-right: 20rpx;
393 | margin-top: 8rpx;
394 | }
395 |
396 | .gravatarLikeImg {
397 | margin-top: 4px;
398 | /*border-radius: 50%;
399 |
400 | opacity: 1;
401 | transform: scale(1);
402 | perspective-origin: top center;
403 | transition: all ease-in-out 0.3s;
404 | */
405 | height: 48rpx;
406 | width: 48rpx;
407 | margin-right: 20rpx;
408 | }
409 |
410 | .relatedNavigator {
411 | color: #21759b !important;
412 | }
413 |
414 | .sharedetail {
415 | position: relative;
416 | text-align: center;
417 | margin-top: 30rpx;
418 | }
419 |
420 | .share-button {
421 | opacity: 0;
422 | position: absolute;
423 | width: 100%;
424 | height: 100%;
425 | margin: 0;
426 | padding: 0;
427 | top: 0;
428 | left: 0;
429 | }
430 |
431 | .share-title {
432 | color: #333;
433 | font-size: 30rpx;
434 | padding-top: 20rpx;
435 | }
436 |
437 | .copy-button {
438 | color: #296fd0 !important;
439 | }
440 |
441 | .showMessage {
442 | text-align: center;
443 | font-weight: normal;
444 | font-size: 26rpx;
445 | line-height: 40rpx;
446 | color: sandybrown;
447 | margin-top: 20rpx;
448 | margin-bottom: 20rpx;
449 | }
450 |
451 | .no-more {
452 | color: #757575;
453 | font-size: 30rpx;
454 | line-height: 1.8rem;
455 | margin-bottom: 15rpx;
456 | text-align: center;
457 | margin-top: 15rpx;
458 | }
459 |
460 | .ditail-copyright {
461 | font-size: 26rpx;
462 | line-height: 1.2;
463 | font-weight: normal;
464 | text-align: center;
465 | color: #999;
466 | margin-top: 20rpx;
467 | /* margin-bottom: 130rpx; */
468 | }
469 |
470 | .wxParse-a {
471 | color: #21759b;
472 | }
473 |
474 | .wxParse-code {
475 | padding: 2px 4px !important;
476 | font-size: 90% !important;
477 | border-radius: 3px !important;
478 | color: #eb2226 !important;
479 | background-color: #f9f2f4 !important;
480 | font-family: Source Code Pro, Consolas, Menlo, Monaco, Courier New, monospace !important;
481 | }
482 |
483 | /* menu-box */
484 |
485 | .menu-box {
486 | position: relative;
487 | height: 90px;
488 | padding: 0px 0 8 0;
489 | box-sizing: border-box;
490 | margin-bottom: -90px;
491 | }
492 |
493 | .menuBackground {
494 | position: fixed;
495 | top: 0;
496 | left: 0;
497 | bottom: 0;
498 | right: 0;
499 | /* background-color: transparent; */
500 | z-index: 105;
501 | }
502 |
503 | .iconList {
504 | text-align: center;
505 | border-top: 1px solid #eee;
506 | }
507 |
508 | .iconLine {
509 | margin-top: 20rpx;
510 | }
511 |
512 | .iconLine text {
513 | font-size: 24rpx;
514 | text-align: center;
515 | color: #959595;
516 | }
517 |
518 | .iconLine view {
519 | text-align: center;
520 | }
521 |
522 | .text-center {
523 | text-align: center;
524 | }
525 |
526 | .img-menu {
527 | width: 50rpx;
528 | height: 50rpx;
529 | display: inline-block;
530 | text-align: center;
531 | }
532 |
533 | .img-menu2 {
534 | width: 60rpx;
535 | height: 60rpx;
536 | display: inline-block;
537 | text-align: center;
538 | }
539 |
540 | .emoji-move-in {
541 | -webkit-animation: emoji-move-in 0.3s forwards;
542 | animation: emoji-move-in 0.3s forwards;
543 | }
544 |
545 | .emoji-move-out {
546 | -webkit-animation: emoji-move-out 0.3s forwards;
547 | animation: emoji-move-out 0.3s forwards;
548 | }
549 |
550 | .no-emoji-move {
551 | -webkit-animation: none;
552 | animation: none;
553 | }
554 |
555 | @-webkit-keyframes emoji-move-in {
556 | 0% {
557 | margin-bottom: -90px;
558 | }
559 |
560 | 100% {
561 | margin-bottom: 0;
562 | }
563 | }
564 |
565 | @keyframes emoji-move-in {
566 | 0% {
567 | margin-bottom: -90px;
568 | }
569 |
570 | 100% {
571 | margin-bottom: 0;
572 | }
573 | }
574 |
575 | @-webkit-keyframes emoji-move-out {
576 | 0% {
577 | margin-bottom: 0;
578 | }
579 |
580 | 100% {
581 | margin-bottom: -90px;
582 | }
583 | }
584 |
585 | @keyframes emoji-move-out {
586 | 0% {
587 | margin-bottom: 0;
588 | }
589 |
590 | 100% {
591 | margin-bottom: -90px;
592 | }
593 | }
594 |
595 | /* end menu-box */
596 |
597 | .pagination {
598 | font-weight: normal;
599 | font-size: 28rpx;
600 | line-height: 60rpx;
601 | color: #4c4c4c !important;
602 | border-bottom: 1px solid #eee;
603 | }
604 |
605 | .nav-previous {
606 | float: left;
607 | width: 80%;
608 | }
609 |
610 | .nav-next {
611 | float: right;
612 | text-align: right;
613 | width: 80%;
614 | }
615 |
616 | .canvas-box {
617 | position: fixed;
618 | top: 999999rpx;
619 | left: 0;
620 | }
621 |
622 | /* 进度条 */
623 |
624 | .sk-three-bounce {
625 | margin: 20rpx auto;
626 | width: 200rpx;
627 | text-align: center;
628 | }
629 |
630 | .sk-three-bounce .sk-child {
631 | width: 30rpx;
632 | height: 30rpx;
633 | background-color: #118fff;
634 | border-radius: 100%;
635 | display: inline-block;
636 | -webkit-animation: sk-three-bounce 1.4s ease-in-out 0s infinite both;
637 | animation: sk-three-bounce 1.4s ease-in-out 0s infinite both;
638 | }
639 |
640 | .sk-three-bounce .sk-bounce1 {
641 | -webkit-animation-delay: -0.32s;
642 | animation-delay: -0.32s;
643 | }
644 |
645 | .sk-three-bounce .sk-bounce2 {
646 | -webkit-animation-delay: -0.16s;
647 | animation-delay: -0.16s;
648 | }
649 |
650 | @-webkit-keyframes sk-three-bounce {
651 | 0%, 80%, 100% {
652 | -webkit-transform: scale(0);
653 | transform: scale(0);
654 | }
655 |
656 | 40% {
657 | -webkit-transform: scale(1);
658 | transform: scale(1);
659 | }
660 | }
661 |
662 | @keyframes sk-three-bounce {
663 | 0%, 80%, 100% {
664 | -webkit-transform: scale(0);
665 | transform: scale(0);
666 | }
667 |
668 | 40% {
669 | -webkit-transform: scale(1);
670 | transform: scale(1);
671 | }
672 | }
673 |
674 | /* more */
675 |
676 | .loadingmore {
677 | margin-top: 24rpx;
678 | text-align: center;
679 | margin-bottom: 24rpx;
680 | }
681 |
682 | .more-button {
683 | font-size: 0.785714286rem;
684 | font-weight: normal;
685 | color: #959595;
686 | background-color: #eee;
687 | background-repeat: repeat-x;
688 | margin-top: 30rpx;
689 | width: 240rpx;
690 | border-radius: 300rpx;
691 | }
692 |
693 | .more-button::after {
694 | border: none;
695 | }
696 |
697 | .no-more {
698 | color: #757575;
699 | font-size: 30rpx;
700 | line-height: 1.8rem;
701 | margin-bottom: 15rpx;
702 | text-align: center;
703 | margin-top: 15rpx;
704 | }
705 |
706 | /* more end */
707 |
708 | /*common list for index list page */
709 |
710 | .common-list {
711 | margin-bottom: 24rpx;
712 | }
713 |
714 | .common-list .list-item {
715 | position: relative;
716 | border-bottom: 1px solid #eee;
717 | padding: 24rpx;
718 | min-height: 150rpx;
719 | overflow: hidden;
720 | }
721 |
722 | .common-list .list-item.has-img image.cover {
723 | position: absolute;
724 | left: 0rpx;
725 | top: 24rpx;
726 | width: 200rpx;
727 | height: 150rpx;
728 | border-radius: 8rpx;
729 | }
730 |
731 | .common-list .list-item.has-img .content-title {
732 | margin-left: 200rpx;
733 | height: 80rpx;
734 | margin-bottom: 20rpx;
735 | }
736 |
737 | .common-list .list-item.has-img .content-title text {
738 | text-overflow: -o-ellipsis-lastline;
739 | overflow: hidden;
740 | text-overflow: ellipsis;
741 | display: -webkit-box;
742 | -webkit-line-clamp: 2;
743 | -webkit-box-orient: vertical;
744 | font-size: 30rpx;
745 | line-height: 1.4;
746 | font-weight: 400;
747 | color: #3a4040;
748 | }
749 |
750 | .common-list .list-item.has-img .content-date {
751 | margin-left: 200rpx;
752 | }
753 |
754 | .common-list .list-item.has-img .content-date image {
755 | width: 24rpx;
756 | height: 24rpx;
757 | margin-right: 10rpx;
758 | vertical-align: middle;
759 | }
760 |
761 | .common-list .list-item .content-date text {
762 | color: #959595;
763 | margin-right: 32rpx;
764 | font-size: 20rpx;
765 | line-height: 1.2;
766 | font-weight: normal;
767 | }
768 |
769 | /*common list end */
770 |
771 | .showerror {
772 | text-align: center;
773 | font-weight: normal;
774 | font-size: 30rpx;
775 | line-height: 40rpx;
776 | color: #757575;
777 | margin-top: 100rpx;
778 | }
779 |
780 | .errortext {
781 | margin-top: 50rpx;
782 | table-layout: center;
783 | }
784 |
785 | .copyright {
786 | font-size: 26rpx;
787 | line-height: 1.6;
788 | font-weight: 400;
789 | text-align: center;
790 | color: #c4c4c4;
791 | margin-top: 48rpx;
792 | padding-bottom: 80rpx;
793 | }
794 |
795 | .common-gap {
796 | width: 100%;
797 | height: 24rpx;
798 | background-color: #f5f7f7;
799 | }
800 |
--------------------------------------------------------------------------------
/miniprogram/component/NewWxComment/images/about.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yicm/NewWxComment/7b0f3e35aa8f689adef3e6de7f45c343fcf3d307/miniprogram/component/NewWxComment/images/about.png
--------------------------------------------------------------------------------
/miniprogram/component/NewWxComment/images/about_active.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yicm/NewWxComment/7b0f3e35aa8f689adef3e6de7f45c343fcf3d307/miniprogram/component/NewWxComment/images/about_active.png
--------------------------------------------------------------------------------
/miniprogram/component/NewWxComment/images/copy_link.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yicm/NewWxComment/7b0f3e35aa8f689adef3e6de7f45c343fcf3d307/miniprogram/component/NewWxComment/images/copy_link.png
--------------------------------------------------------------------------------
/miniprogram/component/NewWxComment/images/copy_link_active.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yicm/NewWxComment/7b0f3e35aa8f689adef3e6de7f45c343fcf3d307/miniprogram/component/NewWxComment/images/copy_link_active.png
--------------------------------------------------------------------------------
/miniprogram/component/NewWxComment/images/home.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yicm/NewWxComment/7b0f3e35aa8f689adef3e6de7f45c343fcf3d307/miniprogram/component/NewWxComment/images/home.png
--------------------------------------------------------------------------------
/miniprogram/component/NewWxComment/images/home_active.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yicm/NewWxComment/7b0f3e35aa8f689adef3e6de7f45c343fcf3d307/miniprogram/component/NewWxComment/images/home_active.png
--------------------------------------------------------------------------------
/miniprogram/component/NewWxComment/images/like.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yicm/NewWxComment/7b0f3e35aa8f689adef3e6de7f45c343fcf3d307/miniprogram/component/NewWxComment/images/like.png
--------------------------------------------------------------------------------
/miniprogram/component/NewWxComment/images/like_active.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yicm/NewWxComment/7b0f3e35aa8f689adef3e6de7f45c343fcf3d307/miniprogram/component/NewWxComment/images/like_active.png
--------------------------------------------------------------------------------
/miniprogram/component/NewWxComment/images/more.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yicm/NewWxComment/7b0f3e35aa8f689adef3e6de7f45c343fcf3d307/miniprogram/component/NewWxComment/images/more.png
--------------------------------------------------------------------------------
/miniprogram/component/NewWxComment/images/more_active.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yicm/NewWxComment/7b0f3e35aa8f689adef3e6de7f45c343fcf3d307/miniprogram/component/NewWxComment/images/more_active.png
--------------------------------------------------------------------------------
/miniprogram/component/NewWxComment/images/poster.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yicm/NewWxComment/7b0f3e35aa8f689adef3e6de7f45c343fcf3d307/miniprogram/component/NewWxComment/images/poster.png
--------------------------------------------------------------------------------
/miniprogram/component/NewWxComment/images/poster_active.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yicm/NewWxComment/7b0f3e35aa8f689adef3e6de7f45c343fcf3d307/miniprogram/component/NewWxComment/images/poster_active.png
--------------------------------------------------------------------------------
/miniprogram/component/NewWxComment/images/reward.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yicm/NewWxComment/7b0f3e35aa8f689adef3e6de7f45c343fcf3d307/miniprogram/component/NewWxComment/images/reward.png
--------------------------------------------------------------------------------
/miniprogram/component/NewWxComment/images/reward_active.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yicm/NewWxComment/7b0f3e35aa8f689adef3e6de7f45c343fcf3d307/miniprogram/component/NewWxComment/images/reward_active.png
--------------------------------------------------------------------------------
/miniprogram/component/NewWxComment/images/share.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yicm/NewWxComment/7b0f3e35aa8f689adef3e6de7f45c343fcf3d307/miniprogram/component/NewWxComment/images/share.png
--------------------------------------------------------------------------------
/miniprogram/component/NewWxComment/images/share_active.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yicm/NewWxComment/7b0f3e35aa8f689adef3e6de7f45c343fcf3d307/miniprogram/component/NewWxComment/images/share_active.png
--------------------------------------------------------------------------------
/miniprogram/component/WxLogin/WxLogin.js:
--------------------------------------------------------------------------------
1 | // component/WxLogin/WxLogin.js
2 | Component({
3 | /**
4 | * 组件的属性列表
5 | */
6 | properties: {
7 | showModal: {
8 | type: Boolean,
9 | value: false,
10 | observer(newval, oldval) {
11 | var that = this;
12 | console.log(newval)
13 | console.log(oldval)
14 | that.setData({
15 | showModal: newval
16 | })
17 | }
18 | }
19 | },
20 |
21 | /**
22 | * 组件的初始数据
23 | */
24 | data: {
25 | showModal: false,
26 | },
27 |
28 | /**
29 | * 组件的方法列表
30 | */
31 | methods: {
32 | onGetUserInfo: function(e) {
33 | var that = this;
34 | if (e.detail.userInfo) {
35 | // 点击了确认按钮
36 | that.hideModal();
37 | }
38 | },
39 | hideModal: function () {
40 | var that = this;
41 | that.setData({
42 | showModal: false
43 | });
44 | },
45 | }
46 | })
47 |
--------------------------------------------------------------------------------
/miniprogram/component/WxLogin/WxLogin.json:
--------------------------------------------------------------------------------
1 | {
2 | "component": true,
3 | "usingComponents": {}
4 | }
--------------------------------------------------------------------------------
/miniprogram/component/WxLogin/WxLogin.wxml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/miniprogram/component/WxLogin/WxLogin.wxss:
--------------------------------------------------------------------------------
1 | /* component/WxLogin/WxLogin.wxss */
2 | .modal-mask {
3 | width: 100%;
4 | height: 100%;
5 | position: fixed;
6 | top: 0;
7 | left: 0;
8 | background: #484848;
9 | opacity: 0.5;
10 | overflow: hidden;
11 | z-index: 9000;
12 | color: rgba(248, 246, 246, 0.76);
13 | align-items:center;
14 | }
15 |
16 | .modal-content {
17 | position: fixed;
18 | top: 45%;
19 | left: 0;
20 | z-index: 9500;
21 | width: 60%;
22 | height: 10%;
23 | overflow: hidden;
24 | background:white;
25 | /*top/bottom , left/right*/
26 | margin: 0rpx 20%;
27 | border-radius: 16rpx;
28 | align-items:center;
29 | }
30 |
31 | .cell-content {
32 | display: flex;
33 | flex-direction: row;
34 | justify-content: space-between;
35 | align-items: center;
36 | width: 100%;
37 | height: 100%;
38 | }
39 |
40 | .avatar {
41 | margin: 0rpx, 0rpx;
42 | width: 40%;
43 | height: 100%;
44 | }
45 |
46 | .auth-button {
47 | line-height: 120rpx;
48 | margin: 0rpx, 0rpx;
49 | width: 60%;
50 | height: 100%;
51 | text-align: center;
52 | }
--------------------------------------------------------------------------------
/miniprogram/component/WxLogin/images/login_active.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yicm/NewWxComment/7b0f3e35aa8f689adef3e6de7f45c343fcf3d307/miniprogram/component/WxLogin/images/login_active.png
--------------------------------------------------------------------------------
/miniprogram/libs/leancloud/rest_api_leancloud.js:
--------------------------------------------------------------------------------
1 | /*
2 | Ref : https://leancloud.cn/docs/rest_api.html
3 | */
4 | const LeanCloud_URL_PREFIX = 'https://api.leancloud.cn/1.1/';
5 | exports.LeanCloud_APP_ID = 'HRYpYqLTygyfRlsN8I3KEhkw-gzGzoHsz';
6 | exports.LeanCloud_APP_KEY = '5two7AvBo3gjnH3hpYSyBW35';
7 |
8 | //---------------------------------
9 | // Request
10 | //---------------------------------
11 | module.exports.showFail = function(content) {
12 | wx.showToast({
13 | title: content + '//(ㄒoㄒ)/',
14 | icon: 'none',
15 | duration: 3000
16 | })
17 | }
18 |
19 | var request = exports.request = function (options) {
20 | wx.showLoading({
21 | title: '加载中',
22 | });
23 | wx.request({
24 | url: LeanCloud_URL_PREFIX + options.url,
25 | data: options.data,
26 | header: {
27 | 'X-LC-Id': exports.LeanCloud_APP_ID,
28 | 'X-LC-Key': exports.LeanCloud_APP_KEY,
29 | 'content-type': 'application/json; charset=utf-8'
30 | },
31 | method: options.method || 'GET',
32 | success: function (res) {
33 | options.success && options.success(res.data);
34 | wx.hideLoading();
35 | },
36 | fail: function (error) {
37 | console.log(error);
38 | this.showFail('调用失败');
39 | wx.hideLoading();
40 | options.fail && options.fail(error);
41 | },
42 | complete: function () {
43 | wx.hideLoading();
44 | }
45 | });
46 | };
--------------------------------------------------------------------------------
/miniprogram/libs/scripts/common.js:
--------------------------------------------------------------------------------
1 | const timeAgoWithTimeStr = (dateString) => {
2 | // ios: 2018/06/02 11:11:11
3 | // android: 2018-06-02 11:11:11 & 2018/06/02 11:11:11
4 | var date_time_arr = dateString.split(' ');
5 | var ios_date_arr = date_time_arr[0].split('-');
6 | var ios_date_str = ios_date_arr[0] + '/' + ios_date_arr[1] + '/' + ios_date_arr[2];
7 | var ios_datetime_str = ios_date_str + ' ' + date_time_arr[1];
8 |
9 | var newDateString = dateString;
10 | newDateString = ios_datetime_str;
11 |
12 | var date = new Date(newDateString)
13 |
14 | try {
15 | var oldTime = date.getTime();
16 | var currTime = new Date().getTime();
17 | var diffValue = currTime - oldTime;
18 |
19 | var days = Math.floor(diffValue / (24 * 3600 * 1000));
20 |
21 | if (days === 0) {
22 | // 计算相差小时数
23 | var leave1 = diffValue % (24 * 3600 * 1000); // 计算天数后剩余的毫秒数
24 | var hours = Math.floor(leave1 / (3600 * 1000));
25 | if (hours === 0) {
26 | // 计算相差分钟数
27 | var leave2 = leave1 % (3600 * 1000); // 计算小时数后剩余的毫秒数
28 | var minutes = Math.floor(leave2 / (60 * 1000));
29 | if (minutes === 0) {
30 | // 计算相差秒数
31 | var leave3 = leave2 % (60 * 1000); // 计算分钟数后剩余的毫秒数
32 | var seconds = Math.round(leave3 / 1000);
33 | return seconds + ' 秒前';
34 | }
35 | return minutes + ' 分钟前';
36 | }
37 | return hours + ' 小时前';
38 | }
39 | if (days < 0) return '刚刚';
40 |
41 | if (days < 3) {
42 | return days + ' 天前';
43 | } else {
44 | return dateString
45 | }
46 | } catch (error) {
47 | console.log(error)
48 | }
49 | }
50 |
51 | function getTime() {
52 | // 获取当前时间戳
53 | var timestamp = Date.parse(new Date());
54 | var n = timestamp;
55 | var date = new Date(n);
56 | // 年
57 | var Y = date.getFullYear();
58 | // 月
59 | var M = (date.getMonth() + 1 < 10 ? '0' + (date.getMonth() + 1) : date.getMonth() + 1);
60 | // 日
61 | var D = date.getDate() < 10 ? '0' + date.getDate() : date.getDate();
62 | // 时
63 | var h = date.getHours();
64 | // 分
65 | var m = date.getMinutes();
66 | // 秒
67 | var s = date.getSeconds();
68 | return Y + '-' + M + '-' + D + ' ' + h + ":" + m + ":" + s;
69 | }
70 |
71 | module.exports = {
72 | timeAgoWithTimeStr: timeAgoWithTimeStr,
73 | getTime: getTime
74 | }
75 |
--------------------------------------------------------------------------------
/miniprogram/pages/index/index.js:
--------------------------------------------------------------------------------
1 | //index.js
2 | //获取应用实例
3 | const app = getApp()
4 |
5 | Page({
6 | data: {
7 | motto: 'Hello World',
8 | userInfo: {},
9 | hasUserInfo: false,
10 | canIUse: wx.canIUse('button.open-type.getUserInfo')
11 | },
12 | //事件处理函数
13 | bindViewTap: function() {
14 | wx.navigateTo({
15 | url: '../logs/logs'
16 | })
17 | },
18 | onLoad: function() {
19 | if (app.globalData.userInfo) {
20 | this.setData({
21 | userInfo: app.globalData.userInfo,
22 | hasUserInfo: true
23 | })
24 | } else if (this.data.canIUse) {
25 | // 由于 getUserInfo 是网络请求,可能会在 Page.onLoad 之后才返回
26 | // 所以此处加入 callback 以防止这种情况
27 | app.userInfoReadyCallback = res => {
28 | this.setData({
29 | userInfo: res.userInfo,
30 | hasUserInfo: true
31 | })
32 | }
33 | } else {
34 | // 在没有 open-type=getUserInfo 版本的兼容处理
35 | wx.getUserInfo({
36 | success: res => {
37 | app.globalData.userInfo = res.userInfo
38 | this.setData({
39 | userInfo: res.userInfo,
40 | hasUserInfo: true
41 | })
42 | }
43 | })
44 | }
45 | },
46 | getUserInfo: function(e) {
47 | console.log(e)
48 | app.globalData.userInfo = e.detail.userInfo
49 | this.setData({
50 | userInfo: e.detail.userInfo,
51 | hasUserInfo: true
52 | })
53 | },
54 | onReachBottom: function() {
55 | let newWxComment = this.selectComponent('#NewWxComment');
56 | newWxComment.onReachBottom();
57 | }
58 | })
--------------------------------------------------------------------------------
/miniprogram/pages/index/index.json:
--------------------------------------------------------------------------------
1 | {
2 | "navigationBarTitleText": "主页",
3 | "enablePullDownRefresh": false,
4 | "usingComponents": {
5 | "NewWxComment": "/component/NewWxComment/NewWxComment"
6 | }
7 | }
--------------------------------------------------------------------------------
/miniprogram/pages/index/index.wxml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | 本教程全面介绍 JavaScript 核心语法,从最简单的讲起,循序渐进、由浅入深,力求清晰易懂。所有章节都带有大量的代码实例,便于理解和模仿,可以用到实际项目中,即学即用。
5 |
6 | 本教程适合初学者当作 JavaScript 语言入门教程,也适合当作日常使用的参考手册。
7 |
8 | 什么是 JavaScript 语言?
9 | JavaScript 是一种轻量级的脚本语言。所谓“脚本语言”(script language),指的是它不具备开发操作系统的能力,而是只用来编写控制其他大型应用程序(比如浏览器)的“脚本”。
10 |
11 | JavaScript 也是一种嵌入式(embedded)语言。它本身提供的核心语法不算很多,只能用来做一些数学和逻辑运算。JavaScript 本身不提供任何与 I/O(输入/输出)相关的 API,都要靠宿主环境(host)提供,所以 JavaScript 只合适嵌入更大型的应用程序环境,去调用宿主环境提供的底层 API。
12 |
13 | 目前,已经嵌入 JavaScript 的宿主环境有多种,最常见的环境就是浏览器,另外还有服务器环境,也就是 Node 项目。
14 |
15 | 从语法角度看,JavaScript 语言是一种“对象模型”语言。各种宿主环境通过这个模型,描述自己的功能和操作接口,从而通过 JavaScript 控制这些功能。但是,JavaScript 并不是纯粹的“面向对象语言”,还支持其他编程范式(比如函数式编程)。这导致几乎任何一个问题,JavaScript 都有多种解决方法。阅读本书的过程中,你会诧异于 JavaScript 语法的灵活性。
16 |
17 | JavaScript 的核心语法部分相当精简,只包括两个部分:基本的语法构造(比如操作符、控制结构、语句)和标准库(就是一系列具有各种功能的对象比如Array、Date、Math等)。除此之外,各种宿主环境提供额外的 API(即只能在该环境使用的接口),以便 JavaScript 调用。以浏览器为例,它提供的额外 API 可以分成三大类。
18 |
19 |
20 |
--------------------------------------------------------------------------------
/miniprogram/pages/index/index.wxss:
--------------------------------------------------------------------------------
1 | /**index.wxss**/
2 | .userinfo {
3 | display: flex;
4 | flex-direction: column;
5 | align-items: center;
6 | }
7 |
8 | .userinfo-avatar {
9 | width: 128rpx;
10 | height: 128rpx;
11 | margin: 20rpx;
12 | border-radius: 50%;
13 | }
14 |
15 | .userinfo-nickname {
16 | color: #aaa;
17 | }
18 |
19 | .usermotto {
20 | margin-top: 200px;
21 | }
--------------------------------------------------------------------------------
/miniprogram/pages/logs/logs.js:
--------------------------------------------------------------------------------
1 | //logs.js
2 | const util = require('../../utils/util.js')
3 |
4 | Page({
5 | data: {
6 | logs: []
7 | },
8 | onLoad: function () {
9 | this.setData({
10 | logs: (wx.getStorageSync('logs') || []).map(log => {
11 | return util.formatTime(new Date(log))
12 | })
13 | })
14 | }
15 | })
16 |
--------------------------------------------------------------------------------
/miniprogram/pages/logs/logs.json:
--------------------------------------------------------------------------------
1 | {
2 | "navigationBarTitleText": "查看启动日志",
3 | "usingComponents": {}
4 | }
--------------------------------------------------------------------------------
/miniprogram/pages/logs/logs.wxml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | {{index + 1}}. {{log}}
5 |
6 |
7 |
--------------------------------------------------------------------------------
/miniprogram/pages/logs/logs.wxss:
--------------------------------------------------------------------------------
1 | .log-list {
2 | display: flex;
3 | flex-direction: column;
4 | padding: 40rpx;
5 | }
6 | .log-item {
7 | margin: 10rpx;
8 | }
9 |
--------------------------------------------------------------------------------
/miniprogram/sitemap.json:
--------------------------------------------------------------------------------
1 | {
2 | "desc": "关于本文件的更多信息,请参考文档 https://developers.weixin.qq.com/miniprogram/dev/framework/sitemap.html",
3 | "rules": [{
4 | "action": "allow",
5 | "page": "*"
6 | }]
7 | }
--------------------------------------------------------------------------------
/miniprogram/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 |
--------------------------------------------------------------------------------
/project.config.json:
--------------------------------------------------------------------------------
1 | {
2 | "description": "项目配置文件",
3 | "miniprogramRoot": "miniprogram/",
4 | "packOptions": {
5 | "ignore": []
6 | },
7 | "setting": {
8 | "urlCheck": false,
9 | "es6": false,
10 | "enhance": false,
11 | "postcss": true,
12 | "minified": true,
13 | "newFeature": true,
14 | "coverView": true,
15 | "autoAudits": false,
16 | "checkInvalidKey": true,
17 | "checkSiteMap": true,
18 | "uploadWithSourceMap": true,
19 | "babelSetting": {
20 | "ignore": [],
21 | "disablePlugins": [],
22 | "outputPath": ""
23 | }
24 | },
25 | "compileType": "miniprogram",
26 | "libVersion": "2.8.2",
27 | "appid": "wx40b8ecd087d22fd1",
28 | "projectname": "NewWxComment",
29 | "debugOptions": {
30 | "hidedInDevtools": []
31 | },
32 | "isGameTourist": false,
33 | "simulatorType": "wechat",
34 | "simulatorPluginLibVersion": {},
35 | "condition": {
36 | "search": {
37 | "current": -1,
38 | "list": []
39 | },
40 | "conversation": {
41 | "current": -1,
42 | "list": []
43 | },
44 | "game": {
45 | "currentL": -1,
46 | "list": []
47 | },
48 | "miniprogram": {
49 | "current": -1,
50 | "list": []
51 | }
52 | }
53 | }
--------------------------------------------------------------------------------
/screenshots/NewWxComment.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yicm/NewWxComment/7b0f3e35aa8f689adef3e6de7f45c343fcf3d307/screenshots/NewWxComment.png
--------------------------------------------------------------------------------
/screenshots/Xiaobaiai.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yicm/NewWxComment/7b0f3e35aa8f689adef3e6de7f45c343fcf3d307/screenshots/Xiaobaiai.jpg
--------------------------------------------------------------------------------