narro пре 6 година
родитељ
комит
88ed1ddca6

+ 5
- 0
CHANGELOG.md Прегледај датотеку

@@ -1,5 +1,10 @@
1 1
 # CHANGELOG
2 2
 
3
+## 0.5.5
4
+
5
+- [x] 增加删除评论、回复功能
6
+- [x] 错误回调onError增加info:{ response } 参数
7
+
3 8
 ## 0.5.4
4 9
 
5 10
 - [x] 暂无昵称 -> 游客

+ 17
- 17
README.md Прегледај датотеку

@@ -2,7 +2,7 @@
2 2
 
3 3
 通用评论系统及编辑器
4 4
 
5
-**`version 0.5.4`**
5
+**`version 0.5.5`**
6 6
 
7 7
 ```js
8 8
 import Comment, { Editor, RenderText } from 'comment';
@@ -13,20 +13,20 @@ import Comment, { Editor, RenderText } from 'comment';
13 13
 ## Comment
14 14
 
15 15
 
16
-| props            | type          | default                            | required | description                                                  |
17
-| ---------------- | ------------- | ---------------------------------- | -------- | ------------------------------------------------------------ |
18
-| type             | number        |                                    | true     | 评论的 type                                                  |
19
-| businessId       | string        |                                    | true     | 评论的 business id                                           |
20
-| API              | string        | http://api.links123.net/comment/v1 | false    | API 前缀                                                     |
21
-| showList         | boolean       | true                               | false    | 是否显示评论列表                                             |
22
-| showEditor       | boolean       | true                               | false    | 是否显示评论输入框                                           |
23
-| showAlertComment | boolean       | false                              | false    | 评论成功之后,是否通过 Antd 的 Message 组件进行提示          |
24
-| showAlertReply   | boolean       | false                              | false    | 回复成功之后,是否通过 Antd 的 Message 组件进行提示          |
25
-| showAlertFavor   | boolean       | false                              | false    | 点赞/取消点赞成功之后,是否通过 Antd 的 Message 组件进行提示 |
26
-| showError        | boolean       | true                               | false    | 是否使用Antd的Message组件提示错误信息                        |
27
-| onError          | function(msg) |                                    | false    | 错误回调, 出错了会被调用                                     |
28
-| token            | string        |                                    | false    | [deprecated] token,用于身份认证,非必须。默认使用 cookie    |
29
-
16
+| props            | type          | default                            | required | description                                                                       |
17
+| ---------------- | ------------- | ---------------------------------- | -------- | --------------------------------------------------------------------------------- |
18
+| type             | number        |                                    | true     | 评论的 type                                                                       |
19
+| businessId       | string        |                                    | true     | 评论的 business id                                                                |
20
+| API              | string        | http://api.links123.net/comment/v1 | false    | API 前缀                                                                          |
21
+| showList         | boolean       | true                               | false    | 是否显示评论列表                                                                  |
22
+| showEditor       | boolean       | true                               | false    | 是否显示评论输入框                                                                |
23
+| showAlertComment | boolean       | false                              | false    | 评论成功之后,是否通过 Antd 的 Message 组件进行提示                               |
24
+| showAlertReply   | boolean       | false                              | false    | 回复成功之后,是否通过 Antd 的 Message 组件进行提示                               |
25
+| showAlertFavor   | boolean       | false                              | false    | 点赞/取消点赞成功之后,是否通过 Antd 的 Message 组件进行提示                      |
26
+| showError        | boolean       | true                               | false    | 是否使用Antd的Message组件提示错误信息                                             |
27
+| onError          | function(msg) |                                    | false    | 错误回调, 出错了会被调用                                                          |
28
+| userId           | number        |                                    | false    | 用户id, comment内部不维护用户id, 调用组件时传递过来, 目前用于判断是否显示删除按钮 |
29
+| token            | string        |                                    | false    | [deprecated] token,用于身份认证,非必须。默认使用 cookie                         |
30 30
 
31 31
 
32 32
 ## Editor
@@ -52,7 +52,7 @@ import Comment, { Editor, RenderText } from 'comment';
52 52
 | onRef               | function                        |               | false    | 传递子组件的引用                                                                                  |
53 53
 | closeUploadWhenBlur | boolean                         |               | false    | 当 upload 失去焦点(鼠标点击非 Upload 的区域)的时候,是否自动关闭 Popover                        |
54 54
 | showError           | boolean                         | true          | false    | 是否使用Antd的Message组件提示错误信息, 主要是上传图片出错的情况                                   |
55
-| onError             | function(msg)                   |               | false    | 错误回调, 出错了会被调用, 主要是上传图片出错的情况                                                |
55
+| onError             | function(msg,{response})        |               | false    | 错误回调, 出错了会被调用, 主要是上传图片出错的情况                                                |
56 56
 
57 57
 
58 58
 
@@ -265,4 +265,4 @@ $ yarn start
265 265
 - [x] oss/sts 接口报错
266 266
 - [ ] 头像 404 `https://links123-images.oss-cn-hangzhou.aliyuncs.com/avatar/`
