app-comments.vue 9.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286
  1. <template>
  2. <view class="app-comments" v-if="mall.setting.is_comment == 1">
  3. <view class="empty" v-if="showType !== 'detail'">
  4. <view class="app-top dir-left-nowrap cross-center">
  5. <view class="box box-grow-1 main-center cross-center" @click="clickStatus(item.index)"
  6. v-for="(item, index) in commentCount"
  7. :key="index"
  8. :class="status === item.index ? theme + '-background' : 'background'">
  9. <view>{{item.name}}({{item.count}})</view>
  10. </view>
  11. </view>
  12. </view>
  13. <view class="list" v-if="list.length > 0">
  14. <view class="dir-left-nowrap block cross-center" v-if="showType === 'detail'">
  15. <view class="box-grow-1">评价</view>
  16. <view class="box-grow-0 more" @click="goto">查看更多</view>
  17. <image class="box-grow-0" src="../../../static/image/icon/arrow-right.png"></image>
  18. </view>
  19. <view class="comments" v-for="(item, index) in list" :key="index" :class="showType === 'detail' ? 'bt' : 'bb'">
  20. <view class="title dir-left-nowrap cross-center">
  21. <image class="box-grow-0" :src="item.avatar"></image>
  22. <view class="box-grow-1">{{item.nickname}}</view>
  23. <view class="more box-grow-0">{{item.time}}</view>
  24. </view>
  25. <view :class="showType === 'detail' ? 'content' : ''">{{item.content}}</view>
  26. <view class="dir-left-wrap pic-list">
  27. <image :src="pic_url" v-for="(pic_url,pic_url_index) in item.pic_url" :key="pic_url_index"
  28. @click="imgPreview(index, pic_url_index)"></image>
  29. </view>
  30. <view class="replay" v-if="showType !== 'detail' && item.reply_content">
  31. <view>
  32. <text :class="theme + '-color'">商家:</text>
  33. {{item.reply_content}}
  34. </view>
  35. </view>
  36. </view>
  37. </view>
  38. <view class="block cross-center" v-else>暂无评价</view>
  39. </view>
  40. </template>
  41. <script>
  42. import { mapState } from 'vuex';
  43. let page = 1;
  44. let is_loading = false;
  45. let is_no_more = false;
  46. export default {
  47. name: 'app-comments',
  48. props: {
  49. goodsId: Number,
  50. url: {
  51. type: String,
  52. default() {
  53. return '';
  54. }
  55. },
  56. showType: {
  57. type: String,
  58. default() {
  59. return 'detail'
  60. }
  61. },
  62. reachBottom: Number,
  63. },
  64. watch: {
  65. goodsId: {
  66. handler() {
  67. this.loadData();
  68. }
  69. },
  70. reachBottom: {
  71. handler(){
  72. if (is_no_more) return;
  73. this.loadData();
  74. }
  75. }
  76. },
  77. computed: {
  78. ...mapState({
  79. theme: state => state.mallConfig.theme,
  80. mall: state => state.mallConfig.mall
  81. }),
  82. },
  83. methods: {
  84. loadData() {
  85. if (this.mall.setting.is_comment == 0) return;
  86. if (is_loading) return;
  87. is_loading = true;
  88. if (this.showType !== 'detail') {
  89. uni.showLoading({
  90. title: '加载中'
  91. });
  92. }
  93. this.$request({
  94. url: this.url ? this.url : this.$api.goods.comments_list,
  95. data: {
  96. goods_id: this.goodsId,
  97. page: page,
  98. status: this.status,
  99. }
  100. }).then(response => {
  101. is_loading = false;
  102. uni.hideLoading();
  103. if (response.code === 0) {
  104. this.commentCount = response.data.comment_count;
  105. if (page === 1) {
  106. this.list = [];
  107. }
  108. let list = response.data.comments;
  109. if (list.length > 0) {
  110. if (this.showType === 'detail') {
  111. list = list.splice(0, 2)
  112. }
  113. this.list = [...this.list, ...list];
  114. page++;
  115. } else {
  116. is_no_more = true;
  117. }
  118. }
  119. }).catch(() => {
  120. is_loading = false;
  121. uni.hideLoading();
  122. });
  123. },
  124. goto() {
  125. uni.navigateTo({
  126. url: `/pages/comments/comments?goods_id=${this.goodsId}`
  127. })
  128. },
  129. clickStatus(status) {
  130. this.status = status;
  131. page = 1;
  132. is_no_more = false;
  133. this.loadData();
  134. },
  135. imgPreview(index, pic_index) {
  136. if (this.list && this.list[index] && this.list[index].pic_url && this.list[index].pic_url.length > 0) {
  137. uni.previewImage({
  138. current: pic_index,
  139. urls: this.list[index].pic_url
  140. });
  141. }
  142. },
  143. },
  144. data() {
  145. return {
  146. commentCount: [],
  147. list: [],
  148. status: 0,
  149. };
  150. },
  151. created() {
  152. page = 1;
  153. is_loading = false;
  154. is_no_more = false;
  155. },
  156. mounted() {
  157. if (this.goodsId) this.loadData();
  158. },
  159. }
  160. </script>
  161. <style scoped lang="scss">
  162. .app-comments {
  163. .more {
  164. font-size: $uni-font-size-weak-one;
  165. color: $uni-general-color-two;
  166. }
  167. .block {
  168. width: 100%;
  169. height: #{80rpx};
  170. font-size: $uni-font-size-general-two;
  171. background-color: #FFFFFF;
  172. padding: 0 #{24rpx};
  173. image {
  174. width: #{12rpx};
  175. height: #{22rpx};
  176. display: block;
  177. margin-left: #{12rpx};
  178. }
  179. }
  180. .empty {
  181. width: 100%;
  182. height: #{100rpx};
  183. margin-bottom: #{20rpx};
  184. }
  185. .app-top {
  186. padding: #{24rpx};
  187. background-color: #FFFFFF;
  188. width: 100%;
  189. height: #{100rpx};
  190. position: fixed;
  191. left: 0;
  192. top: 0;
  193. .box {
  194. padding: 0 #{20rpx};
  195. margin-right: #{16rpx};
  196. border-radius: #{26rpx};
  197. font-size: $uni-font-size-general-two;
  198. height: 100%;
  199. &.background {
  200. background-color: #f1f1f1;
  201. color: $uni-general-color-one;
  202. }
  203. }
  204. }
  205. .list {
  206. background-color: #ffffff;
  207. padding: 0 #{24rpx};
  208. .block {
  209. padding: 0;
  210. }
  211. .comments {
  212. padding: #{28rpx} 0;
  213. width: 100%;
  214. word-break: break-all;
  215. .title {
  216. font-size: $uni-font-size-general-one;
  217. color: $uni-general-color-two;
  218. margin-bottom: #{28rpx};
  219. image {
  220. width: #{56rpx};
  221. height: #{56rpx};
  222. display: block;
  223. margin-right: #{26rpx};
  224. border-radius: #{28upx};
  225. }
  226. }
  227. &.bt {
  228. border-top: #{1rpx} solid #e2e2e2;
  229. }
  230. &.bb {
  231. border-bottom: #{1rpx} solid #e2e2e2;
  232. }
  233. &.bb:last-child {
  234. border: none;
  235. }
  236. .content {
  237. word-break: break-all;
  238. text-overflow: ellipsis;
  239. display: -webkit-box;
  240. -webkit-box-orient: vertical;
  241. -webkit-line-clamp: 2;
  242. overflow: hidden;
  243. }
  244. .pic-list {
  245. image {
  246. width: #{200rpx};
  247. height: #{200rpx};
  248. display: inline-block;
  249. margin: #{20rpx} #{20rpx} 0 0;
  250. }
  251. }
  252. .replay {
  253. width: 100%;
  254. background-color: $uni-weak-color-two;
  255. padding: #{28rpx};
  256. border-radius: #{16rpx};
  257. font-size: $uni-font-size-general-one;
  258. color: $uni-general-color-one;
  259. }
  260. }
  261. }
  262. }
  263. </style>