评论功能

后端

  • controller,实现新增评论和分页查询评论,此时需要保存用户的id,可以通过JWT将token转化为id,在进行远程调用,查询用户的信息进行保存

    1. @RestController
    2. @RequestMapping("/eduservice/edu-comment")
    3. @CrossOrigin
    4. public class EduCommentController {
    5. @Autowired
    6. private EduCommentService eduCommentService;
    7. @Autowired
    8. private CommentClient commentClient;
    9. // 分页查询评论
    10. @GetMapping("getPageComment/{currentPage}/{limit}/{courseId}")
    11. public ResultEntity getPageEduComment(
    12. @PathVariable long currentPage,
    13. @PathVariable long limit,
    14. @PathVariable(required = false) String courseId) {
    15. Map<String, Object> map = eduCommentService.getPageComment(currentPage, limit, courseId);
    16. return ResultEntity.ok().data(map);
    17. }
    18. // 保存评论
    19. @PostMapping("saveComment")
    20. public ResultEntity saveComment(@RequestBody EduComment eduComment, HttpServletRequest request) {
    21. // 获取用户id
    22. String memberId = JwtUtils.getMemberIdByJwtToken(request);
    23. if (StringUtils.isEmpty(memberId)) {
    24. return ResultEntity.error().message("请登录!");
    25. }
    26. // 调用ucenter的方法查询登录用户的信息
    27. LoginInfoDO loginInfoDO = commentClient.getLoginInfoById(memberId);
    28. BeanUtils.copyProperties(loginInfoDO, eduComment);
    29. eduComment.setMemberId(memberId);
    30. eduCommentService.save(eduComment);
    31. return ResultEntity.ok();
    32. }
    33. }
  • impl实现分页查询数据,注意封装分页显示的对象

    1. public class EduCommentServiceImpl extends ServiceImpl<EduCommentMapper, EduComment> implements EduCommentService {
    2. @Override
    3. public Map<String, Object> getPageComment(long currentPage, long limit, String courseId) {
    4. Page<EduComment> eduCommentPage = new Page<>(currentPage, limit);
    5. QueryWrapper<EduComment> eduCommentQueryWrapper = new QueryWrapper<>();
    6. eduCommentQueryWrapper.eq("course_id", courseId);
    7. eduCommentQueryWrapper.orderByDesc("gmt_create");
    8. baseMapper.selectPage(eduCommentPage, eduCommentQueryWrapper);
    9. List<EduComment> eduCommentList = eduCommentPage.getRecords();
    10. Map<String, Object> map = new HashMap<>();
    11. map.put("items", eduCommentList);
    12. map.put("current", eduCommentPage.getCurrent());
    13. map.put("pages", eduCommentPage.getPages());
    14. map.put("size", eduCommentPage.getSize());
    15. map.put("total", eduCommentPage.getTotal());
    16. map.put("hasNext", eduCommentPage.hasNext());
    17. map.put("hasPrevious", eduCommentPage.hasPrevious());
    18. return map;
    19. }
  • 调用ucenter模块的代理接口,进行用户信息查询
    ```java @FeignClient(name = “service-ucenter”, fallback = com.atguigu.eduservice.client.CommentDegradeFeignClient.class) // 代理的微服务名 @Component public interface CommentClient {

    // 调用ucenter查询登录信息,注意全路径 @PostMapping(“/ucenterservice/ucenter-member/getLoginInfoById/{memberId}”) public LoginInfoDO getLoginInfoById(@PathVariable(“memberId”) String memberId);

}

  1. - ucenter中的controller
  2. ```java
  3. // 用户id获取用户信息
  4. @GetMapping("getLoginInfoById/{memberId}")
  5. public LoginInfoDO getLoginInfoById(@PathVariable String memberId) {
  6. UcenterMember ucenterMember = ucenterMemberService.getById(memberId);
  7. LoginInfoDO loginInfoDO = new LoginInfoDO();
  8. BeanUtils.copyProperties(ucenterMember, loginInfoDO);
  9. return loginInfoDO;
  10. }
  • 此时需要在common工程创建LoginInfo类,接口进行返回数据,可以使用ResultEntity,但取值不方便

    1. @Data
    2. @ApiModel(value = "LoginInfo信息对象用于订单和评论", description = "传输LoginInfo信息")
    3. public class LoginInfoDO {
    4. @ApiModelProperty(value = "手机号")
    5. private String mobile;
    6. @ApiModelProperty(value = "昵称")
    7. private String nickname;
    8. @ApiModelProperty(value = "性别 1 女,2 男")
    9. private Integer sex;
    10. @ApiModelProperty(value = "年龄")
    11. private Integer age;
    12. @ApiModelProperty(value = "用户头像")
    13. private String avatar;
    14. }

前端

  • api中定义接口地址

    1. import request from '@/utils/request'
    2. export default {
    3. getPageComment(currentPage, limit, courseId) {
    4. return request({
    5. url: `/eduservice/edu-comment/getPageComment/${currentPage}/${limit}/${courseId}`,
    6. method: 'get'
    7. })
    8. },
    9. saveComment(comment) {
    10. return request({
    11. url: `/eduservice/edu-comment/saveComment`,
    12. method: 'post',
    13. data: comment
    14. })
    15. }
    16. }
  • data定义对象

    1. comment: {
    2. id: "",
    3. content: "",
    4. courseId: "",
    5. teacherId: "",
    6. },
  • 显示课程信息时将值赋值进去

    1. // 显示课程信息
    2. initCourse() {
    3. courseApi.getFrontBaseCourse(this.courseId).then((response) => {
    4. (this.course = response.data.data.courseVO),
    5. (this.chapterList = response.data.data.chapterList),
    6. (this.comment.teacherId = response.data.data.courseVO.teacherId);
    7. this.comment.courseId = response.data.data.courseVO.id;
    8. });
  • js调用方法

    1. // 分页查询评论
    2. initComment() {
    3. commentApi
    4. .getPageComment(this.page, this.limit, this.courseId)
    5. .then((response) => {
    6. this.data = response.data.data;
    7. });
    8. },
    9. // 添加评论
    10. addComment() {
    11. commentApi
    12. .saveComment(this.comment)
    13. .then((response) => {
    14. if (response.data.success) {
    15. // 评论置空,防止下次没清空
    16. this.comment.content = "";
    17. this.initComment();
    18. }
    19. })
    20. .catch((error) => {
    21. this.$message({
    22. type: "error",
    23. message: "评论失败!",
    24. });
    25. });
    26. },
  • 页面显示

    1. <div class="mt50 commentHtml">
    2. <div>
    3. <h6 class="c-c-content c-infor-title" id="i-art-comment">
    4. <span class="commentTitle">课程评论</span>
    5. </h6>
    6. <section class="lh-bj-list pr mt20 replyhtml">
    7. <ul>
    8. <li class="unBr">
    9. <aside class="noter-pic">
    10. <img
    11. width="50"
    12. height="50"
    13. class="picImg"
    14. src="~/assets/img/avatar-boy.gif"
    15. />
    16. </aside>
    17. <div class="of">
    18. <section class="n-reply-wrap">
    19. <fieldset>
    20. <textarea
    21. name=""
    22. v-model="comment.content"
    23. placeholder="输入您要评论的文字"
    24. id="commentContent"
    25. ></textarea>
    26. </fieldset>
    27. <p class="of mt5 tar pl10 pr10">
    28. <span class="fl"
    29. ><tt
    30. class="c-red commentContentmeg"
    31. style="display: none"
    32. ></tt
    33. ></span>
    34. <input
    35. type="button"
    36. @click="addComment()"
    37. value="回复"
    38. class="lh-reply-btn"
    39. />
    40. </p>
    41. </section>
    42. </div>
    43. </li>
    44. </ul>
    45. </section>
    46. <section class="">
    47. <section class="question-list lh-bj-list pr">
    48. <ul class="pr10">
    49. <li v-for="(comment, index) in data.items" v-bind:key="index">
    50. <aside class="noter-pic">
    51. <img
    52. width="50"
    53. height="50"
    54. class="picImg"
    55. :src="comment.avatar"
    56. />
    57. </aside>
    58. <div class="of">
    59. <span class="fl">
    60. <font class="fsize12 c-blue"> {{ comment.nickname }}</font>
    61. <font class="fsize12 c-999 ml5">评论:</font></span
    62. >
    63. </div>
    64. <div class="noter-txt mt5">
    65. <p>{{ comment.content }}</p>
    66. </div>
    67. <div class="of mt5">
    68. <span class="fr"
    69. ><font class="fsize12 c-999 ml5">{{
    70. comment.gmtCreate
    71. }}</font></span
    72. >
    73. </div>
    74. </li>
    75. </ul>
    76. </section>
    77. </section>
    78. <!-- 公共分页 开始 -->
    79. <div class="paging">
    80. <!-- undisable这个class是否存在,取决于数据属性hasPrevious -->
    81. <a
    82. :class="{ undisable: !data.hasPrevious }"
    83. href="#"
    84. title="首页"
    85. @click.prevent="gotoPage(1)"
    86. ></a
    87. >
    88. <a
    89. :class="{ undisable: !data.hasPrevious }"
    90. href="#"
    91. title="前一页"
    92. @click.prevent="gotoPage(data.current - 1)"
    93. >&lt;</a
    94. >
    95. <a
    96. v-for="page in data.pages"
    97. :key="page"
    98. :class="{
    99. current: data.current == page,
    100. undisable: data.current == page,
    101. }"
    102. :title="'第' + page + '页'"
    103. href="#"
    104. @click.prevent="gotoPage(page)"
    105. >{{ page }}</a
    106. >
    107. <a
    108. :class="{ undisable: !data.hasNext }"
    109. href="#"
    110. title="后一页"
    111. @click.prevent="gotoPage(data.current + 1)"
    112. >&gt;</a
    113. >
    114. <a
    115. :class="{ undisable: !data.hasNext }"
    116. href="#"
    117. title="末页"
    118. @click.prevent="gotoPage(data.pages)"
    119. ></a
    120. >
    121. <div class="clear" />
    122. </div>
    123. <!-- 公共分页 结束 -->