267 267
 - [ ] 上传图片的时候偶尔会出现InvalidPart
268
-
268
+- [ ] 上传图片失败时, 提示并且不显示缩略图

+ 110
- 72
lib/App.js Прегледај датотеку

@@ -85,12 +85,15 @@ var App = function (_Component) {
85 85
       isNoMoreComment: false
86 86
     };
87 87
     _this.handleChangeLoading = _this.handleChangeLoading.bind(_this);
88
-    _this.sGetComment = _this.sGetComment.bind(_this);
89
-    _this.sGetReply = _this.sGetReply.bind(_this);
90 88
     _this.sCreateComment = _this.sCreateComment.bind(_this);
91
-    _this.sCreateReply = _this.sCreateReply.bind(_this);
89
+    _this.sDeleteComment = _this.sDeleteComment.bind(_this);
92 90
     _this.sCommentFavor = _this.sCommentFavor.bind(_this);
91
+    _this.sCreateReply = _this.sCreateReply.bind(_this);
92
+    _this.sDeleteReply = _this.sDeleteReply.bind(_this);
93
+    _this.errorHandler = _this.errorHandler.bind(_this);
94
+    _this.sGetComment = _this.sGetComment.bind(_this);
93 95
     _this.sReplyFavor = _this.sReplyFavor.bind(_this);
96
+    _this.sGetReply = _this.sGetReply.bind(_this);
94 97
     _this.sOssSts = _this.sOssSts.bind(_this);
95 98
     return _this;
96 99
   }
