评论功能
后端
controller,实现新增评论和分页查询评论,此时需要保存用户的id,可以通过JWT将token转化为id,在进行远程调用,查询用户的信息进行保存
@RestController
@RequestMapping("/eduservice/edu-comment")
@CrossOrigin
public class EduCommentController {
@Autowired
private EduCommentService eduCommentService;
@Autowired
private CommentClient commentClient;
// 分页查询评论
@GetMapping("getPageComment/{currentPage}/{limit}/{courseId}")
public ResultEntity getPageEduComment(
@PathVariable long currentPage,
@PathVariable long limit,
@PathVariable(required = false) String courseId) {
Map<String, Object> map = eduCommentService.getPageComment(currentPage, limit, courseId);
return ResultEntity.ok().data(map);
}
// 保存评论
@PostMapping("saveComment")
public ResultEntity saveComment(@RequestBody EduComment eduComment, HttpServletRequest request) {
// 获取用户id
String memberId = JwtUtils.getMemberIdByJwtToken(request);
if (StringUtils.isEmpty(memberId)) {
return ResultEntity.error().message("请登录!");
}
// 调用ucenter的方法查询登录用户的信息
LoginInfoDO loginInfoDO = commentClient.getLoginInfoById(memberId);
BeanUtils.copyProperties(loginInfoDO, eduComment);
eduComment.setMemberId(memberId);
eduCommentService.save(eduComment);
return ResultEntity.ok();
}
}
impl实现分页查询数据,注意封装分页显示的对象
public class EduCommentServiceImpl extends ServiceImpl<EduCommentMapper, EduComment> implements EduCommentService {
@Override
public Map<String, Object> getPageComment(long currentPage, long limit, String courseId) {
Page<EduComment> eduCommentPage = new Page<>(currentPage, limit);
QueryWrapper<EduComment> eduCommentQueryWrapper = new QueryWrapper<>();
eduCommentQueryWrapper.eq("course_id", courseId);
eduCommentQueryWrapper.orderByDesc("gmt_create");
baseMapper.selectPage(eduCommentPage, eduCommentQueryWrapper);
List<EduComment> eduCommentList = eduCommentPage.getRecords();
Map<String, Object> map = new HashMap<>();
map.put("items", eduCommentList);
map.put("current", eduCommentPage.getCurrent());
map.put("pages", eduCommentPage.getPages());
map.put("size", eduCommentPage.getSize());
map.put("total", eduCommentPage.getTotal());
map.put("hasNext", eduCommentPage.hasNext());
map.put("hasPrevious", eduCommentPage.hasPrevious());
return map;
}
调用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);
}
- ucenter中的controller
```java
// 用户id获取用户信息
@GetMapping("getLoginInfoById/{memberId}")
public LoginInfoDO getLoginInfoById(@PathVariable String memberId) {
UcenterMember ucenterMember = ucenterMemberService.getById(memberId);
LoginInfoDO loginInfoDO = new LoginInfoDO();
BeanUtils.copyProperties(ucenterMember, loginInfoDO);
return loginInfoDO;
}
此时需要在common工程创建LoginInfo类,接口进行返回数据,可以使用ResultEntity,但取值不方便
@Data
@ApiModel(value = "LoginInfo信息对象用于订单和评论", description = "传输LoginInfo信息")
public class LoginInfoDO {
@ApiModelProperty(value = "手机号")
private String mobile;
@ApiModelProperty(value = "昵称")
private String nickname;
@ApiModelProperty(value = "性别 1 女,2 男")
private Integer sex;
@ApiModelProperty(value = "年龄")
private Integer age;
@ApiModelProperty(value = "用户头像")
private String avatar;
}
前端
api中定义接口地址
import request from '@/utils/request'
export default {
getPageComment(currentPage, limit, courseId) {
return request({
url: `/eduservice/edu-comment/getPageComment/${currentPage}/${limit}/${courseId}`,
method: 'get'
})
},
saveComment(comment) {
return request({
url: `/eduservice/edu-comment/saveComment`,
method: 'post',
data: comment
})
}
}
data定义对象
comment: {
id: "",
content: "",
courseId: "",
teacherId: "",
},
显示课程信息时将值赋值进去
// 显示课程信息
initCourse() {
courseApi.getFrontBaseCourse(this.courseId).then((response) => {
(this.course = response.data.data.courseVO),
(this.chapterList = response.data.data.chapterList),
(this.comment.teacherId = response.data.data.courseVO.teacherId);
this.comment.courseId = response.data.data.courseVO.id;
});
js调用方法
// 分页查询评论
initComment() {
commentApi
.getPageComment(this.page, this.limit, this.courseId)
.then((response) => {
this.data = response.data.data;
});
},
// 添加评论
addComment() {
commentApi
.saveComment(this.comment)
.then((response) => {
if (response.data.success) {
// 评论置空,防止下次没清空
this.comment.content = "";
this.initComment();
}
})
.catch((error) => {
this.$message({
type: "error",
message: "评论失败!",
});
});
},
页面显示
<div class="mt50 commentHtml">
<div>
<h6 class="c-c-content c-infor-title" id="i-art-comment">
<span class="commentTitle">课程评论</span>
</h6>
<section class="lh-bj-list pr mt20 replyhtml">
<ul>
<li class="unBr">
<aside class="noter-pic">
<img
width="50"
height="50"
class="picImg"
src="~/assets/img/avatar-boy.gif"
/>
</aside>
<div class="of">
<section class="n-reply-wrap">
<fieldset>
<textarea
name=""
v-model="comment.content"
placeholder="输入您要评论的文字"
id="commentContent"
></textarea>
</fieldset>
<p class="of mt5 tar pl10 pr10">
<span class="fl"
><tt
class="c-red commentContentmeg"
style="display: none"
></tt
></span>
<input
type="button"
@click="addComment()"
value="回复"
class="lh-reply-btn"
/>
</p>
</section>
</div>
</li>
</ul>
</section>
<section class="">
<section class="question-list lh-bj-list pr">
<ul class="pr10">
<li v-for="(comment, index) in data.items" v-bind:key="index">
<aside class="noter-pic">
<img
width="50"
height="50"
class="picImg"
:src="comment.avatar"
/>
</aside>
<div class="of">
<span class="fl">
<font class="fsize12 c-blue"> {{ comment.nickname }}</font>
<font class="fsize12 c-999 ml5">评论:</font></span
>
</div>
<div class="noter-txt mt5">
<p>{{ comment.content }}</p>
</div>
<div class="of mt5">
<span class="fr"
><font class="fsize12 c-999 ml5">{{
comment.gmtCreate
}}</font></span
>
</div>
</li>
</ul>
</section>
</section>
<!-- 公共分页 开始 -->
<div class="paging">
<!-- undisable这个class是否存在,取决于数据属性hasPrevious -->
<a
:class="{ undisable: !data.hasPrevious }"
href="#"
title="首页"
@click.prevent="gotoPage(1)"
>首</a
>
<a
:class="{ undisable: !data.hasPrevious }"
href="#"
title="前一页"
@click.prevent="gotoPage(data.current - 1)"
><</a
>
<a
v-for="page in data.pages"
:key="page"
:class="{
current: data.current == page,
undisable: data.current == page,
}"
:title="'第' + page + '页'"
href="#"
@click.prevent="gotoPage(page)"
>{{ page }}</a
>
<a
:class="{ undisable: !data.hasNext }"
href="#"
title="后一页"
@click.prevent="gotoPage(data.current + 1)"
>></a
>
<a
:class="{ undisable: !data.hasNext }"
href="#"
title="末页"
@click.prevent="gotoPage(data.pages)"
>末</a
>
<div class="clear" />
</div>
<!-- 公共分页 结束 -->