comment-list.vue 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266
  1. <template>
  2. <view class="comment-list">
  3. <!-- 顶部区域 -->
  4. <view class="comment-list_head">
  5. <view class="title">
  6. 评论列表
  7. <text class="count">({{ result.total || 0 }}条)</text>
  8. </view>
  9. <view class="filter">
  10. <text class="filter-item " :class="{ active: sort == 0 }" @click="fnOnSort(0)">默认</text>
  11. <text class="filter-item " :class="{ active: sort == 1 }" @click="fnOnSort(1)">热评</text>
  12. <!-- <text class="filter-item">全部</text> -->
  13. </view>
  14. </view>
  15. <!-- <view v-if="disallowComment" class="disallow-comment"><tm-empty icon="icon-shiliangzhinengduixiang-" label="文章已开启禁止评论"></tm-empty></view> -->
  16. <!-- 内容区域 -->
  17. <view class="comment-list_content">
  18. <view v-if="loading != 'success'" class="loading-wrap flex">
  19. <view v-if="loading == 'loading'" class="loading flex flex-center flex-col">
  20. <text class="e-loading-icon iconfont icon-loading text-blue"></text>
  21. <view class="text-size-n text-grey-lighten-1 py-12 mt-12">加载中,请稍等...</view>
  22. </view>
  23. <view v-else-if="loading == 'error'" class="error">
  24. <tm-empty icon="icon-wind-cry" label="加载失败">
  25. <tm-button theme="bg-gradient-light-blue-accent" size="m" v-if="!disallowComment" @click="fnToComment()">刷新试试</tm-button>
  26. </tm-empty>
  27. </view>
  28. </view>
  29. <block v-else>
  30. <view class="empty pt-50" v-if="dataList.length == 0">
  31. <tm-empty icon="icon-shiliangzhinengduixiang-" label="暂无评论">
  32. <tm-button theme="bg-gradient-light-blue-accent" size="m" v-if="!disallowComment" @click="fnToComment(null)">抢沙发</tm-button>
  33. </tm-empty>
  34. </view>
  35. <block v-else>
  36. <!-- 评论内容 : 目前仅支持二级评论 -->
  37. <block v-for="(comment, index) in dataList" :key="comment.id">
  38. <comment-item
  39. :useContentBg="false"
  40. :isChild="false"
  41. :comment="comment"
  42. :postId="postId"
  43. @on-copy="fnCopyContent"
  44. @on-comment="fnToComment"
  45. @on-todo="fnToDo"
  46. @on-detail="fnShowCommetnDetail"
  47. ></comment-item>
  48. <!-- 二级评论 -->
  49. <block v-if="comment.children && comment.children.length != 0">
  50. <block v-for="(childComment, childIndex) in comment.children" :key="childComment.id">
  51. <comment-item
  52. :useContentBg="false"
  53. :isChild="true"
  54. :comment="childComment"
  55. :postId="postId"
  56. @on-copy="fnCopyContent"
  57. @on-comment="fnToComment"
  58. @on-todo="fnToDo"
  59. @on-detail="fnShowCommetnDetail"
  60. ></comment-item>
  61. </block>
  62. </block>
  63. </block>
  64. <view v-if="false" class="to-more-comment">
  65. <tm-button item-class="btn" :block="true" width="90vw" theme="bg-gradient-light-blue-lighten" size="m">点击查看全部评论</tm-button>
  66. </view>
  67. </block>
  68. </block>
  69. </view>
  70. </view>
  71. </template>
  72. <script>
  73. import tmEmpty from '@/tm-vuetify/components/tm-empty/tm-empty.vue';
  74. import tmButton from '@/tm-vuetify/components/tm-button/tm-button.vue';
  75. export default {
  76. name: 'comment-list',
  77. components: { tmEmpty, tmButton },
  78. props: {
  79. // 是否禁用评论
  80. disallowComment: {
  81. type: Boolean,
  82. default: false
  83. },
  84. postId: {
  85. type: Number,
  86. default: null
  87. },
  88. post: {
  89. type: Object,
  90. default: () => {}
  91. }
  92. },
  93. data() {
  94. return {
  95. loading: 'loading',
  96. sort: 0,
  97. queryParams: {
  98. sort: '',
  99. more: true
  100. },
  101. api: 'getPostCommentTree',
  102. result: {},
  103. dataList: []
  104. };
  105. },
  106. created() {
  107. this.fnGetData();
  108. uni.$on('comment_list_refresh', () => {
  109. this.fnOnSort(this.sort, true);
  110. });
  111. },
  112. methods: {
  113. fnOnSort(type, refresh = false) {
  114. if (this.sort == type && refresh == false) return;
  115. const _api = ['getPostCommentTree', 'getPostTopCommentList'];
  116. this.sort = type;
  117. this.api = _api[type];
  118. this.fnGetData();
  119. },
  120. fnGetData() {
  121. this.loading = 'loading';
  122. this.$httpApi[this.api](this.postId, {})
  123. .then(res => {
  124. if (res.status == 200) {
  125. this.result = res.data;
  126. this.dataList = res.data.content;
  127. this.loading = 'success';
  128. } else {
  129. this.loading = 'error';
  130. }
  131. })
  132. .catch(err => {
  133. this.loading = 'error';
  134. })
  135. .finally(() => {
  136. uni.hideLoading();
  137. });
  138. },
  139. fnToDo() {
  140. uni.$tm.toast('Halo暂未支持!');
  141. },
  142. fnToComment(data) {
  143. if (this.disallowComment) {
  144. return uni.$tm.toast('文章已禁止评论!');
  145. }
  146. console.log(data);
  147. let _comment = {};
  148. if (data) {
  149. let { type, comment } = data;
  150. // 来自用户
  151. _comment = {
  152. id: this.post.id,
  153. parentId: comment.id,
  154. title: comment.author,
  155. from: 'posts',
  156. formPage: 'comment_list',
  157. type: 'user'
  158. };
  159. } else {
  160. // 来自文章
  161. _comment = {
  162. id: this.post.id,
  163. parentId: 0,
  164. title: '评论文章:' + this.post.title,
  165. formPage: 'comment_list',
  166. from: 'posts',
  167. type: 'post'
  168. };
  169. }
  170. uni.$tm.vx.commit('comment/setCommentInfo', _comment);
  171. this.$Router.push({
  172. path: '/pagesA/comment/comment',
  173. query: _comment
  174. });
  175. },
  176. fnCopyContent(content) {
  177. uni.$tm.u.setClipboardData(content);
  178. uni.$tm.toast('内容已复制成功!');
  179. },
  180. fnShowCommetnDetail(comment) {
  181. this.$emit('on-comment-detail', {
  182. postId: this.postId,
  183. comment: comment
  184. });
  185. }
  186. }
  187. };
  188. </script>
  189. <style lang="scss" scoped>
  190. .comment-list {
  191. &_head {
  192. display: flex;
  193. align-items: center;
  194. justify-content: space-between;
  195. position: relative;
  196. box-sizing: border-box;
  197. padding-left: 24rpx;
  198. font-size: 34rpx;
  199. font-weight: bold;
  200. &:before {
  201. content: '';
  202. position: absolute;
  203. left: 0rpx;
  204. top: 8rpx;
  205. width: 8rpx;
  206. height: 30rpx;
  207. background-color: rgb(3, 174, 252);
  208. border-radius: 6rpx;
  209. }
  210. .title {
  211. .count {
  212. font-size: 28rpx;
  213. font-weight: normal;
  214. }
  215. }
  216. .filter {
  217. font-size: 26rpx;
  218. font-weight: normal;
  219. &-item {
  220. margin-left: 20rpx;
  221. color: #666;
  222. &.active {
  223. font-weight: bold;
  224. color: rgb(255, 152, 0);
  225. font-size: 26rpx;
  226. }
  227. }
  228. }
  229. }
  230. &_content {
  231. margin-top: 24rpx;
  232. padding-bottom: 36rpx;
  233. }
  234. }
  235. .loading-wrap {
  236. width: 100%;
  237. height: 506rpx;
  238. .loading {
  239. width: 100%;
  240. }
  241. .e-loading-icon {
  242. font-size: 100rpx;
  243. }
  244. }
  245. .to-more-comment {
  246. width: 100%;
  247. display: flex;
  248. align-items: center;
  249. justify-content: center;
  250. margin-top: 80rpx;
  251. ::v-deep {
  252. .tm-button .tm-button-btn uni-button {
  253. height: 70rpx;
  254. }
  255. }
  256. }
  257. </style>