@@ -110,12 +113,23 @@ var App = function (_Component) {
110 113
   }, {
111 114
     key: "error",
112 115
     value: function error(msg) {
116
+      var info = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
117
+
113 118
       if (this.props.showError) {
114 119
         _message3.default.error(msg);
115 120
       }
116 121
       if (this.props.onError) {
117
-        this.props.onError(msg);
122
+        this.props.onError(msg, info);
123
+      }
124
+    }
125
+  }, {
126
+    key: "errorHandler",
127
+    value: function errorHandler(error) {
128
+      if (error.response && error.response.data && error.response.data.msg) {
129
+        this.error(_lang2.default[error.response.data.msg] || _constant.ERROR_DEFAULT, { response: error.response });
130
+        return;
118 131
       }
132
+      this.error(_lang2.default[error.message] || _constant.ERROR_DEFAULT, { response: error.response });
119 133
     }
120 134
 
121 135
     /**
@@ -180,13 +194,7 @@ var App = function (_Component) {
180 194
             isNoMoreComment: true
181 195
           });
182 196
         }
183
-      }).catch(function (error) {
184
-        if (error.response && error.response.data && error.response.data.msg) {
185
-          _this2.error(_lang2.default[error.response.data.msg] || _constant.ERROR_DEFAULT);
186
-          return;
187
-        }
188
-        _this2.error(_lang2.default[error.message] || _constant.ERROR_DEFAULT);
189
-      }).finally(function () {
197
+      }).catch(this.errorHandler).finally(function () {
190 198
         _this2.handleChangeLoading("sGetComment", false);
191 199
       });
192 200
     }
@@ -235,13 +243,7 @@ var App = function (_Component) {
235 243
           return item;
236 244
         });
237 245
         _this3.setState({ list: list });
238
-      }).catch(function (error) {
239
-        if (error.response && error.response.data && error.response.data.msg) {
240
-          _this3.error(_lang2.default[error.response.data.msg] || _constant.ERROR_DEFAULT);
241
-          return;
242
-        }
243
-        _this3.error(_lang2.default[error.message] || _constant.ERROR_DEFAULT);
244
-      }).finally(function () {
246
+      }).catch(this.errorHandler).finally(function () {
245 247
         _this3.handleChangeLoading("sGetReply", false);
246 248
       });
247 249
     }
@@ -292,17 +294,40 @@ var App = function (_Component) {
292 294
           isTemporary: true // 临时的数据
293 295
         }));
294 296
         _this4.setState({ list: list, total: total + 1 });
295
-      }).catch(function (error) {
296
-        if (error.response && error.response.data && error.response.data.msg) {
297
-          _this4.error(_lang2.default[error.response.data.msg] || _constant.ERROR_DEFAULT);
298
-          return;
299
-        }
300
-        _this4.error(_lang2.default[error.message] || _constant.ERROR_DEFAULT);
301
-      }).finally(function () {
297
+      }).catch(this.errorHandler).finally(function () {
302 298
         _this4.handleChangeLoading("sCreateComment", false);
303 299
       });
304 300
     }
305 301
 
302
+    /**
303
+     * 删除评论
304
+     */
305
+
306
+  }, {
307
+    key: "sDeleteComment",
308
+    value: function sDeleteComment(commentId) {
309
+      var _this5 = this;
310
+
311
+      this.handleChangeLoading("sDeleteComment", true);
312
+      var API = this.props.API;
313
+
314
+      this.axios(API + "/comments/" + commentId, {
315
+        method: "delete",
316
+        withCredentials: true
317
+      }).then(function () {
318
+        var _state2 = _this5.state,
319
+            list = _state2.list,
320
+            total = _state2.total;
321
+
322
+        var res = list.filter(function (item) {
323
+          return item.id !== commentId;
324
+        });
325
+        _this5.setState({ list: res, total: total - 1 });
326
+      }).catch(this.errorHandler).finally(function () {
327
+        _this5.handleChangeLoading("sDeleteComment", false);
328
+      });
329
+    }
330
+
306 331
     /**
307 332
      * 添加回复
308 333
      * 回复评论/回复回复
@@ -312,7 +337,7 @@ var App = function (_Component) {
312 337
   }, {
313 338
     key: "sCreateReply",
314 339
     value: function sCreateReply(data, cb) {
315
-      var _this5 = this;
340
+      var _this6 = this;
316 341
 
317 342
       if (!data.content) return this.error("回复内容不能为空 ");
318 343
       this.handleChangeLoading("sCreateReply", true);
@@ -323,14 +348,14 @@ var App = function (_Component) {
323 348
         data: data,
324 349
         withCredentials: true
325 350
       }).then(function (response) {
326
-        if (_this5.props.showAlertReply) {
351
+        if (_this6.props.showAlertReply) {
327 352
           _message3.default.success("回复成功!");
328 353
         }
329 354
         if ((0, _helper.isFunction)(cb)) cb();
330 355
         // 将数据写入到 list 中
331 356
         // 临时插入
332 357
         // 等到获取数据之后,删除临时数据
333
-        var list = _this5.state.list.map(function (item) {
358
+        var list = _this6.state.list.map(function (item) {
334 359
           if (item.id === data.comment_id) {
335 360
             if (!item.replies) item.replies = [];
336 361
             item.replies.push(_extends({}, response.data, {
@@ -340,15 +365,43 @@ var App = function (_Component) {
340 365
           }
341 366
           return item;
342 367
         });
343
-        _this5.setState({ list: list });
344
-      }).catch(function (error) {
345
-        if (error.response && error.response.data && error.response.data.msg) {
346
-          _this5.error(_lang2.default[error.response.data.msg] || _constant.ERROR_DEFAULT);
347
-          return;
348
-        }
349
-        _this5.error(_lang2.default[error.message] || _constant.ERROR_DEFAULT);
350
-      }).finally(function () {
351
-        _this5.handleChangeLoading("sCreateReply", false);
368
+        _this6.setState({ list: list });
369
+      }).catch(this.errorHandler).finally(function () {
370
+        _this6.handleChangeLoading("sCreateReply", false);
371
+      });
372
+    }
373
+
374
+    /**
375
+     * 删除回复
376
+     * @param {*} replyId 
377
+     * @param {*} commentId 
378
+     */
379
+
380
+  }, {
381
+    key: "sDeleteReply",
382
+    value: function sDeleteReply(replyId, commentId) {
383
+      var _this7 = this;
384
+
385
+      this.handleChangeLoading("sDeleteReply", true);
386
+      var API = this.props.API;
387
+
388
+      this.axios(API + "/replies/" + replyId + "?CommentID=" + commentId, {
389
+        method: "delete",
390
+        withCredentials: true
391
+      }).then(function () {
392
+        var list = _this7.state.list.map(function (item) {
393
+          if (item.id === commentId) {
394
+            var replies = item.replies.filter(function (item) {
395
+              return item.id !== replyId;
396
+            });
397
+            item.replies = replies;
398
+            item.reply_count -= 1;
399
+          }
400
+          return item;
401
+        });
402
+        _this7.setState({ list: list });
403
+      }).catch(this.errorHandler).finally(function () {
404
+        _this7.handleChangeLoading("sDeleteReply", false);
352 405
       });
353 406
     }
354 407
 
@@ -361,7 +414,7 @@ var App = function (_Component) {
361 414
   }, {
362 415
     key: "sCommentFavor",
363 416
     value: function sCommentFavor(commentId, favored) {
364
-      var _this6 = this;
417
+      var _this8 = this;
365 418
 
366 419
       this.handleChangeLoading("sCommentFavor", true);
367 420
       var API = this.props.API;
@@ -370,26 +423,20 @@ var App = function (_Component) {
370 423
         method: favored ? "delete" : "put",
371 424
         withCredentials: true
372 425
       }).then(function (response) {
373
-        if (_this6.props.showAlertFavor) {
426
+        if (_this8.props.showAlertFavor) {
374 427
           _message3.default.success(favored ? "取消点赞成功!" : "点赞成功!");
375 428
         }
376 429
         // 更新 list 中的该项数据的 favored
377
-        var list = _this6.state.list.map(function (item) {
430
+        var list = _this8.state.list.map(function (item) {
378 431
           if (item.id === commentId) {
379 432
             item.favored = !favored;
380 433
             item.favor_count += favored ? -1 : 1;
381 434
           }
382 435
           return item;
383 436
         });
384
-        _this6.setState({ list: list });
385
-      }).catch(function (error) {
386
-        if (error.response && error.response.data && error.response.data.msg) {
387
-          _this6.error(_lang2.default[error.response.data.msg] || _constant.ERROR_DEFAULT);
388
-          return;
389
-        }
390
-        _this6.error(_lang2.default[error.message] || _constant.ERROR_DEFAULT);
391
-      }).finally(function () {
392
-        _this6.handleChangeLoading("sCommentFavor", false);
437
+        _this8.setState({ list: list });
438
+      }).catch(this.errorHandler).finally(function () {
439
+        _this8.handleChangeLoading("sCommentFavor", false);
393 440
       });
394 441
     }
395 442
 
@@ -403,7 +450,7 @@ var App = function (_Component) {
403 450
   }, {
404 451
     key: "sReplyFavor",
405 452
     value: function sReplyFavor(replyId, commentId, favored) {
406
-      var _this7 = this;
453
+      var _this9 = this;
407 454
 
408 455
       this.handleChangeLoading("sReplyFavor", true);
409 456
       var API = this.props.API;
@@ -417,7 +464,7 @@ var App = function (_Component) {
417 464
       }).then(function (response) {
418 465
         _message3.default.success(favored ? "取消点赞成功!" : "点赞成功!");
419 466
         // 更新 list 中的该项数据的 favored
420
-        var list = _this7.state.list.map(function (item) {
467
+        var list = _this9.state.list.map(function (item) {
421 468
           if (item.id === commentId) {
422 469
             item.replies = item.replies.map(function (r) {
423 470
               if (r.id === replyId) {
@@ -432,15 +479,9 @@ var App = function (_Component) {
432 479
           }
433 480
           return item;
434 481
         });
435
-        _this7.setState({ list: list });
436
-      }).catch(function (error) {
437
-        if (error.response && error.response.data && error.response.data.msg) {
438
-          _this7.error(_lang2.default[error.response.data.msg] || _constant.ERROR_DEFAULT);
439
-          return;
440
-        }
441
-        _this7.error(_lang2.default[error.message] || _constant.ERROR_DEFAULT);
442
-      }).finally(function () {
443
-        _this7.handleChangeLoading("sReplyFavor", false);
482
+        _this9.setState({ list: list });
483
+      }).catch(this.errorHandler).finally(function () {
484
+        _this9.handleChangeLoading("sReplyFavor", false);
444 485
       });
445 486
     }
446 487
 
@@ -451,21 +492,15 @@ var App = function (_Component) {
451 492
   }, {
452 493
     key: "sOssSts",
453 494
     value: function sOssSts() {
454
-      var _this8 = this;
495
+      var _this10 = this;
455 496
 
456 497
       this.handleChangeLoading("sOssSts", true);
457 498
       var API = this.props.API;
458 499
 
459 500
       this.axios.get(API + "/oss/sts").then(function (response) {
460
-        _this8.setState({ oss: _extends({}, response.data) });
461
-      }).catch(function (error) {
462
-        if (error.response && error.response.data && error.response.data.msg) {
463
-          _this8.error(_lang2.default[error.response.data.msg] || _constant.ERROR_DEFAULT);
464
-          return;
465
-        }
466
-        _this8.error(_lang2.default[error.message] || _constant.ERROR_DEFAULT);
467
-      }).finally(function () {
468
-        _this8.handleChangeLoading("sOssSts", false);
501
+        _this10.setState({ oss: _extends({}, response.data) });
502
+      }).catch(this.errorHandler).finally(function () {
503
+        _this10.handleChangeLoading("sOssSts", false);
469 504
       });
470 505
     }
471 506
   }, {
@@ -479,7 +514,9 @@ var App = function (_Component) {
479 514
         sReplyFavor: this.sReplyFavor,
480 515
         sCreateReply: this.sCreateReply,
481 516
         sGetReply: this.sGetReply,
482
-        sOssSts: this.sOssSts
517
+        sOssSts: this.sOssSts,
518
+        sDeleteComment: this.sDeleteComment,
519
+        sDeleteReply: this.sDeleteReply
483 520
       });
484 521
 
485 522
       return _react2.default.createElement(
@@ -512,7 +549,8 @@ App.propTypes = {
512 549
   showAlertReply: _propTypes2.default.bool, // 回复成功之后,是否通过 Antd 的 Message 组件进行提示
513 550
   showAlertFavor: _propTypes2.default.bool, // 点赞/取消点赞成功之后,是否通过 Antd 的 Message 组件进行提示
514 551
   showError: _propTypes2.default.bool, // 是否使用Antd的Message组件提示错误信息
515
-  onError: _propTypes2.default.func // 错误回调, 出错了会被调用
552
+  onError: _propTypes2.default.func, // 错误回调, 出错了会被调用
553
+  userId: _propTypes2.default.number // 用户id, comment内部不维护用户id, 调用组件时传递过来, 目前用于判断是否显示删除按钮
516 554
 };
517 555
 
518 556
 App.defaultProps = {

+ 1
- 1
lib/App.js.map
Разлика између датотеке није приказан због своје велике величине
Прегледај датотеку


+ 23
- 0
lib/components/ContentItem/index.js Прегледај датотеку

@@ -4,6 +4,10 @@ Object.defineProperty(exports, "__esModule", {
4 4
   value: true
5 5
 });
6 6
 
7
+var _popconfirm = require("antd/es/popconfirm");
8
+
9
+var _popconfirm2 = _interopRequireDefault(_popconfirm);
10
+
7 11
 var _icon = require("antd/es/icon");
8 12
 
9 13
 var _icon2 = _interopRequireDefault(_icon);
@@ -18,6 +22,8 @@ var _avatar2 = _interopRequireDefault(_avatar);
18 22
 
19 23
 var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
20 24
 
25
+require("antd/es/popconfirm/style/css");
26
+
21 27
 require("antd/es/icon/style/css");
22 28
 
23 29
 require("antd/es/tooltip/style/css");
@@ -201,6 +207,23 @@ var CommentItem = function (_Component) {
201 207
                 showReply ? _react2.default.createElement(_icon2.default, { type: "up" }) : _react2.default.createElement(_icon2.default, { type: "down" })
202 208
               )
203 209
             ) : null,
210
+            app.userId === content.user_id && _react2.default.createElement(
211
+              _popconfirm2.default,
212
+              { title: "\u786E\u5B9A\u8981\u5220\u9664\u5417?", onConfirm: function onConfirm() {
213
+                  if (replyId) {
214
+                    app.sDeleteReply(content.id, commentId);
215
+                    return;
216
+                  }
217
+                  app.sDeleteComment(content.id);
218
+                }, okText: "\u786E\u5B9A", cancelText: "\u53D6\u6D88" },
219
+              _react2.default.createElement(
220
+                "a",
221
+                {
222
+                  className: "comment-item-bottom-right"
223
+                },
224
+                "\xA0 \u5220\u9664"
225
+              )
226
+            ),
204 227
             _react2.default.createElement(
205 228
               "a",
206 229
               {

+ 1
- 1
lib/components/ContentItem/index.js.map
Разлика између датотеке није приказан због своје велике величине
Прегледај датотеку


+ 1
- 1
lib/components/Editor/Upload.js Прегледај датотеку

@@ -150,7 +150,7 @@ var App = function (_React$Component) {
150 150
             _message3.default.error(msg);
151 151
           }
152 152
           if (_this2.props.onError) {
153
-            _this2.props.onError(msg);
153
+            _this2.props.onError(msg, { response: e.response });
154 154
           }
155 155
           info.onError(e);
156 156
         });

+ 1
- 1
lib/components/Editor/Upload.js.map
Разлика између датотеке није приказан због своје велике величине
Прегледај датотеку


+ 1
- 1
lib/components/Editor/index.js.map
Разлика између датотеке није приказан због своје велике величине
Прегледај датотеку


+ 13
- 2
lib/index.js Прегледај датотеку

@@ -81,7 +81,13 @@ var Index = function (_Component) {
81 81
           showAlertReply: true,
82 82
           showAlertFavor: true,
83 83
           showError: false,
84
-          onError: function onError(msg) {
84
+          userId: 71299,
85
+          onError: function onError(msg, _ref2) {
86
+            var response = _ref2.response;
87
+
88
+            if (response.status === 401) {
89
+              console.log("unlogined");
90
+            }
85 91
             console.log("-----------" + msg);
86 92
           }
87 93
         },
@@ -96,7 +102,12 @@ var Index = function (_Component) {
96 102
             console.log("succ");
97 103
           },
98 104
           showError: false,
99
-          onError: function onError(msg) {
105
+          onError: function onError(msg, _ref3) {
106
+            var response = _ref3.response;
107
+
108
+            if (response.status === 401) {
109
+              console.log("unlogined");
110
+            }
100 111
             console.log("-----------" + msg);
101 112
           }
102 113
         })

+ 1
- 1
lib/index.js.map
Разлика између датотеке није приказан због своје велике величине
Прегледај датотеку


+ 1
- 1
package.json Прегледај датотеку

@@ -1,6 +1,6 @@
1 1
 {
2 2
   "name": "comment",
3
-  "version": "0.5.4",
3
+  "version": "0.5.5",
4 4
   "main": "lib/App.js",
5 5
   "description": "通用评论",
6 6
   "keywords": [

+ 82
- 56
src/App.js Прегледај датотеку

@@ -29,12 +29,15 @@ class App extends Component {
29 29
       isNoMoreComment: false
30 30
     };
31 31
     this.handleChangeLoading = this.handleChangeLoading.bind(this);
32
-    this.sGetComment = this.sGetComment.bind(this);
33
-    this.sGetReply = this.sGetReply.bind(this);
34 32
     this.sCreateComment = this.sCreateComment.bind(this);
35
-    this.sCreateReply = this.sCreateReply.bind(this);
33
+    this.sDeleteComment = this.sDeleteComment.bind(this);
36 34
     this.sCommentFavor = this.sCommentFavor.bind(this);
35
+    this.sCreateReply = this.sCreateReply.bind(this);
36
+    this.sDeleteReply = this.sDeleteReply.bind(this);
37
+    this.errorHandler = this.errorHandler.bind(this);
38
+    this.sGetComment = this.sGetComment.bind(this);
37 39
     this.sReplyFavor = this.sReplyFavor.bind(this);
40
+    this.sGetReply = this.sGetReply.bind(this);
38 41
     this.sOssSts = this.sOssSts.bind(this);
39 42
   }
40 43
 
@@ -50,15 +53,27 @@ class App extends Component {
50 53
 
51 54
   componentDidMount() {}
52 55
 
53
-  error(msg) {
56
+  error(msg, info = {}) {
54 57
     if (this.props.showError) {
55 58
       message.error(msg);
56 59
     }
57 60
     if (this.props.onError) {
58
-      this.props.onError(msg);
61
+      this.props.onError(msg, info);
59 62
     }
60 63
   }
61 64
 
65
+  errorHandler(error) {
66
+    if (error.response && error.response.data && error.response.data.msg) {
67
+      this.error(lang[error.response.data.msg] || ERROR_DEFAULT, {
68
+        response: error.response
69
+      });
70
+      return;
71
+    }
72
+    this.error(lang[error.message] || ERROR_DEFAULT, {
73
+      response: error.response
74
+    });
75
+  }
76
+
62 77
   /**
63 78
    * 改变 loading 状态
64 79
    * @param {string} key key
@@ -102,13 +117,7 @@ class App extends Component {
102 117
           });
103 118
         }
104 119
       })
105
-      .catch(error => {
106
-        if (error.response && error.response.data && error.response.data.msg) {
107
-          this.error(lang[error.response.data.msg] || ERROR_DEFAULT);
108
-          return;
109
-        }
110
-        this.error(lang[error.message] || ERROR_DEFAULT);
111
-      })
120
+      .catch(this.errorHandler)
112 121
       .finally(() => {
113 122
         this.handleChangeLoading("sGetComment", false);
114 123
       });
@@ -150,13 +159,7 @@ class App extends Component {
150 159
         });
151 160
         this.setState({ list });
152 161
       })
153
-      .catch(error => {
154
-        if (error.response && error.response.data && error.response.data.msg) {
155
-          this.error(lang[error.response.data.msg] || ERROR_DEFAULT);
156
-          return;
157
-        }
158
-        this.error(lang[error.message] || ERROR_DEFAULT);
159
-      })
162
+      .catch(this.errorHandler)
160 163
       .finally(() => {
161 164
         this.handleChangeLoading("sGetReply", false);
162 165
       });
@@ -194,18 +197,33 @@ class App extends Component {
194 197
         });
195 198
         this.setState({ list, total: total + 1 });
196 199
       })
197
-      .catch(error => {
198
-        if (error.response && error.response.data && error.response.data.msg) {
199
-          this.error(lang[error.response.data.msg] || ERROR_DEFAULT);
200
-          return;
201
-        }
202
-        this.error(lang[error.message] || ERROR_DEFAULT);
203
-      })
200
+      .catch(this.errorHandler)
204 201
       .finally(() => {
205 202
         this.handleChangeLoading("sCreateComment", false);
206 203
       });
207 204
   }
208 205
 
206
+  /**
207
+   * 删除评论
208
+   */
209
+  sDeleteComment(commentId) {
210
+    this.handleChangeLoading("sDeleteComment", true);
211
+    const { API } = this.props;
212
+    this.axios(`${API}/comments/${commentId}`, {
213
+      method: "delete",
214
+      withCredentials: true
215
+    })
216
+      .then(() => {
217
+        const { list, total } = this.state;
218
+        const res = list.filter(item => item.id !== commentId);
219
+        this.setState({ list: res, total: total - 1 });
220
+      })
221
+      .catch(this.errorHandler)
222
+      .finally(() => {
223
+        this.handleChangeLoading("sDeleteComment", false);
224
+      });
225
+  }
226
+
209 227
   /**
210 228
    * 添加回复
211 229
    * 回复评论/回复回复
@@ -241,18 +259,41 @@ class App extends Component {
241 259
         });
242 260
         this.setState({ list });
243 261
       })
244
-      .catch(error => {
245
-        if (error.response && error.response.data && error.response.data.msg) {
246
-          this.error(lang[error.response.data.msg] || ERROR_DEFAULT);
247
-          return;
248
-        }
249
-        this.error(lang[error.message] || ERROR_DEFAULT);
250
-      })
262
+      .catch(this.errorHandler)
251 263
       .finally(() => {
252 264
         this.handleChangeLoading("sCreateReply", false);
253 265
       });
254 266
   }
255 267
 
268
+  /**
269
+   * 删除回复
270
+   * @param {*} replyId
271
+   * @param {*} commentId
272
+   */
273
+  sDeleteReply(replyId, commentId) {
274
+    this.handleChangeLoading("sDeleteReply", true);
275
+    const { API } = this.props;
276
+    this.axios(`${API}/replies/${replyId}?CommentID=${commentId}`, {
277
+      method: "delete",
278
+      withCredentials: true
279
+    })
280
+      .then(() => {
281
+        const list = this.state.list.map(item => {
282
+          if (item.id === commentId) {
283
+            const replies = item.replies.filter(item => item.id !== replyId);
284
+            item.replies = replies;
285
+            item.reply_count -= 1;
286
+          }
287
+          return item;
288
+        });
289
+        this.setState({ list });
290
+      })
291
+      .catch(this.errorHandler)
292
+      .finally(() => {
293
+        this.handleChangeLoading("sDeleteReply", false);
294
+      });
295
+  }
296
+
256 297
   /**
257 298
    * 评论 点赞/取消点赞
258 299
    * @param {string} commentId { commentId }
@@ -279,13 +320,7 @@ class App extends Component {
279 320
         });
280 321
         this.setState({ list });
281 322
       })
282
-      .catch(error => {
283
-        if (error.response && error.response.data && error.response.data.msg) {
284
-          this.error(lang[error.response.data.msg] || ERROR_DEFAULT);
285
-          return;
286
-        }
287
-        this.error(lang[error.message] || ERROR_DEFAULT);
288
-      })
323
+      .catch(this.errorHandler)
289 324
       .finally(() => {
290 325
         this.handleChangeLoading("sCommentFavor", false);
291 326
       });
@@ -327,13 +362,7 @@ class App extends Component {
327 362
         });
328 363
         this.setState({ list });
329 364
       })
330
-      .catch(error => {
331
-        if (error.response && error.response.data && error.response.data.msg) {
332
-          this.error(lang[error.response.data.msg] || ERROR_DEFAULT);
333
-          return;
334
-        }
335
-        this.error(lang[error.message] || ERROR_DEFAULT);
336
-      })
365
+      .catch(this.errorHandler)
337 366
       .finally(() => {
338 367
         this.handleChangeLoading("sReplyFavor", false);
339 368
       });
@@ -350,13 +379,7 @@ class App extends Component {
350 379
       .then(response => {
351 380
         this.setState({ oss: { ...response.data } });
352 381
       })
353
-      .catch(error => {
354
-        if (error.response && error.response.data && error.response.data.msg) {
355
-          this.error(lang[error.response.data.msg] || ERROR_DEFAULT);
356
-          return;
357
-        }
358
-        this.error(lang[error.message] || ERROR_DEFAULT);
359
-      })
382
+      .catch(this.errorHandler)
360 383
       .finally(() => {
361 384
         this.handleChangeLoading("sOssSts", false);
362 385
       });
@@ -373,7 +396,9 @@ class App extends Component {
373 396
       sReplyFavor: this.sReplyFavor,
374 397
       sCreateReply: this.sCreateReply,
375 398
       sGetReply: this.sGetReply,
376
-      sOssSts: this.sOssSts
399
+      sOssSts: this.sOssSts,
400
+      sDeleteComment: this.sDeleteComment,
401
+      sDeleteReply: this.sDeleteReply
377 402
     };
378 403
 
379 404
     return (
@@ -403,7 +428,8 @@ App.propTypes = {
403 428
   showAlertReply: PropTypes.bool, // 回复成功之后,是否通过 Antd 的 Message 组件进行提示
404 429
   showAlertFavor: PropTypes.bool, // 点赞/取消点赞成功之后,是否通过 Antd 的 Message 组件进行提示
405 430
   showError: PropTypes.bool, // 是否使用Antd的Message组件提示错误信息
406
-  onError: PropTypes.func // 错误回调, 出错了会被调用
431
+  onError: PropTypes.func, // 错误回调, 出错了会被调用
432
+  userId: PropTypes.number // 用户id, comment内部不维护用户id, 调用组件时传递过来, 目前用于判断是否显示删除按钮
407 433
 };
408 434
 
409 435
 App.defaultProps = {

+ 17
- 2
src/components/ContentItem/index.js Прегледај датотеку

@@ -1,6 +1,6 @@
1 1
 import React, { Component } from "react";
2 2
 import PropTypes from "prop-types";
3
-import { Avatar, Icon, Tooltip } from "antd";
3
+import { Avatar, Icon, Tooltip, Popconfirm } from "antd";
4 4
 import dayjs from "dayjs";
5 5
 import "dayjs/locale/zh-cn";
6 6
 import relativeTime from "dayjs/plugin/relativeTime";
@@ -121,7 +121,22 @@ class CommentItem extends Component {
121 121
                 </a>
122 122
               </div>
123 123
             ) : null}
124
-
124
+            {app.userId === content.user_id && (
125
+              <Popconfirm
126
+                title="确定要删除吗?"
127
+                onConfirm={() => {
128
+                  if (replyId) {
129
+                    app.sDeleteReply(content.id, commentId);
130
+                    return;
131
+                  }
132
+                  app.sDeleteComment(content.id);
133
+                }}
134
+                okText="确定"
135
+                cancelText="取消"
136
+              >
137
+                <a className="comment-item-bottom-right">&nbsp; 删除</a>
138
+              </Popconfirm>
139
+            )}
125 140
             <a
126 141
               onClick={this.handleToggleInput}
127 142
               className="comment-item-bottom-right"

+ 1
- 1
src/components/Editor/Upload.js Прегледај датотеку

@@ -93,7 +93,7 @@ class App extends React.Component {
93 93
             message.error(msg);
94 94
           }
95 95
           if (this.props.onError) {
96
-            this.props.onError(msg);
96
+            this.props.onError(msg, { response: e.response });
97 97
           }
98 98
           info.onError(e);
99 99
         });

+ 9
- 2
src/index.js Прегледај датотеку

@@ -41,7 +41,11 @@ class Index extends Component {
41 41
         showAlertReply
42 42
         showAlertFavor
43 43
         showError={false}
44
-        onError={msg => {
44
+        userId={71299}
45
+        onError={(msg, { response }) => {
46
+          if (response.status === 401) {
47
+            console.log("unlogined");
48
+          }
45 49
           console.log(`-----------${msg}`);
46 50
         }}
47 51
       >
@@ -56,7 +60,10 @@ class Index extends Component {
56 60
             console.log("succ");
57 61
           }}
58 62
           showError={false}
59
-          onError={msg => {
63
+          onError={(msg, { response }) => {
64
+            if (response.status === 401) {
65
+              console.log("unlogined");
66
+            }
60 67
             console.log(`-----------${msg}`);
61 68
           }}
62 69
         />