UserCommentCard.vue 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125
  1. <template>
  2. <el-card class="comment-card shadow-box">
  3. <div slot="header" class="comment-header">
  4. <span>全部评论 <small>{{ totalSize }}</small></span>
  5. </div>
  6. <div class="comment-container">
  7. <comment
  8. v-model="dataList"
  9. :user="currentUser"
  10. :props="commentProps"
  11. :before-submit="submit"
  12. :before-like="like"
  13. :before-delete="deleteComment"
  14. :upload-img="uploadImg"
  15. />
  16. <div class="pagination-wrapper">
  17. <el-pagination
  18. :small="screenWidth <= 768"
  19. hide-on-single-page
  20. background
  21. layout="prev, pager, next"
  22. :page-size="pageSize"
  23. :current-page="currentPage"
  24. :total="totalSize"
  25. @current-change="handleCurrentChange"
  26. />
  27. </div>
  28. </div>
  29. </el-card>
  30. </template>
  31. <script>
  32. import comment from '@/components/comment'
  33. import { publishComment, getComment } from '@/api/comment'
  34. export default {
  35. name: 'UserCommentCard',
  36. components: { comment },
  37. props: {
  38. videoId: { type: String, required: true },
  39. currentUser: { type: Object, required: true },
  40. screenWidth: { type: Number, default: 1200 }
  41. },
  42. data() {
  43. return {
  44. currentPage: 1,
  45. pageSize: 20,
  46. totalSize: 0,
  47. dataList: [],
  48. commentProps: {
  49. id: 'commentId',
  50. content: 'content',
  51. imgSrc: 'imageUrl',
  52. children: 'children',
  53. likes: 'likes',
  54. liked: 'liked',
  55. reply: 'reply',
  56. createAt: 'createAt',
  57. total: 'total',
  58. user: 'user'
  59. }
  60. }
  61. },
  62. watch: {
  63. videoId: {
  64. immediate: true,
  65. handler(newVal) {
  66. if (newVal) this.getCommentWrapper(1)
  67. }
  68. }
  69. },
  70. methods: {
  71. handleCurrentChange(page) {
  72. this.currentPage = page
  73. this.getCommentWrapper(page)
  74. window.scrollTo({ top: document.querySelector('.comment-card').offsetTop - 100, behavior: 'smooth' })
  75. },
  76. getCommentWrapper(pageNumber) {
  77. getComment(this.videoId, pageNumber).then(resp => {
  78. if (resp.code === 0) {
  79. this.dataList = resp.data.list
  80. this.totalSize = resp.data.totalSize
  81. } else {
  82. this.$message.error(resp.msg)
  83. }
  84. }).catch(err => this.$message.error(err.message))
  85. },
  86. async submit(newComment, parent, add) {
  87. // 模拟延迟
  88. await new Promise(resolve => setTimeout(resolve, 300))
  89. const payload = { newComment, parent, postId: this.videoId }
  90. publishComment(payload).then(resp => {
  91. if (resp.code === 0) {
  92. add(Object.assign(newComment, { postId: this.videoId }))
  93. if (parent === null) this.totalSize += 1
  94. this.$notify.success({ message: '评论已发布' })
  95. } else {
  96. this.$notify.warning({ message: '评论发布失败' })
  97. }
  98. })
  99. },
  100. async like(comment) {
  101. console.log('Like comment:', comment)
  102. // 这里可以调用点赞接口
  103. },
  104. async deleteComment(comment, parent) {
  105. console.log('Delete comment:', comment)
  106. // 这里可以调用删除接口
  107. },
  108. async uploadImg({ file, callback }) {
  109. const reader = new FileReader()
  110. reader.readAsDataURL(file)
  111. reader.onload = () => callback(reader.result)
  112. }
  113. }
  114. }
  115. </script>
  116. <style scoped>
  117. .comment-card { margin-bottom: 40px; }
  118. .comment-header { font-weight: 600; font-size: 18px; }
  119. .comment-header small { font-weight: normal; color: #909399; margin-left: 8px; }
  120. .pagination-wrapper { margin-top: 30px; display: flex; justify-content: center; }
  121. </style>