瑶都万能墙
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

346 lines
8.1 KiB

1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
  1. <template>
  2. <view class="comment">
  3. <view class="comment-header">
  4. <view class="avatar">
  5. <image :src="item.userHead"
  6. @click.stop="previewImage([item.userHead])"
  7. mode="aspectFill"></image>
  8. </view>
  9. <view class="user-info">
  10. <view class="username">{{ item.userName }}</view>
  11. <view class="comment-content" v-html="$utils.stringFormatHtml(item.userValue)"></view>
  12. <view class="comment-meta">
  13. <text class="time">{{ $timeUtils.formatTime(item.createTime) }}</text>
  14. <!-- <text class="location">贵州</text> -->
  15. <text class="reply-btn" @click.stop="handleReply(0)">回复</text>
  16. </view>
  17. </view>
  18. </view>
  19. <!-- 主评论图片 -->
  20. <view class="images" v-if="images && images.length > 0">
  21. <view class="image"
  22. @click.stop="previewImage(images, i)"
  23. :key="i" v-for="(img, i) in images">
  24. <image :src="img" mode="aspectFill"></image>
  25. </view>
  26. </view>
  27. <!-- 子评论列表 -->
  28. <view class="sub-comments-list" v-if="subComments && subComments.length > 0">
  29. <view class="sub-comment-item" v-for="(subComment, index) in subComments" :key="subComment.id">
  30. <view class="sub-comment-header">
  31. <view class="sub-avatar">
  32. <image :src="subComment.userHead" mode="aspectFill" @click.stop="previewImage([subComment.userHead])"></image>
  33. </view>
  34. <view class="sub-user-info">
  35. <view class="sub-username">
  36. <text>{{ subComment.userName }}</text>
  37. <!-- 显示回复信息 -->
  38. <text class="reply-to" v-if="subComment.replyToName">回复 @{{ subComment.replyToName }}:</text>
  39. </view>
  40. <view class="sub-comment-content" v-html="$utils.stringFormatHtml(subComment.userValue)"></view>
  41. <view class="sub-comment-meta">
  42. <text class="sub-time">{{ $timeUtils.formatTime(subComment.createTime) }}</text>
  43. <!-- <text class="location">贵州</text> -->
  44. <text class="sub-reply-btn" @click.stop="handleSubReply(subComment)">回复</text>
  45. </view>
  46. </view>
  47. </view>
  48. <!-- 子评论图片 -->
  49. <view class="sub-comment-images" v-if="subComment.userImage">
  50. <view class="sub-image"
  51. @click.stop="previewImage(subComment.userImage.split(','), i)"
  52. :key="i" v-for="(img, i) in subComment.userImage.split(',')">
  53. <image :src="img" mode="aspectFill"></image>
  54. </view>
  55. </view>
  56. </view>
  57. </view>
  58. <!-- 加载更多子评论按钮 -->
  59. <view class="load-more-section" v-if="item.replyNum && item.replyNum > 0 && (!subComments || subComments.length === 0)">
  60. <view class="load-more-btn" @click.stop="loadSubComments">
  61. <text class="load-more-text">查看{{item.replyNum}}条回复</text>
  62. </view>
  63. </view>
  64. </view>
  65. </template>
  66. <script>
  67. export default {
  68. props : ['item', 'parentId', 'sourceType', 'sourceId', 'subComments'],
  69. data() {
  70. return {
  71. isLoadingSubComments: false // 添加加载状态
  72. }
  73. },
  74. computed : {
  75. images(){
  76. if(!this.item.userImage){
  77. return []
  78. }
  79. return this.item.userImage.split(',')
  80. }
  81. },
  82. methods: {
  83. // 导航到子评论详情
  84. navigateToSubComment(comment) {
  85. uni.navigateTo({
  86. url: `/pages_order/comment/commentDetail?id=${comment.id}&parentId=${this.parentId}&sourceType=${this.sourceType}&sourceId=${this.sourceId}`
  87. });
  88. },
  89. // 加载子评论
  90. loadSubComments() {
  91. if (this.isLoadingSubComments) return; // 防止重复加载
  92. this.isLoadingSubComments = true;
  93. uni.showLoading({
  94. title: '加载中...'
  95. });
  96. this.$emit('loadSubComments', this.item);
  97. // 模拟加载完成后的状态重置
  98. setTimeout(() => {
  99. this.isLoadingSubComments = false;
  100. uni.hideLoading();
  101. }, 1000);
  102. },
  103. // 处理回复
  104. handleReply() {
  105. // 检查用户是否已登录
  106. if (!this.userInfo || !this.userInfo.id) {
  107. console.log('用户未登录,跳转到登录页面')
  108. // 使用utils中的toLogin方法跳转到登录页面
  109. this.$utils.toLogin()
  110. return
  111. }
  112. this.$emit('reply', {
  113. item : this.item,
  114. level : 0,
  115. });
  116. },
  117. // 处理子评论回复
  118. handleSubReply(subComment) {
  119. // 检查用户是否已登录
  120. if (!this.userInfo || !this.userInfo.id) {
  121. console.log('用户未登录,跳转到登录页面')
  122. // 使用utils中的toLogin方法跳转到登录页面
  123. this.$utils.toLogin()
  124. return
  125. }
  126. this.$emit('reply', {
  127. item : subComment,
  128. level : 1,
  129. });
  130. }
  131. }
  132. }
  133. </script>
  134. <style scoped lang="scss">
  135. .comment {
  136. background-color: #fff;
  137. padding: 26.25rpx 35rpx;
  138. margin-bottom: 1.75rpx;
  139. border-bottom: 1.75rpx solid #f5f5f5;
  140. .comment-header {
  141. display: flex;
  142. align-items: flex-start;
  143. .avatar {
  144. width: 70rpx;
  145. height: 70rpx;
  146. border-radius: 50%;
  147. overflow: hidden;
  148. margin-right: 17.5rpx;
  149. flex-shrink: 0;
  150. image {
  151. width: 100%;
  152. height: 100%;
  153. }
  154. }
  155. .user-info {
  156. flex: 1;
  157. .username {
  158. font-size: 24.5rpx;
  159. font-weight: 600;
  160. color: $uni-text-color;
  161. margin-bottom: 7rpx;
  162. }
  163. .comment-content {
  164. font-size: 26.25rpx;
  165. line-height: 1.5;
  166. color: $uni-text-color;
  167. margin-bottom: 10.5rpx;
  168. word-break: break-all;
  169. }
  170. .comment-meta {
  171. display: flex;
  172. align-items: center;
  173. font-size: 21rpx;
  174. color: $uni-text-color-grey;
  175. .time {
  176. margin-right: 17.5rpx;
  177. }
  178. .location {
  179. margin-right: 17.5rpx;
  180. }
  181. .reply-btn {
  182. color: $uni-text-color-grey;
  183. padding: 7rpx 14rpx;
  184. background-color: #f5f5f5;
  185. border-radius: 17.5rpx;
  186. font-size: 19.25rpx;
  187. margin-left: auto;
  188. }
  189. }
  190. }
  191. }
  192. .images {
  193. display: flex;
  194. flex-wrap: wrap;
  195. margin-top: 17.5rpx;
  196. margin-left: 87.5rpx;
  197. .image {
  198. margin: 8.75rpx;
  199. image {
  200. height: 105rpx;
  201. width: 105rpx;
  202. border-radius: 10.5rpx;
  203. }
  204. }
  205. }
  206. // 子评论列表样式
  207. .sub-comments-list {
  208. margin-top: 17.5rpx;
  209. margin-left: 87.5rpx;
  210. .sub-comment-item {
  211. margin-bottom: 26.25rpx;
  212. &:last-child {
  213. margin-bottom: 0;
  214. }
  215. .sub-comment-header {
  216. display: flex;
  217. align-items: flex-start;
  218. .sub-avatar {
  219. width: 52.5rpx;
  220. height: 52.5rpx;
  221. border-radius: 50%;
  222. overflow: hidden;
  223. margin-right: 14rpx;
  224. flex-shrink: 0;
  225. image {
  226. width: 100%;
  227. height: 100%;
  228. }
  229. }
  230. .sub-user-info {
  231. flex: 1;
  232. .sub-username {
  233. font-size: 22.75rpx;
  234. font-weight: 600;
  235. color: $uni-text-color;
  236. margin-bottom: 5.25rpx;
  237. .reply-to {
  238. font-size: 21rpx;
  239. color: $uni-color-primary;
  240. font-weight: 500;
  241. margin-left: 8.75rpx;
  242. }
  243. }
  244. .sub-comment-content {
  245. font-size: 24.5rpx;
  246. line-height: 1.5;
  247. color: $uni-text-color;
  248. margin-bottom: 8.75rpx;
  249. word-break: break-all;
  250. }
  251. .sub-comment-meta {
  252. display: flex;
  253. align-items: center;
  254. font-size: 19.25rpx;
  255. color: $uni-text-color-grey;
  256. .sub-time {
  257. margin-right: 14rpx;
  258. }
  259. .sub-location {
  260. margin-right: 14rpx;
  261. }
  262. .sub-reply-btn {
  263. color: $uni-text-color-grey;
  264. padding: 5.25rpx 10.5rpx;
  265. background-color: #f5f5f5;
  266. border-radius: 14rpx;
  267. font-size: 17.5rpx;
  268. margin-left: auto;
  269. }
  270. }
  271. }
  272. }
  273. .sub-comment-images {
  274. display: flex;
  275. flex-wrap: wrap;
  276. margin-top: 10.5rpx;
  277. margin-left: 66.5rpx;
  278. .sub-image {
  279. margin-right: 7rpx;
  280. margin-bottom: 7rpx;
  281. image {
  282. width: 84rpx;
  283. height: 84rpx;
  284. border-radius: 7rpx;
  285. }
  286. }
  287. }
  288. }
  289. }
  290. .load-more-section {
  291. margin-left: 87.5rpx;
  292. .load-more-btn {
  293. display: inline-flex;
  294. align-items: center;
  295. padding: 7rpx 14rpx;
  296. background-color: #f5f5f5;
  297. border-radius: 17.5rpx;
  298. font-size: 21rpx;
  299. color: $uni-text-color-grey;
  300. }
  301. }
  302. }
  303. </style>