Browse Source

Merge branch 'feature/token' of node/npmcomment into master

node 6 years ago
parent
commit
0d0fb477b9

+ 5
- 0
CHANGELOG.md View File

1
 # CHANGELOG
1
 # CHANGELOG
2
 
2
 
3
+## 0.2.1
4
+
5
+- [x] feat: 添加 props token
6
+- [x] feat: 编辑器没有值的时候,默认处于 disabled 状态
7
+
3
 ## 0.2.0
8
 ## 0.2.0
4
 
9
 
5
 - [x] feat: 添加 showHeader 属性
10
 - [x] feat: 添加 showHeader 属性

+ 1
- 0
README.md View File

22
 | showList | boolean |   true  | false     | 是否显示评论列表|
22
 | showList | boolean |   true  | false     | 是否显示评论列表|
23
 | showEditor | boolean |   true  | false     | 是否显示评论输入框|
23
 | showEditor | boolean |   true  | false     | 是否显示评论输入框|
24
 | showHeader | boolean |   true  | false     | 是否显示评论顶部的提示|
24
 | showHeader | boolean |   true  | false     | 是否显示评论顶部的提示|
25
+| token | string |     | false     | token,用于身份认证,非必须。默认使用 cookie|
25
 
26
 
26
 
27
 
27
 
28
 

+ 40
- 24
lib/App.js View File

29
 
29
 
30
 var _propTypes2 = _interopRequireDefault(_propTypes);
30
 var _propTypes2 = _interopRequireDefault(_propTypes);
31
 
31
 
32
-var _axios = require("./axios");
32
+var _axios = require("axios");
33
 
33
 
34
 var _axios2 = _interopRequireDefault(_axios);
34
 var _axios2 = _interopRequireDefault(_axios);
35
 
35
 
98
   }
98
   }
99
 
99
 
