├── libs ├── leancloud │ ├── .gitignore │ └── av-weapp-min.js └── scripts │ └── common.js ├── component └── WxComment │ ├── WxComment.json │ ├── images │ ├── zan.png │ ├── views.png │ ├── coffee.png │ ├── comment.png │ └── zan_self.png │ ├── WxComment.wxss │ ├── WxComment.wxml │ └── WxComment.js ├── screenshot ├── admin.png ├── xiaobaiai.jpg └── screenshot.png └── README.md /libs/leancloud/.gitignore: -------------------------------------------------------------------------------- 1 | rest_api_leancloud.js 2 | -------------------------------------------------------------------------------- /component/WxComment/WxComment.json: -------------------------------------------------------------------------------- 1 | { 2 | "component": true 3 | } -------------------------------------------------------------------------------- /screenshot/admin.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yicm/WxComment/HEAD/screenshot/admin.png -------------------------------------------------------------------------------- /screenshot/xiaobaiai.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yicm/WxComment/HEAD/screenshot/xiaobaiai.jpg -------------------------------------------------------------------------------- /screenshot/screenshot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yicm/WxComment/HEAD/screenshot/screenshot.png -------------------------------------------------------------------------------- /component/WxComment/images/zan.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yicm/WxComment/HEAD/component/WxComment/images/zan.png -------------------------------------------------------------------------------- /component/WxComment/images/views.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yicm/WxComment/HEAD/component/WxComment/images/views.png -------------------------------------------------------------------------------- /component/WxComment/images/coffee.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yicm/WxComment/HEAD/component/WxComment/images/coffee.png -------------------------------------------------------------------------------- /component/WxComment/images/comment.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yicm/WxComment/HEAD/component/WxComment/images/comment.png -------------------------------------------------------------------------------- /component/WxComment/images/zan_self.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yicm/WxComment/HEAD/component/WxComment/images/zan_self.png -------------------------------------------------------------------------------- /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 | } -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ## 已开发新版 NewWxComment ,详见 https://github.com/yicm/NewWxComment ## 2 | 3 | 4 | # WxComment 5 | 6 | `WxComment`[https://github.com/yicm/WxComment](https://github.com/yicm/WxComment)是一个微信小程序的评论插件,结合BaaS提供商[LeanCloud](https://leancloud.cn/),无需其他另外的个人或者云服务器,就可以免费使用。解决了需要个人去注册域名、备案、购买云服务器的繁杂问题。 7 | 8 | 9 | # 特色 10 | 11 | - 独立插件,独立放入小程序项目即可使用 12 | - 友好的UI界面和交互界面 13 | - 与微信用户信息绑定,显示微信用户头像和昵称 14 | - 支持插件内容修改,包括按钮文字,评论提示,评论字数最低限制等属性 15 | - 支持长按删除评论操作 16 | - 支持评论点赞功能 17 | - 支持评论回复功能,即子评论 18 | - 子评论支持点赞功能 19 | - 支持emoji表情显示😉 20 | - 支持文章阅读量统计功能 21 | - 支持light/dark两种样式设置 22 | - 支持点击头像关注用户功能 23 | - 对发布高质量文章的用户关注(见微信小程序`小白AI`) 24 | - 关注后,可通过在WxComment组件外对用户详细资料查看等操作(见微信小程序`小白AI`) 25 | - 支持评论消息订阅功能 26 | - 评论指定文章或页面后,会自动订阅该文章或页面的评论,当有新的评论则可以实现消息更新,提示已有新的评论。 27 | - 支持配置Admin用户删除其他用户的评论 28 | 29 | 30 | # 屏幕截图 31 | 32 | 下图为`WxComment`嵌入式到具体博客中显示的效果。 33 | 34 | ![](https://raw.githubusercontent.com/yicm/WxComment/master/screenshot/screenshot.png) 35 | 36 | # 快速入手 37 | 38 | 1. 注册LeanCloud账号,并创建过LeanCloud应用; 39 | 40 | 2. 登陆LeanCloud账号,打开链接[https://leancloud.cn/docs/weapp-domains.html](https://leancloud.cn/docs/weapp-domains.html),将显示域名配置到你的微信小程序服务器配置中; 41 | 42 | 3. 设置小程序的 AppID 与 AppSecret 43 | 3.1 登录 微信公众平台,在`设置` > `开发设置` 中获得 AppID 与 AppSecret 44 | 3.2 前往 LeanCloud `控制台` > `组件` > `社交`,保存「微信小程序」的 AppID 与 AppSecret 45 | 46 | 4. 克隆项目WxComment并将其放入小程序根目录 47 | 48 | ``` 49 | $ git clone https://github.com/yicm/WxComment.git 50 | ``` 51 | 52 | 5. 将LeanCloud自己的AppID和AppKey复制到WxComment.js对应位置; 53 | 54 | ``` 55 | AV.init({ 56 | appId: 'your leancloud appid', 57 | appKey: 'your leancloud appkey', 58 | }); 59 | ``` 60 | 61 | 6. 在小程序其他wxml文件中引入WxComment组件 62 | 63 | test.wxml 64 | 65 | ``` 66 | 67 | 68 | 69 | ``` 70 | 71 | test.json 72 | 73 | ``` 74 | "usingComponents": { 75 | "WxComment": "/component/WxComment/WxComment" 76 | } 77 | ``` 78 | 79 | 7. 配置Admin删除其他用户评论 80 | 81 | - 登陆LeanCloud,进入应用->`存储`->`数据`->`创建Class`->创建`Admin` Class: 82 | 83 | ![](https://raw.githubusercontent.com/yicm/WxComment/master/screenshot/admin.png) 84 | 85 | 86 | WxComment组件属性说明: 87 | 88 | ```bash 89 | tipOne: 颜色显示tip区域文字内容 90 | tipTwo: 无颜色显示tip区域文字内容 91 | submitBtnText:提交按钮文字内容,默认为“回复” 92 | textMaxLength: 评论最大文字长度限制,默认300 93 | articleID:文章或页面与WxComment绑定的唯一ID 94 | articleTitle: 文章或页面标题,默认值为空 95 | articleURL: 文章或页面的访问链接,默认值为空 96 | contentLen:评论内容至少为多长限制,默认为1 97 | theme: 评论组件样式,支持light/dark两种样式,默认值为light 98 | ``` 99 | 100 | # Demo 101 | 102 | 小程序`小白AI`博客引用WxComment组件示例,评论消息订阅可见`我的`->`消息`: 103 | 104 | ![](https://raw.githubusercontent.com/yicm/WxComment/master/screenshot/xiaobaiai.jpg) 105 | 106 | # TODO 107 | 108 | - 支持查看用户详细信息以及优化关注功能 109 | - 支持设置用户资料 110 | - 支持匿名群聊和私聊 111 | - 支持评论附加图片 112 | - ... 113 | 114 | # License 115 | 116 | [MIT](https://opensource.org/licenses/MIT) 117 | 118 | -------------------------------------------------------------------------------- /component/WxComment/WxComment.wxss: -------------------------------------------------------------------------------- 1 | image, video { 2 | width: 100%; 3 | margin: 0 auto 20rpx auto; 4 | } 5 | 6 | image { 7 | height: auto; 8 | } 9 | 10 | .theme_dark{ 11 | background-color: black; 12 | color: white; 13 | } 14 | 15 | .hide { 16 | display: none; 17 | } 18 | 19 | .show { 20 | display: block; 21 | } 22 | 23 | .title_box { 24 | display: flex; 25 | height: 70rpx; 26 | justify-content: center; 27 | margin-top: 20rpx; 28 | } 29 | 30 | .comment_list_box { 31 | display: flex; 32 | justify-content: center; 33 | } 34 | 35 | .comment_list { 36 | display: flex; 37 | width: 720rpx; 38 | margin: 0 auto; 39 | margin-top: 16rpx; 40 | min-height: 0; 41 | overflow: hidden; 42 | padding-top: 25rpx; 43 | padding-bottom: 25rpx; 44 | border-bottom: 1px dashed #f1f1f1; 45 | } 46 | 47 | .comment_avatar { 48 | width: 90rpx; 49 | height: 90rpx; 50 | } 51 | 52 | .comment_avatar image { 53 | width: 90rpx; 54 | height: 90rpx; 55 | border-radius: 50%; 56 | } 57 | 58 | .avatar_button { 59 | background: none; 60 | border: none; 61 | padding: 1rpx 5rpx 1rpx 1rpx; 62 | margin: 1rpx 5rpx 0rpx 5rpx; 63 | } 64 | 65 | .avatar_button::after { 66 | border: none; 67 | outline: none; 68 | } 69 | 70 | .comment_total_box { 71 | width: 610rpx; 72 | display: flex; 73 | flex-direction: column; 74 | } 75 | 76 | .comment_content_box { 77 | display: flex; 78 | flex-direction: column; 79 | width: 100%; 80 | margin-bottom: 15rpx; 81 | } 82 | 83 | .comment_meta { 84 | display: flex; 85 | flex-direction: row; 86 | flex-wrap: wrap; 87 | justify-content: space-between; 88 | width: 100%; 89 | margin-bottom: 8rpx; 90 | height: 38rpx; 91 | } 92 | 93 | .comment_nickname { 94 | display: flex; 95 | margin-right: 20rpx; 96 | font-size: 26rpx; 97 | font-weight: 600; 98 | color: #3f9f94; 99 | } 100 | 101 | .commnet_date { 102 | margin-left: 10rpx; 103 | font-size: 24rpx; 104 | color: #8e8e8e; 105 | } 106 | 107 | .comment_zan { 108 | display: flex; 109 | } 110 | 111 | .comment_zan image { 112 | width: 35rpx; 113 | height: 35rpx; 114 | } 115 | 116 | .comment_zan_num { 117 | color: #425888; 118 | font-size: 24rpx; 119 | height: 35rpx; 120 | line-height: 35rpx; 121 | } 122 | 123 | .comment_content { 124 | width: 100%; 125 | color: #6f6f6f; 126 | } 127 | 128 | .no_comment { 129 | color: #dadada; 130 | } 131 | 132 | .title_display { 133 | width: 720rpx; 134 | display: flex; 135 | flex-direction: row; 136 | padding-bottom: 2rpx; 137 | /*border-bottom: 1px solid #f1f1f1;*/ 138 | } 139 | 140 | .views_box { 141 | display: flex; 142 | height: 30rpx; 143 | justify-content: center; 144 | margin-top: 25rpx; 145 | margin-bottom: 10rpx; 146 | } 147 | 148 | .views_title_display { 149 | display: flex; 150 | flex-direction: row; 151 | width: 720rpx; 152 | padding-bottom: 2rpx; 153 | } 154 | 155 | .views_image { 156 | } 157 | 158 | .views_image image { 159 | width: 35rpx; 160 | height: 35rpx; 161 | } 162 | 163 | .views_text { 164 | width: 35rpx; 165 | height: 35rpx; 166 | color: #bfbfbf; 167 | font-size: 22rpx; 168 | line-height: 35rpx; 169 | margin-left: 10rpx; 170 | } 171 | 172 | .seg_line_box { 173 | display: flex; 174 | height: 5rpx; 175 | justify-content: center; 176 | margin-top: 5rpx; 177 | } 178 | 179 | .seg_line_left { 180 | width: 325rpx; 181 | border-bottom: 1rpx solid #e1e1e1; 182 | } 183 | 184 | .seg_line_dot { 185 | width: 50rpx; 186 | border-bottom: 5rpx dotted #dbdbdb; 187 | margin-left: 10rpx; 188 | margin-right: 10rpx; 189 | } 190 | 191 | .seg_line_right { 192 | width: 325rpx; 193 | border-bottom: 1rpx solid #e1e1e1; 194 | } 195 | 196 | .title_img image { 197 | width: 60rpx; 198 | height: 60rpx; 199 | } 200 | 201 | .title_text { 202 | display: flex; 203 | color: #3f9f94; 204 | font-size: 38rpx; 205 | line-height: 60rpx; 206 | margin-left: 10rpx; 207 | } 208 | 209 | .comment_display { 210 | width: 720rpx; 211 | height: 300rpx; 212 | box-sizing: border-box; 213 | position: relative; 214 | border: 1px solid #dadada; 215 | margin: 20rpx auto 20rpx auto; 216 | overflow: hidden; 217 | } 218 | 219 | .comment_textarea { 220 | box-sizing: border-box; 221 | position: relative; 222 | margin: 2rpx auto 2rpx auto; 223 | overflow: hidden; 224 | width: 700rpx; 225 | height: 220rpx; 226 | border: 1px #dadada; 227 | border-style: none none dashed none; 228 | } 229 | 230 | .comment_submit_display { 231 | display: flex; 232 | margin: 5rpx auto 5rpx auto; 233 | width: 700rpx; 234 | } 235 | 236 | .comment_submit_tip { 237 | width: 550rpx; 238 | font-size: 22rpx; 239 | height: 72rpx; 240 | line-height: 100rpx; 241 | margin: 2rpx auto 2rpx auto; 242 | } 243 | 244 | .markdown_tip { 245 | color: #ee9a49; 246 | } 247 | 248 | .commit_submit_btn { 249 | width: 150rpx; 250 | height: 65rpx; 251 | margin: 2rpx auto 2rpx auto; 252 | } 253 | 254 | .sub_comment_list_box { 255 | display: flex; 256 | flex-direction: column; 257 | width: 610rpx; 258 | } 259 | 260 | .sub_comment_display_box { 261 | display: flex; 262 | flex-direction: row; 263 | } 264 | 265 | .sub_comment_box { 266 | display: flex; 267 | flex-direction: column; 268 | width: 510rpx; 269 | } 270 | -------------------------------------------------------------------------------- /component/WxComment/WxComment.wxml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | {{article_views}} 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 评论列表 29 | 30 | ,共{{comment_num}}条评论 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | {{item.showNickName}} 52 | 53 | {{item.time}} 54 | 55 | 56 | 57 | 58 | 59 | {{item.zanNum}} 60 | 61 | 62 | 63 | 64 | 65 | {{item.zanNum}} 66 | 67 | 68 | 69 | {{item.content}} 70 | 71 | 72 | 73 | 74 | 79 | 80 | 81 | 82 | {{sub_item.showNickName}} 83 | 84 | {{sub_item.time}} 85 | 86 | 87 | 88 | 89 | 90 | {{sub_item.zanNum}} 91 | 92 | 93 | 94 | 95 | 96 | {{sub_item.zanNum}} 97 | 98 | 99 | 100 | {{sub_item.content}} 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 |