100
   _createClass(App, [{
100
   _createClass(App, [{
101
+    key: "componentWillMount",
102
+    value: function componentWillMount() {
103
+      this.axios = _axios2.default;
104
+      this.axios.defaults.withCredentials = true;
105
+      if (this.props.token) {
106
+        this.axios.defaults.headers.common["Authorization"] = "Bearer " + this.props.token;
107
+      }
108
+    }
109
+  }, {
101
     key: "componentDidMount",
110
     key: "componentDidMount",
102
     value: function componentDidMount() {}
111
     value: function componentDidMount() {}
103
 
112
 
135
           type = _props.type,
144
           type = _props.type,
136
           businessId = _props.businessId;
145
           businessId = _props.businessId;
137
 
146
 
138
-      _axios2.default.get(API + "/comments?type=" + type + "&business_id=" + businessId + "&page=" + page + "&limit=" + _constant.LIMIT).then(function (response) {
147
+      this.axios.get(API + "/comments?type=" + type + "&business_id=" + businessId + "&page=" + page + "&limit=" + _constant.LIMIT).then(function (response) {
139
         var _response$data = response.data,
148
         var _response$data = response.data,
140
             list = _response$data.list,
149
             list = _response$data.list,
141
             page = _response$data.page,
150
             page = _response$data.page,
191
       this.handleChangeLoading("sGetReply", true);
200
       this.handleChangeLoading("sGetReply", true);
192
       var API = this.props.API;
201
       var API = this.props.API;
193
 
202
 
194
-      _axios2.default.get(API + "/replies?comment_id=" + commentId + "&page=" + page + "&limit=" + _constant.LIMIT).then(function (response) {
203
+      this.axios.get(API + "/replies?comment_id=" + commentId + "&page=" + page + "&limit=" + _constant.LIMIT).then(function (response) {
195
         if (!response.data.list) {
204
         if (!response.data.list) {
196
           _message3.default.info("没有更多数据了!");
205
           _message3.default.info("没有更多数据了!");
197
         }
206
         }
242
       var _ref3 = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {},
251
       var _ref3 = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {},
243
           content = _ref3.content;
252
           content = _ref3.content;
244
 
253
 
254
+      var cb = arguments[1];
255
+
245
       if (!content) return _message3.default.error("评论内容不能为空 ");
256
       if (!content) return _message3.default.error("评论内容不能为空 ");
246
       this.handleChangeLoading("sCreateComment", true);
257
       this.handleChangeLoading("sCreateComment", true);
247
       var _props2 = this.props,
258
       var _props2 = this.props,
249
           type = _props2.type,
260
           type = _props2.type,
250
           businessId = _props2.businessId;
261
           businessId = _props2.businessId;
251
 
262
 
252
-      (0, _axios2.default)(API + "/comments", {
263
+      this.axios(API + "/comments", {
253
         method: "post",
264
         method: "post",
254
         data: {
265
         data: {
255
           type: type,
266
           type: type,
259
         withCredentials: true
270
         withCredentials: true
260
       }).then(function (response) {
271
       }).then(function (response) {
261
         _message3.default.success("评论成功!");
272
         _message3.default.success("评论成功!");
273
+        if ((0, _helper.isFunction)(cb)) cb();
262
         // 将数据写入到 list 中
274
         // 将数据写入到 list 中
263
         // 临时插入
275
         // 临时插入
264
         // 等到获取数据之后,删除临时数据
276
         // 等到获取数据之后,删除临时数据
292
     value: function sCreateReply(data, cb) {
304
     value: function sCreateReply(data, cb) {
293
       var _this5 = this;
305
       var _this5 = this;
294
 
306
 
295
-      console.log("list: ", this.state.list);
296
-
297
       if (!data.content) return _message3.default.error("回复内容不能为空 ");
307
       if (!data.content) return _message3.default.error("回复内容不能为空 ");
298
       this.handleChangeLoading("sCreateReply", true);
308
       this.handleChangeLoading("sCreateReply", true);
299
       var API = this.props.API;
309
       var API = this.props.API;
300
 
310
 
301
-      (0, _axios2.default)(API + "/replies", {
311
+      this.axios(API + "/replies", {
302
         method: "post",
312
         method: "post",
303
         data: data,
313
         data: data,
304
         withCredentials: true
314
         withCredentials: true
344
       this.handleChangeLoading("sCommentFavor", true);
354
       this.handleChangeLoading("sCommentFavor", true);
345
       var API = this.props.API;
355
       var API = this.props.API;
346
 
356
 
347
-      (0, _axios2.default)(API + "/comments/" + commentId + "/favor", {
357
+      this.axios(API + "/comments/" + commentId + "/favor", {
348
         method: favored ? "delete" : "put",
358
         method: favored ? "delete" : "put",
349
         withCredentials: true
359
         withCredentials: true
350
       }).then(function (response) {
360
       }).then(function (response) {
382
       var _this7 = this;
392
       var _this7 = this;
383
 
393
 
384
       this.handleChangeLoading("sReplyFavor", true);
394
       this.handleChangeLoading("sReplyFavor", true);
385
-      console.log("replyId, commentId ", replyId, commentId);
386
-
387
       var API = this.props.API;
395
       var API = this.props.API;
388
 
396
 
389
-      (0, _axios2.default)(API + "/replies/" + replyId + "/favor", {
397
+      this.axios(API + "/replies/" + replyId + "/favor", {
390
         method: favored ? "delete" : "put",
398
         method: favored ? "delete" : "put",
399
+        data: {
400
+          comment_id: commentId
401
+        },
391
         withCredentials: true
402
         withCredentials: true
392
       }).then(function (response) {
403
       }).then(function (response) {
393
-        console.log("response: ", response);
394
-
395
         _message3.default.success(favored ? "取消点赞成功!" : "点赞成功!");
404
         _message3.default.success(favored ? "取消点赞成功!" : "点赞成功!");
396
-        // TODO: (2018.07.20 node) 对评论的回复点赞,报错
397
-        // // 更新 list 中的该项数据的 favored
398
-        // const list = this.state.list.map(item => {
399
-        //   if (item.id === replyId) {
400
-        //     item.favored = !favored;
401
-        //     item.favor_count += favored ? -1 : 1;
402
-        //   }
403
-        //   return item;
404
-        // });
405
-        // this.setState({ list });
405
+        // 更新 list 中的该项数据的 favored
406
+        var list = _this7.state.list.map(function (item) {
407
+          if (item.id === commentId) {
408
+            item.replies = item.replies.map(function (r) {
409
+              if (r.id === replyId) {
410
+                r.favored = !favored;
411
+                // r.favor_count =  response.data.favor_count;
412
+                // 点赞数 +1,而不是使用后端返回的点赞数
413
+                // 不然如果返回的不是增加 1,用户可能以为程序错误
414
+                r.favor_count += favored ? -1 : 1;
415
+              }
416
+              return r;
417
+            });
418
+          }
419
+          return item;
420
+        });
421
+        _this7.setState({ list: list });
406
       }).catch(function (error) {
422
       }).catch(function (error) {
407
         if (error.response && error.response.data && error.response.data.msg) {
423
         if (error.response && error.response.data && error.response.data.msg) {
408
           _message3.default.error(_lang2.default[error.response.data.msg] || _constant.ERROR_DEFAULT);
424
           _message3.default.error(_lang2.default[error.response.data.msg] || _constant.ERROR_DEFAULT);
426
       this.handleChangeLoading("sOssSts", true);
442
       this.handleChangeLoading("sOssSts", true);
427
       var API = this.props.API;
443
       var API = this.props.API;
428
 
444
 
429
-      _axios2.default.get(API + "/oss/sts").then(function (response) {
445
+      this.axios.get(API + "/oss/sts").then(function (response) {
430
         _this8.setState({ oss: _extends({}, response.data) });
446
         _this8.setState({ oss: _extends({}, response.data) });
431
       }).catch(function (error) {
447
       }).catch(function (error) {
432
         if (error.response && error.response.data && error.response.data.msg) {
448
         if (error.response && error.response.data && error.response.data.msg) {

+ 1
- 1
lib/App.js.map
File diff suppressed because it is too large
View File


+ 1
- 0
lib/axios.js View File

11
 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
11
 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
12
 
12
 
13
 _axios2.default.defaults.withCredentials = true;
13
 _axios2.default.defaults.withCredentials = true;
14
+_axios2.default.defaults.headers.common["Authorization"] = "Bearer ";
14
 
15
 
15
 exports.default = _axios2.default;
16
 exports.default = _axios2.default;
16
 //# sourceMappingURL=axios.js.map
17
 //# sourceMappingURL=axios.js.map

+ 1
- 1
lib/axios.js.map View File

1
-{"version":3,"sources":["../src/axios.js"],"names":["axios","defaults","withCredentials"],"mappings":";;;;;;AAAA;;;;;;AAEAA,gBAAMC,QAAN,CAAeC,eAAf,GAAiC,IAAjC;;kBAEeF,e","file":"axios.js","sourcesContent":["import axios from \"axios\";\n\naxios.defaults.withCredentials = true;\n\nexport default axios;\n"]}
1
+{"version":3,"sources":["../src/axios.js"],"names":["axios","defaults","withCredentials","headers","common"],"mappings":";;;;;;AAAA;;;;;;AAEAA,gBAAMC,QAAN,CAAeC,eAAf,GAAiC,IAAjC;AACAF,gBAAMC,QAAN,CAAeE,OAAf,CAAuBC,MAAvB,CAA8B,eAA9B,IAAiD,SAAjD;;kBAEeJ,e","file":"axios.js","sourcesContent":["import axios from \"axios\";\n\naxios.defaults.withCredentials = true;\naxios.defaults.headers.common[\"Authorization\"] = \"Bearer \";\n\nexport default axios;\n"]}

+ 9
- 2
lib/components/CommentInput/index.js View File

41
     return _this;
41
     return _this;
42
   }
42
   }
43
 
43
 
44
+  /**
45
+   * 提交评论
46
+   * @param {string} value 需要提交的评论的值
47
+   * @param {function} cb 提交成功后的回掉
48
+   */
49
+
50
+
44
   _createClass(CommentInput, [{
51
   _createClass(CommentInput, [{
45
     key: "handleSubmit",
52
     key: "handleSubmit",
46
-    value: function handleSubmit(value) {
53
+    value: function handleSubmit(value, cb) {
47
       var _props = this.props,
54
       var _props = this.props,
48
           action = _props.action,
55
           action = _props.action,
49
           commentId = _props.commentId,
56
           commentId = _props.commentId,
53
       if (action === "comment") {
60
       if (action === "comment") {
54
         this.props.app.sCreateComment({
61
         this.props.app.sCreateComment({
55
           content: value
62
           content: value
56
-        });
63
+        }, cb);
57
       } else if (action === "reply") {
64
       } else if (action === "reply") {
58
         this.props.app.sCreateReply({
65
         this.props.app.sCreateReply({
59
           comment_id: commentId,
66
           comment_id: commentId,

+ 1
- 1
lib/components/CommentInput/index.js.map View File

1
-{"version":3,"sources":["../../../src/components/CommentInput/index.js"],"names":["CommentInput","props","state","handleSubmit","bind","value","action","commentId","replyId","callback","app","sCreateComment","content","sCreateReply","comment_id","reply_id","childrenWithProps","React","Children","map","cloneElement","child","onSubmit","rows","Component","propTypes","PropTypes","oneOf","defaultProps"],"mappings":";;;;;;;;;;AAAA;;;;AACA;;;;AACA;;;;;;;;;;;;IAEMA,Y;;;AACJ,wBAAYC,KAAZ,EAAmB;AAAA;;AAAA,4HACXA,KADW;;AAEjB,UAAKC,KAAL,GAAa,EAAb;AACA,UAAKC,YAAL,GAAoB,MAAKA,YAAL,CAAkBC,IAAlB,OAApB;AAHiB;AAIlB;;;;iCAEYC,K,EAAO;AAAA,mBAC+B,KAAKJ,KADpC;AAAA,UACVK,MADU,UACVA,MADU;AAAA,UACFC,SADE,UACFA,SADE;AAAA,UACSC,OADT,UACSA,OADT;AAAA,UACkBC,QADlB,UACkBA,QADlB;;AAElB,UAAIH,WAAW,SAAf,EAA0B;AACxB,aAAKL,KAAL,CAAWS,GAAX,CAAeC,cAAf,CAA8B;AAC5BC,mBAASP;AADmB,SAA9B;AAGD,OAJD,MAIO,IAAIC,WAAW,OAAf,EAAwB;AAC7B,aAAKL,KAAL,CAAWS,GAAX,CAAeG,YAAf,CACE;AACEC,sBAAYP,SADd;AAEEK,mBAASP;AAFX,SADF,EAKE;AAAA,iBAAMI,YAAYA,UAAlB;AAAA,SALF;AAOD,OARM,MAQA,IAAIH,WAAW,cAAf,EAA+B;AACpC,aAAKL,KAAL,CAAWS,GAAX,CAAeG,YAAf,CACE;AACEC,sBAAYP,SADd;AAEEK,mBAASP,KAFX;AAGEU,oBAAUP;AAHZ,SADF,EAME;AAAA,iBAAMC,YAAYA,UAAlB;AAAA,SANF;AAQD;AACF;;;6BAEQ;AAAA;;AACP,UAAMO,oBAAoBC,gBAAMC,QAAN,CAAeC,GAAf,CAAmB,KAAKlB,KAAL,CAAWW,OAA9B,EAAuC,iBAAS;AACxE,eAAOK,gBAAMG,YAAN,CAAmBC,KAAnB;AACL;AACA;AACA;AACA;AACAC,oBAAU,OAAKnB;AALV,WAMFkB,MAAMpB,KANJ;AAOL;AACAsB,gBACE,OAAKtB,KAAL,CAAWK,MAAX,KAAsB,SAAtB,GACIe,MAAMpB,KAAN,CAAYsB,IADhB,GAEIF,MAAMpB,KAAN,CAAYsB,IAAZ,GAAmB;AAXpB,WAAP;AAaD,OAdyB,CAA1B;;AAgBA,aAAO;AAAA;AAAA;AAAMP;AAAN,OAAP;AACD;;;;EAnDwBQ,gB;;AAsD3BxB,aAAayB,SAAb,GAAyB;AACvB;AACA;AACA;AACAnB,UAAQoB,oBAAUC,KAAV,CAAgB,CAAC,SAAD,EAAY,OAAZ,EAAqB,cAArB,CAAhB;AAJe,CAAzB;;AAOA3B,aAAa4B,YAAb,GAA4B;AAC1BtB,UAAQ;AADkB,CAA5B;;kBAIe,uBAAQN,YAAR,C","file":"index.js","sourcesContent":["import React, { Component } from \"react\";\nimport PropTypes from \"prop-types\";\nimport Comment from \"../../Comment\";\n\nclass CommentInput extends Component {\n  constructor(props) {\n    super(props);\n    this.state = {};\n    this.handleSubmit = this.handleSubmit.bind(this);\n  }\n\n  handleSubmit(value) {\n    const { action, commentId, replyId, callback } = this.props;\n    if (action === \"comment\") {\n      this.props.app.sCreateComment({\n        content: value\n      });\n    } else if (action === \"reply\") {\n      this.props.app.sCreateReply(\n        {\n          comment_id: commentId,\n          content: value\n        },\n        () => callback && callback()\n      );\n    } else if (action === \"replyToReply\") {\n      this.props.app.sCreateReply(\n        {\n          comment_id: commentId,\n          content: value,\n          reply_id: replyId\n        },\n        () => callback && callback()\n      );\n    }\n  }\n\n  render() {\n    const childrenWithProps = React.Children.map(this.props.content, child => {\n      return React.cloneElement(child, {\n        // 编辑器本身不提交值,但 CommentInput 会提交\n        // CommentInput 主要是负责评论的业务逻辑,提交评论和回复\n        // 默认使用 CommentInput 的 onSubmit 来提交评论\n        // 但也可以使用 Editor 的 props 来覆盖 onSubmit\n        onSubmit: this.handleSubmit,\n        ...child.props,\n        // 如果当前的编辑器不是“评论”,则编辑器高度减小一些\n        rows:\n          this.props.action === \"comment\"\n            ? child.props.rows\n            : child.props.rows - 1\n      });\n    });\n\n    return <div>{childrenWithProps}</div>;\n  }\n}\n\nCommentInput.propTypes = {\n  // comment 评论\n  // reply 评论的回复\n  // replyToReply 回复的回复\n  action: PropTypes.oneOf([\"comment\", \"reply\", \"replyToReply\"])\n};\n\nCommentInput.defaultProps = {\n  action: \"comment\"\n};\n\nexport default Comment(CommentInput);\n"]}
1
+{"version":3,"sources":["../../../src/components/CommentInput/index.js"],"names":["CommentInput","props","state","handleSubmit","bind","value","cb","action","commentId","replyId","callback","app","sCreateComment","content","sCreateReply","comment_id","reply_id","childrenWithProps","React","Children","map","cloneElement","child","onSubmit","rows","Component","propTypes","PropTypes","oneOf","defaultProps"],"mappings":";;;;;;;;;;AAAA;;;;AACA;;;;AACA;;;;;;;;;;;;IAEMA,Y;;;AACJ,wBAAYC,KAAZ,EAAmB;AAAA;;AAAA,4HACXA,KADW;;AAEjB,UAAKC,KAAL,GAAa,EAAb;AACA,UAAKC,YAAL,GAAoB,MAAKA,YAAL,CAAkBC,IAAlB,OAApB;AAHiB;AAIlB;;AAED;;;;;;;;;iCAKaC,K,EAAOC,E,EAAI;AAAA,mBAC2B,KAAKL,KADhC;AAAA,UACdM,MADc,UACdA,MADc;AAAA,UACNC,SADM,UACNA,SADM;AAAA,UACKC,OADL,UACKA,OADL;AAAA,UACcC,QADd,UACcA,QADd;;AAEtB,UAAIH,WAAW,SAAf,EAA0B;AACxB,aAAKN,KAAL,CAAWU,GAAX,CAAeC,cAAf,CACE;AACEC,mBAASR;AADX,SADF,EAIEC,EAJF;AAMD,OAPD,MAOO,IAAIC,WAAW,OAAf,EAAwB;AAC7B,aAAKN,KAAL,CAAWU,GAAX,CAAeG,YAAf,CACE;AACEC,sBAAYP,SADd;AAEEK,mBAASR;AAFX,SADF,EAKE;AAAA,iBAAMK,YAAYA,UAAlB;AAAA,SALF;AAOD,OARM,MAQA,IAAIH,WAAW,cAAf,EAA+B;AACpC,aAAKN,KAAL,CAAWU,GAAX,CAAeG,YAAf,CACE;AACEC,sBAAYP,SADd;AAEEK,mBAASR,KAFX;AAGEW,oBAAUP;AAHZ,SADF,EAME;AAAA,iBAAMC,YAAYA,UAAlB;AAAA,SANF;AAQD;AACF;;;6BAEQ;AAAA;;AACP,UAAMO,oBAAoBC,gBAAMC,QAAN,CAAeC,GAAf,CAAmB,KAAKnB,KAAL,CAAWY,OAA9B,EAAuC,iBAAS;AACxE,eAAOK,gBAAMG,YAAN,CAAmBC,KAAnB;AACL;AACA;AACA;AACA;AACAC,oBAAU,OAAKpB;AALV,WAMFmB,MAAMrB,KANJ;AAOL;AACAuB,gBACE,OAAKvB,KAAL,CAAWM,MAAX,KAAsB,SAAtB,GACIe,MAAMrB,KAAN,CAAYuB,IADhB,GAEIF,MAAMrB,KAAN,CAAYuB,IAAZ,GAAmB;AAXpB,WAAP;AAaD,OAdyB,CAA1B;;AAgBA,aAAO;AAAA;AAAA;AAAMP;AAAN,OAAP;AACD;;;;EA3DwBQ,gB;;AA8D3BzB,aAAa0B,SAAb,GAAyB;AACvB;AACA;AACA;AACAnB,UAAQoB,oBAAUC,KAAV,CAAgB,CAAC,SAAD,EAAY,OAAZ,EAAqB,cAArB,CAAhB;AAJe,CAAzB;;AAOA5B,aAAa6B,YAAb,GAA4B;AAC1BtB,UAAQ;AADkB,CAA5B;;kBAIe,uBAAQP,YAAR,C","file":"index.js","sourcesContent":["import React, { Component } from \"react\";\nimport PropTypes from \"prop-types\";\nimport Comment from \"../../Comment\";\n\nclass CommentInput extends Component {\n  constructor(props) {\n    super(props);\n    this.state = {};\n    this.handleSubmit = this.handleSubmit.bind(this);\n  }\n\n  /**\n   * 提交评论\n   * @param {string} value 需要提交的评论的值\n   * @param {function} cb 提交成功后的回掉\n   */\n  handleSubmit(value, cb) {\n    const { action, commentId, replyId, callback } = this.props;\n    if (action === \"comment\") {\n      this.props.app.sCreateComment(\n        {\n          content: value\n        },\n        cb\n      );\n    } else if (action === \"reply\") {\n      this.props.app.sCreateReply(\n        {\n          comment_id: commentId,\n          content: value\n        },\n        () => callback && callback()\n      );\n    } else if (action === \"replyToReply\") {\n      this.props.app.sCreateReply(\n        {\n          comment_id: commentId,\n          content: value,\n          reply_id: replyId\n        },\n        () => callback && callback()\n      );\n    }\n  }\n\n  render() {\n    const childrenWithProps = React.Children.map(this.props.content, child => {\n      return React.cloneElement(child, {\n        // 编辑器本身不提交值,但 CommentInput 会提交\n        // CommentInput 主要是负责评论的业务逻辑,提交评论和回复\n        // 默认使用 CommentInput 的 onSubmit 来提交评论\n        // 但也可以使用 Editor 的 props 来覆盖 onSubmit\n        onSubmit: this.handleSubmit,\n        ...child.props,\n        // 如果当前的编辑器不是“评论”,则编辑器高度减小一些\n        rows:\n          this.props.action === \"comment\"\n            ? child.props.rows\n            : child.props.rows - 1\n      });\n    });\n\n    return <div>{childrenWithProps}</div>;\n  }\n}\n\nCommentInput.propTypes = {\n  // comment 评论\n  // reply 评论的回复\n  // replyToReply 回复的回复\n  action: PropTypes.oneOf([\"comment\", \"reply\", \"replyToReply\"])\n};\n\nCommentInput.defaultProps = {\n  action: \"comment\"\n};\n\nexport default Comment(CommentInput);\n"]}

+ 3
- 0
lib/components/ContentItem/index.css View File

29
   margin-left: 5px;
29
   margin-left: 5px;
30
   cursor: pointer;
30
   cursor: pointer;
31
 }
31
 }
32
+.comment-favor {
33
+  font-size: 20px;
34
+}
32
 .comment-favored {
35
 .comment-favored {
33
   color: #4a90e2;
36
   color: #4a90e2;
34
 }
37
 }

+ 1
- 1
lib/components/ContentItem/index.js View File

193
               },
193
               },
194
               _react2.default.createElement(_icon2.default, {
194
               _react2.default.createElement(_icon2.default, {
195
                 type: "like-o",
195
                 type: "like-o",
196
-                className: content.favored ? "comment-favored" : ""
196
+                className: content.favored ? "comment-favor comment-favored" : "comment-favor"
197
               }),
197
               }),
198
               "\xA0",
198
               "\xA0",
199
               content.favor_count
199
               content.favor_count

+ 1
- 1
lib/components/ContentItem/index.js.map
File diff suppressed because it is too large
View File


+ 19
- 10
lib/components/Editor/index.js View File

147
     }
147
     }
148
 
148
 
149
     /**
149
     /**
150
-     * 上传文件 TODO:
150
+     * 上传文件
151
      * @param {object} param 文件对象
151
      * @param {object} param 文件对象
152
      */
152
      */
153
 
153
 
171
   }, {
171
   }, {
172
     key: "handleSubmit",
172
     key: "handleSubmit",
173
     value: function handleSubmit() {
173
     value: function handleSubmit() {
174
+      var _this2 = this;
175
+
174
       var _state = this.state,
176
       var _state = this.state,
175
           value = _state.value,
177
           value = _state.value,
176
           fileMap = _state.fileMap,
178
           fileMap = _state.fileMap,
182
           value += "[" + _constant.OSS_LINK + fileMap[item.uid] + "]";
184
           value += "[" + _constant.OSS_LINK + fileMap[item.uid] + "]";
183
         });
185
         });
184
       }
186
       }
185
-      this.props.onSubmit(value);
187
+      this.props.onSubmit(value, function () {
188
+        _this2.setState({
189
+          showUpload: false,
190
+          value: "",
191
+          fileList: [],
192
+          fileMap: {}
193
+        });
194
+      });
186
     }
195
     }
187
   }, {
196
   }, {
188
     key: "render",
197
     key: "render",
189
     value: function render() {
198
     value: function render() {
190
-      var _this2 = this;
199
+      var _this3 = this;
191
 
200
 
192
       var _props = this.props,
201
       var _props = this.props,
193
           value = _props.value,
202
           value = _props.value,
202
           emojiToolIcon = _props.emojiToolIcon,
211
           emojiToolIcon = _props.emojiToolIcon,
203
           imageToolIcon = _props.imageToolIcon;
212
           imageToolIcon = _props.imageToolIcon;
204
 
213
 
205
-
206
       var handleSubmit = this.handleSubmit;
214
       var handleSubmit = this.handleSubmit;
215
+      var disabledSubmit = btnDisabled || !this.props.value && !this.state.value && !this.state.fileList.length;
207
       return _react2.default.createElement(
216
       return _react2.default.createElement(
208
         "div",
217
         "div",
209
         { className: "comment-editor" },
218
         { className: "comment-editor" },
210
         _react2.default.createElement(TextArea, {
219
         _react2.default.createElement(TextArea, {
211
           value: value || this.state.value,
220
           value: value || this.state.value,
212
           onChange: function onChange(e) {
221
           onChange: function onChange(e) {
213
-            return _this2.handleChange(e.target.value);
222
+            return _this3.handleChange(e.target.value);
214
           },
223
           },
215
           rows: rows,
224
           rows: rows,
216
           placeholder: placeholder
225
           placeholder: placeholder
271
                   _react2.default.createElement(_icon2.default, {
280
                   _react2.default.createElement(_icon2.default, {
272
                     type: "close",
281
                     type: "close",
273
                     onClick: function onClick() {
282
                     onClick: function onClick() {
274
-                      return _this2.handleShowUpload(false);
283
+                      return _this3.handleShowUpload(false);
275
                     },
284
                     },
276
                     style: {
285
                     style: {
277
                       float: "right",
286
                       float: "right",
283
               },
292
               },
284
               imageToolIcon ? _react2.default.cloneElement(imageToolIcon, {
293
               imageToolIcon ? _react2.default.cloneElement(imageToolIcon, {
285
                 onClick: function onClick() {
294
                 onClick: function onClick() {
286
-                  return _this2.handleShowUpload(true);
295
+                  return _this3.handleShowUpload(true);
287
                 }
296
                 }
288
               }) : _react2.default.createElement(_icon2.default, {
297
               }) : _react2.default.createElement(_icon2.default, {
289
                 type: "picture",
298
                 type: "picture",
290
                 className: "comment-toolbar-icon",
299
                 className: "comment-toolbar-icon",
291
                 style: { marginLeft: 10 },
300
                 style: { marginLeft: 10 },
292
                 onClick: function onClick() {
301
                 onClick: function onClick() {
293
-                  return _this2.handleShowUpload(true);
302
+                  return _this3.handleShowUpload(true);
294
                 }
303
                 }
295
               })
304
               })
296
             )
305
             )
304
               _button2.default,
313
               _button2.default,
305
               {
314
               {
306
                 onClick: function onClick() {
315
                 onClick: function onClick() {
307
-                  return _this2.handleSubmit();
316
+                  return _this3.handleSubmit();
308
                 },
317
                 },
309
                 type: "primary",
318
                 type: "primary",
310
                 loading: btnLoading,
319
                 loading: btnLoading,
311
-                disabled: btnDisabled
320
+                disabled: disabledSubmit
312
               },
321
               },
313
               btnSubmitText
322
               btnSubmitText
314
             )
323
             )

+ 1
- 1
lib/components/Editor/index.js.map
File diff suppressed because it is too large
View File


+ 4
- 0
lib/index.js View File

25
 function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
25
 function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
26
 
26
 
27
 function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
27
 function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
28
+// e.g.
29
+// import { Button, Icon } from "antd";
30
+
28
 
31
 
29
 var Index = function (_Component) {
32
 var Index = function (_Component) {
30
   _inherits(Index, _Component);
33
   _inherits(Index, _Component);
70
         _react2.default.createElement(_App.Editor, null)
73
         _react2.default.createElement(_App.Editor, null)
71
       );
74
       );
72
 
75
 
76
+      // e.g.
73
       // 复杂的用户法
77
       // 复杂的用户法
74
       // const props = {
78
       // const props = {
75
       //   type: 1,
79
       //   type: 1,

+ 1
- 1
lib/index.js.map View File

1
-{"version":3,"sources":["../src/index.js"],"names":["Index","props","state","value","handleChangeValue","bind","handleChangeSubmit","setState","console","log","loading","setTimeout","Component","ReactDOM","render","document","getElementById"],"mappings":";;;;AAAA;;;;AACA;;;;AAEA;;;;AACA;;;;;;;;;;;;IAEMA,K;;;AACJ,iBAAYC,KAAZ,EAAmB;AAAA;;AAAA,8GACXA,KADW;;AAEjB,UAAKC,KAAL,GAAa;AACXC,aAAO;AADI,KAAb;AAGA,UAAKC,iBAAL,GAAyB,MAAKA,iBAAL,CAAuBC,IAAvB,OAAzB;AACA,UAAKC,kBAAL,GAA0B,MAAKA,kBAAL,CAAwBD,IAAxB,OAA1B;AANiB;AAOlB;;;;sCAEiBF,K,EAAO;AACvB,WAAKI,QAAL,CAAc,EAAEJ,YAAF,EAAd;AACAK,cAAQC,GAAR,CAAY,2BAAZ,EAAyCN,KAAzC;AACD;;;uCAEkBA,K,EAAO;AAAA;;AACxB,WAAKI,QAAL,CAAc,EAAEG,SAAS,IAAX,EAAd,EAAiC,YAAM;AACrCC,mBAAW,YAAM;AACf,iBAAKJ,QAAL,CAAc,EAAEG,SAAS,KAAX,EAAd;AACD,SAFD,EAEG,IAFH;AAGD,OAJD;AAKAF,cAAQC,GAAR,CAAY,gBAAZ,EAA8BN,KAA9B;AACD;;;6BAEQ;AACP;AACA,aACE;AAAC,qBAAD;AAAA,UAAK,MAAM,CAAX,EAAc,YAAW,MAAzB;AACE,sCAAC,WAAD;AADF,OADF;;AAMA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACD;;;;EAtEiBS,gB;;AAyEpBC,mBAASC,MAAT,CAAgB,8BAAC,KAAD,OAAhB,EAA2BC,SAASC,cAAT,CAAwB,cAAxB,CAA3B;AACA","file":"index.js","sourcesContent":["import React, { Component } from \"react\";\nimport ReactDOM from \"react-dom\";\nimport { Button, Icon } from \"antd\";\nimport App, { Editor } from \"./App\";\nimport registerServiceWorker from \"./registerServiceWorker\";\n\nclass Index extends Component {\n  constructor(props) {\n    super(props);\n    this.state = {\n      value: \"\"\n    };\n    this.handleChangeValue = this.handleChangeValue.bind(this);\n    this.handleChangeSubmit = this.handleChangeSubmit.bind(this);\n  }\n\n  handleChangeValue(value) {\n    this.setState({ value });\n    console.log(\"handleChangeValue value: \", value);\n  }\n\n  handleChangeSubmit(value) {\n    this.setState({ loading: true }, () => {\n      setTimeout(() => {\n        this.setState({ loading: false });\n      }, 2000);\n    });\n    console.log(\"submit value: \", value);\n  }\n\n  render() {\n    // 最简单的用法\n    return (\n      <App type={1} businessId=\"test\">\n        <Editor />\n      </App>\n    );\n\n    // 复杂的用户法\n    // const props = {\n    //   type: 1,\n    //   businessId: \"1\",\n    //   API: \"http://api.links123.net/comment/v1\",\n    //   showList: true\n    // };\n\n    // const editorProps = {\n    //   showEmoji: true,\n    //   placeholder: \"说点什么吧\",\n    //   rows: 5,\n    //   btnLoading: this.state.loading,\n    //   btnDisable: this.state.loading,\n    //   btnSubmitText: \"提交\",\n    //   value: this.state.value,\n    //   onChange: v => this.handleChangeValue(v),\n    //   onSubmit: v => this.handleChangeSubmit(v),\n    //   button: (\n    //     <Button\n    //       type=\"primary\"\n    //       ghost\n    //       // onClick={() => console.log('click btn: ', this.state.value)}\n    //     >\n    //       自定义按钮\n    //     </Button>\n    //   ),\n    //   emojiToolIcon: <Icon type=\"smile\" style={{ fontSize: 23 }} />,\n    //   imageToolIcon: (\n    //     <Icon type=\"cloud-upload-o\" style={{ fontSize: 25, marginLeft: 10 }} />\n    //   )\n    // };\n\n    // return (\n    //   <App {...props}>\n    //     <Editor {...editorProps} />\n    //   </App>\n    // );\n  }\n}\n\nReactDOM.render(<Index />, document.getElementById(\"root-comment\"));\nregisterServiceWorker();\n"]}
1
+{"version":3,"sources":["../src/index.js"],"names":["Index","props","state","value","handleChangeValue","bind","handleChangeSubmit","setState","console","log","loading","setTimeout","Component","ReactDOM","render","document","getElementById"],"mappings":";;;;AAAA;;;;AACA;;;;AAGA;;;;AACA;;;;;;;;;;;AAHA;AACA;;;IAIMA,K;;;AACJ,iBAAYC,KAAZ,EAAmB;AAAA;;AAAA,8GACXA,KADW;;AAEjB,UAAKC,KAAL,GAAa;AACXC,aAAO;AADI,KAAb;AAGA,UAAKC,iBAAL,GAAyB,MAAKA,iBAAL,CAAuBC,IAAvB,OAAzB;AACA,UAAKC,kBAAL,GAA0B,MAAKA,kBAAL,CAAwBD,IAAxB,OAA1B;AANiB;AAOlB;;;;sCAEiBF,K,EAAO;AACvB,WAAKI,QAAL,CAAc,EAAEJ,YAAF,EAAd;AACAK,cAAQC,GAAR,CAAY,2BAAZ,EAAyCN,KAAzC;AACD;;;uCAEkBA,K,EAAO;AAAA;;AACxB,WAAKI,QAAL,CAAc,EAAEG,SAAS,IAAX,EAAd,EAAiC,YAAM;AACrCC,mBAAW,YAAM;AACf,iBAAKJ,QAAL,CAAc,EAAEG,SAAS,KAAX,EAAd;AACD,SAFD,EAEG,IAFH;AAGD,OAJD;AAKAF,cAAQC,GAAR,CAAY,gBAAZ,EAA8BN,KAA9B;AACD;;;6BAEQ;AACP;AACA,aACE;AAAC,qBAAD;AAAA,UAAK,MAAM,CAAX,EAAc,YAAW,MAAzB;AACE,sCAAC,WAAD;AADF,OADF;;AAMA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACD;;;;EAvEiBS,gB;;AA0EpBC,mBAASC,MAAT,CAAgB,8BAAC,KAAD,OAAhB,EAA2BC,SAASC,cAAT,CAAwB,cAAxB,CAA3B;AACA","file":"index.js","sourcesContent":["import React, { Component } from \"react\";\nimport ReactDOM from \"react-dom\";\n// e.g.\n// import { Button, Icon } from \"antd\";\nimport App, { Editor } from \"./App\";\nimport registerServiceWorker from \"./registerServiceWorker\";\n\nclass Index extends Component {\n  constructor(props) {\n    super(props);\n    this.state = {\n      value: \"\"\n    };\n    this.handleChangeValue = this.handleChangeValue.bind(this);\n    this.handleChangeSubmit = this.handleChangeSubmit.bind(this);\n  }\n\n  handleChangeValue(value) {\n    this.setState({ value });\n    console.log(\"handleChangeValue value: \", value);\n  }\n\n  handleChangeSubmit(value) {\n    this.setState({ loading: true }, () => {\n      setTimeout(() => {\n        this.setState({ loading: false });\n      }, 2000);\n    });\n    console.log(\"submit value: \", value);\n  }\n\n  render() {\n    // 最简单的用法\n    return (\n      <App type={1} businessId=\"test\">\n        <Editor />\n      </App>\n    );\n\n    // e.g.\n    // 复杂的用户法\n    // const props = {\n    //   type: 1,\n    //   businessId: \"1\",\n    //   API: \"http://api.links123.net/comment/v1\",\n    //   showList: true\n    // };\n\n    // const editorProps = {\n    //   showEmoji: true,\n    //   placeholder: \"说点什么吧\",\n    //   rows: 5,\n    //   btnLoading: this.state.loading,\n    //   btnDisable: this.state.loading,\n    //   btnSubmitText: \"提交\",\n    //   value: this.state.value,\n    //   onChange: v => this.handleChangeValue(v),\n    //   onSubmit: v => this.handleChangeSubmit(v),\n    //   button: (\n    //     <Button\n    //       type=\"primary\"\n    //       ghost\n    //       // onClick={() => console.log('click btn: ', this.state.value)}\n    //     >\n    //       自定义按钮\n    //     </Button>\n    //   ),\n    //   emojiToolIcon: <Icon type=\"smile\" style={{ fontSize: 23 }} />,\n    //   imageToolIcon: (\n    //     <Icon type=\"cloud-upload-o\" style={{ fontSize: 25, marginLeft: 10 }} />\n    //   )\n    // };\n\n    // return (\n    //   <App {...props}>\n    //     <Editor {...editorProps} />\n    //   </App>\n    // );\n  }\n}\n\nReactDOM.render(<Index />, document.getElementById(\"root-comment\"));\nregisterServiceWorker();\n"]}

+ 2
- 2
package.json View File

1
 {
1
 {
2
   "name": "comment",
2
   "name": "comment",
3
-  "version": "0.2.0",
3
+  "version": "0.2.1",
4
   "main": "lib/App.js",
4
   "main": "lib/App.js",
5
   "description": "通用评论",
5
   "description": "通用评论",
6
   "keywords": [
6
   "keywords": [
31
   },
31
   },
32
   "scripts": {
32
   "scripts": {
33
     "precommit": "lint-staged",
33
     "precommit": "lint-staged",
34
-    "prettier": "prettier --single-quote --trailing-comma --write 'src/**/*.{js,jsx,json,css,less}'",
34
+    "prettier": "prettier --single-quote --trailing-comma=es5 --write 'src/**/*.{js,jsx,json,css,less}'",
35
     "start": "react-app-rewired start",
35
     "start": "react-app-rewired start",
36
     "build": "react-app-rewired build",
36
     "build": "react-app-rewired build",
37
     "test": "react-app-rewired test --env=jsdom",
37
     "test": "react-app-rewired test --env=jsdom",

+ 40
- 25
src/App.js View File

1
 import React, { Component } from "react";
1
 import React, { Component } from "react";
2
 import PropTypes from "prop-types";
2
 import PropTypes from "prop-types";
3
 import { message, Tag } from "antd";
3
 import { message, Tag } from "antd";
4
-import axios from "./axios";
4
+import axios from "axios";
5
 import { ERROR_DEFAULT, LIMIT } from "./constant";
5
 import { ERROR_DEFAULT, LIMIT } from "./constant";
6
 import { CommentContext } from "./Comment";
6
 import { CommentContext } from "./Comment";
7
 import { isFunction } from "./helper";
7
 import { isFunction } from "./helper";
37
     this.sOssSts = this.sOssSts.bind(this);
37
     this.sOssSts = this.sOssSts.bind(this);
38
   }
38
   }
39
 
39
 
40
+  componentWillMount() {
41
+    this.axios = axios;
42
+    this.axios.defaults.withCredentials = true;
43
+    if (this.props.token) {
44
+      this.axios.defaults.headers.common["Authorization"] = `Bearer ${
45
+        this.props.token
46
+      }`;
47
+    }
48
+  }
49
+
40
   componentDidMount() {}
50
   componentDidMount() {}
41
 
51
 
42
   /**
52
   /**
56
   sGetComment({ page = 1 } = {}) {
66
   sGetComment({ page = 1 } = {}) {
57
     this.handleChangeLoading("sGetComment", true);
67
     this.handleChangeLoading("sGetComment", true);
58
     const { API, type, businessId } = this.props;
68
     const { API, type, businessId } = this.props;
59
-    axios
69
+    this.axios
60
       .get(
70
       .get(
61
         `${API}/comments?type=${type}&business_id=${businessId}&page=${page}&limit=${LIMIT}`
71
         `${API}/comments?type=${type}&business_id=${businessId}&page=${page}&limit=${LIMIT}`
62
       )
72
       )
100
   sGetReply({ commentId, page = 1 } = {}) {
110
   sGetReply({ commentId, page = 1 } = {}) {
101
     this.handleChangeLoading("sGetReply", true);
111
     this.handleChangeLoading("sGetReply", true);
102
     const { API } = this.props;
112
     const { API } = this.props;
103
-    axios
113
+    this.axios
104
       .get(`${API}/replies?comment_id=${commentId}&page=${page}&limit=${LIMIT}`)
114
       .get(`${API}/replies?comment_id=${commentId}&page=${page}&limit=${LIMIT}`)
105
       .then(response => {
115
       .then(response => {
106
         if (!response.data.list) {
116
         if (!response.data.list) {
146
    * 添加评论
156
    * 添加评论
147
    * @param {object} {content} comment content
157
    * @param {object} {content} comment content
148
    */
158
    */
149
-  sCreateComment({ content } = {}) {
159
+  sCreateComment({ content } = {}, cb) {
150
     if (!content) return message.error("评论内容不能为空 ");
160
     if (!content) return message.error("评论内容不能为空 ");
151
     this.handleChangeLoading("sCreateComment", true);
161
     this.handleChangeLoading("sCreateComment", true);
152
     const { API, type, businessId } = this.props;
162
     const { API, type, businessId } = this.props;
153
-    axios(`${API}/comments`, {
163
+    this.axios(`${API}/comments`, {
154
       method: "post",
164
       method: "post",
155
       data: {
165
       data: {
156
         type,
166
         type,
161
     })
171
     })
162
       .then(response => {
172
       .then(response => {
163
         message.success("评论成功!");
173
         message.success("评论成功!");
174
+        if (isFunction(cb)) cb();
164
         // 将数据写入到 list 中
175
         // 将数据写入到 list 中
165
         // 临时插入
176
         // 临时插入
166
         // 等到获取数据之后,删除临时数据
177
         // 等到获取数据之后,删除临时数据
189
    * @param {object} data { comment_id, content, [reply_id] }
200
    * @param {object} data { comment_id, content, [reply_id] }
190
    */
201
    */
191
   sCreateReply(data, cb) {
202
   sCreateReply(data, cb) {
192
-    console.log("list: ", this.state.list);
193
-
194
     if (!data.content) return message.error("回复内容不能为空 ");
203
     if (!data.content) return message.error("回复内容不能为空 ");
195
     this.handleChangeLoading("sCreateReply", true);
204
     this.handleChangeLoading("sCreateReply", true);
196
     const { API } = this.props;
205
     const { API } = this.props;
197
-    axios(`${API}/replies`, {
206
+    this.axios(`${API}/replies`, {
198
       method: "post",
207
       method: "post",
199
       data,
208
       data,
200
       withCredentials: true
209
       withCredentials: true
238
   sCommentFavor(commentId, favored) {
247
   sCommentFavor(commentId, favored) {
239
     this.handleChangeLoading("sCommentFavor", true);
248
     this.handleChangeLoading("sCommentFavor", true);
240
     const { API } = this.props;
249
     const { API } = this.props;
241
-    axios(`${API}/comments/${commentId}/favor`, {
250
+    this.axios(`${API}/comments/${commentId}/favor`, {
242
       method: favored ? "delete" : "put",
251
       method: favored ? "delete" : "put",
243
       withCredentials: true
252
       withCredentials: true
244
     })
253
     })
274
    */
283
    */
275
   sReplyFavor(replyId, commentId, favored) {
284
   sReplyFavor(replyId, commentId, favored) {
276
     this.handleChangeLoading("sReplyFavor", true);
285
     this.handleChangeLoading("sReplyFavor", true);
277
-    console.log("replyId, commentId ", replyId, commentId);
278
-
279
     const { API } = this.props;
286
     const { API } = this.props;
280
-    axios(`${API}/replies/${replyId}/favor`, {
287
+    this.axios(`${API}/replies/${replyId}/favor`, {
281
       method: favored ? "delete" : "put",
288
       method: favored ? "delete" : "put",
289
+      data: {
290
+        comment_id: commentId
291
+      },
282
       withCredentials: true
292
       withCredentials: true
283
     })
293
     })
284
       .then(response => {
294
       .then(response => {
285
-        console.log("response: ", response);
286
-
287
         message.success(favored ? "取消点赞成功!" : "点赞成功!");
295
         message.success(favored ? "取消点赞成功!" : "点赞成功!");
288
-        // TODO: (2018.07.20 node) 对评论的回复点赞,报错
289
-        // // 更新 list 中的该项数据的 favored
290
-        // const list = this.state.list.map(item => {
291
-        //   if (item.id === replyId) {
292
-        //     item.favored = !favored;
293
-        //     item.favor_count += favored ? -1 : 1;
294
-        //   }
295
-        //   return item;
296
-        // });
297
-        // this.setState({ list });
296
+        // 更新 list 中的该项数据的 favored
297
+        const list = this.state.list.map(item => {
298
+          if (item.id === commentId) {
299
+            item.replies = item.replies.map(r => {
300
+              if (r.id === replyId) {
301
+                r.favored = !favored;
302
+                // r.favor_count =  response.data.favor_count;
303
+                // 点赞数 +1,而不是使用后端返回的点赞数
304
+                // 不然如果返回的不是增加 1,用户可能以为程序错误
305
+                r.favor_count += favored ? -1 : 1;
306
+              }
307
+              return r;
308
+            });
309
+          }
310
+          return item;
311
+        });
312
+        this.setState({ list });
298
       })
313
       })
299
       .catch(error => {
314
       .catch(error => {
300
         if (error.response && error.response.data && error.response.data.msg) {
315
         if (error.response && error.response.data && error.response.data.msg) {
314
   sOssSts() {
329
   sOssSts() {
315
     this.handleChangeLoading("sOssSts", true);
330
     this.handleChangeLoading("sOssSts", true);
316
     const { API } = this.props;
331
     const { API } = this.props;
317
-    axios
332
+    this.axios
318
       .get(`${API}/oss/sts`)
333
       .get(`${API}/oss/sts`)
319
       .then(response => {
334
       .then(response => {
320
         this.setState({ oss: { ...response.data } });
335
         this.setState({ oss: { ...response.data } });

+ 1
- 0
src/axios.js View File

1
 import axios from "axios";
1
 import axios from "axios";
2
 
2
 
3
 axios.defaults.withCredentials = true;
3
 axios.defaults.withCredentials = true;
4
+axios.defaults.headers.common["Authorization"] = "Bearer ";
4
 
5
 
5
 export default axios;
6
 export default axios;

+ 12
- 4
src/components/CommentInput/index.js View File

9
     this.handleSubmit = this.handleSubmit.bind(this);
9
     this.handleSubmit = this.handleSubmit.bind(this);
10
   }
10
   }
11
 
11
 
12
-  handleSubmit(value) {
12
+  /**
13
+   * 提交评论
14
+   * @param {string} value 需要提交的评论的值
15
+   * @param {function} cb 提交成功后的回掉
16
+   */
17
+  handleSubmit(value, cb) {
13
     const { action, commentId, replyId, callback } = this.props;
18
     const { action, commentId, replyId, callback } = this.props;
14
     if (action === "comment") {
19
     if (action === "comment") {
15
-      this.props.app.sCreateComment({
16
-        content: value
17
-      });
20
+      this.props.app.sCreateComment(
21
+        {
22
+          content: value
23
+        },
24
+        cb
25
+      );
18
     } else if (action === "reply") {
26
     } else if (action === "reply") {
19
       this.props.app.sCreateReply(
27
       this.props.app.sCreateReply(
20
         {
28
         {

+ 3
- 0
src/components/ContentItem/index.css View File

29
   margin-left: 5px;
29
   margin-left: 5px;
30
   cursor: pointer;
30
   cursor: pointer;
31
 }
31
 }
32
+.comment-favor {
33
+  font-size: 20px;
34
+}
32
 .comment-favored {
35
 .comment-favored {
33
   color: #4a90e2;
36
   color: #4a90e2;
34
 }
37
 }

+ 5
- 1
src/components/ContentItem/index.js View File

113
             >
113
             >
114
               <Icon
114
               <Icon
115
                 type="like-o"
115
                 type="like-o"
116
-                className={content.favored ? "comment-favored" : ""}
116
+                className={
117
+                  content.favored
118
+                    ? "comment-favor comment-favored"
119
+                    : "comment-favor"
120
+                }
117
               />
121
               />
118
               &nbsp;{content.favor_count}
122
               &nbsp;{content.favor_count}
119
             </div>
123
             </div>

+ 13
- 4
src/components/Editor/index.js View File

75
   }
75
   }
76
 
76
 
77
   /**
77
   /**
78
-   * 上传文件 TODO:
78
+   * 上传文件
79
    * @param {object} param 文件对象
79
    * @param {object} param 文件对象
80
    */
80
    */
81
   handleUpload({ uid, path }) {
81
   handleUpload({ uid, path }) {
97
         value += `[${OSS_LINK}${fileMap[item.uid]}]`;
97
         value += `[${OSS_LINK}${fileMap[item.uid]}]`;
98
       });
98
       });
99
     }
99
     }
100
-    this.props.onSubmit(value);
100
+    this.props.onSubmit(value, () => {
101
+      this.setState({
102
+        showUpload: false,
103
+        value: "",
104
+        fileList: [],
105
+        fileMap: {}
106
+      });
107
+    });
101
   }
108
   }
102
 
109
 
103
   render() {
110
   render() {
114
       emojiToolIcon,
121
       emojiToolIcon,
115
       imageToolIcon
122
       imageToolIcon
116
     } = this.props;
123
     } = this.props;
117
-
118
     const handleSubmit = this.handleSubmit;
124
     const handleSubmit = this.handleSubmit;
125
+    const disabledSubmit =
126
+      btnDisabled ||
127
+      (!this.props.value && !this.state.value && !this.state.fileList.length);
119
     return (
128
     return (
120
       <div className="comment-editor">
129
       <div className="comment-editor">
121
         <TextArea
130
         <TextArea
208
                 onClick={() => this.handleSubmit()}
217
                 onClick={() => this.handleSubmit()}
209
                 type="primary"
218
                 type="primary"
210
                 loading={btnLoading}
219
                 loading={btnLoading}
211
-                disabled={btnDisabled}
220
+                disabled={disabledSubmit}
212
               >
221
               >
213
                 {btnSubmitText}
222
                 {btnSubmitText}
214
               </Button>
223
               </Button>

+ 3
- 1
src/index.js View File

1
 import React, { Component } from "react";
1
 import React, { Component } from "react";
2
 import ReactDOM from "react-dom";
2
 import ReactDOM from "react-dom";
3
-import { Button, Icon } from "antd";
3
+// e.g.
4
+// import { Button, Icon } from "antd";
4
 import App, { Editor } from "./App";
5
 import App, { Editor } from "./App";
5
 import registerServiceWorker from "./registerServiceWorker";
6
 import registerServiceWorker from "./registerServiceWorker";
6
 
7
 
36
       </App>
37
       </App>
37
     );
38
     );
38
 
39
 
40
+    // e.g.
39
     // 复杂的用户法
41
     // 复杂的用户法
40
     // const props = {
42
     // const props = {
41
     //   type: 1,
43
     //   type: 1,