follow.vue 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411
  1. <template>
  2. <view class="follow">
  3. <mescroll-uni ref="mescrollRef" top="0" :height="height" @init="initMescroll" @down="downCallback"
  4. @up="upCallback" :down="downOption" :up="upOption">
  5. <block v-for="(item, index) in lists" :key="index">
  6. <view class="content-box">
  7. <!-- 内容头部信息 -->
  8. <router-link :to="'/bundle_b/pages/community_user/community_user?id=' + item.user.id">
  9. <view class="header flex row-between">
  10. <view class="flex">
  11. <!-- 头像 -->
  12. <u-image width="70" height="70" :src="item.user.avatar" borderRadius="50%"></u-image>
  13. <!-- 昵称 -->
  14. <text class="normal bold m-l-16">{{ item.user.nickname }}</text>
  15. </view>
  16. <view>
  17. <text class="muted">{{ item.create_time }}</text>
  18. </view>
  19. </view>
  20. </router-link>
  21. <!-- 内容媒体信息 -->
  22. <view class="swiper-container">
  23. <product-swiper :imgUrls="item.images" :autoplay="false" borderRadius="14"></product-swiper>
  24. </view>
  25. <!-- 提到的宝贝( 商品 ) -->
  26. <view class="goods-box bb flex row-between" @click="handleOpenGoods(item.id)"
  27. v-if="item.goods_data.length">
  28. <text class="nr lighter">查看TA提到的宝贝({{item.goods_data.length}})</text>
  29. <!-- <text class="tips xs">300+人评价</text> -->
  30. <view class="goods flex">
  31. <block v-for="(goodsItem, goodsIndex) in item.goods_data" :key="goodsItem.id">
  32. <u-image v-if="goodsIndex <= 2" :src="goodsItem.image" width="58" height="58"
  33. class="m-l-6"></u-image>
  34. </block>
  35. <u-icon name="arrow-right" class="m-l-10"></u-icon>
  36. </view>
  37. </view>
  38. <!-- 提到的店铺( 店铺 ) -->
  39. <view class="goods-box bb flex row-between" @click="handleOpenShop(item.id)"
  40. v-if="item.shop_data.length">
  41. <text class="nr lighter">查看TA提到的店铺({{item.shop_data.length}})</text>
  42. <!-- <text class="tips xs">300+人评价</text> -->
  43. <view class="goods flex">
  44. <block v-for="(shopItem, shopIndex) in item.shop_data" :key="shopIndex">
  45. <u-image v-if="shopIndex <= 2" :src="shopItem.logo" width="58" height="58"
  46. class="m-l-6"></u-image>
  47. </block>
  48. <u-icon name="arrow-right" class="m-l-10"></u-icon>
  49. </view>
  50. </view>
  51. <!-- 内容文字 -->
  52. <view class="content ">
  53. <view class="text" v-if="item.show">
  54. {{ item.beforeContent }}...
  55. <text class="primary nr m-l-20" @click="handleShowContent(index)">展开</text>
  56. </view>
  57. <view class="text" v-else>
  58. {{ item.content }}
  59. </view>
  60. <view class="tags" v-if="item.topic">
  61. <navigator hover-class="none"
  62. :url="'/bundle_b/pages/community_topic/community_topic?id=' + item.topic.id +'&name=' + item.topic.name">
  63. <text class="sm"># {{ item.topic.name }}</text>
  64. </navigator>
  65. </view>
  66. </view>
  67. <!-- 底部 -->
  68. <view class="footer flex row-between">
  69. <view>
  70. <button open-type="share" @click="handleShare(item)" class="flex-col col--center"
  71. hover-class="none">
  72. <image src="/static/images/icon_forward.png"></image>
  73. </button>
  74. </view>
  75. <view class="flex nr lighter">
  76. <view class="flex likes-box">
  77. <view class="likes" :class="item.is_like==0 ? 'leave':'entry'"
  78. @click="handleCommunityLike(item.is_like, item)">
  79. </view>
  80. <image class="m-l-30"></image>
  81. <text>{{ item.like }}</text>
  82. </view>
  83. <view class=" m-l-40" @click="handleOpenComment(item.id)">
  84. <image src="/static/images/icon_evaluate.png"></image>
  85. <text>{{ item.comment }}</text>
  86. </view>
  87. </view>
  88. </view>
  89. </view>
  90. </block>
  91. </mescroll-uni>
  92. <!-- 提到的商品 -->
  93. <community-goods v-model="showGoodsPopup" v-if="showGoodsPopup" :communityId="communityId"></community-goods>
  94. <!-- 提到的店铺 -->
  95. <community-shop v-model="showShopPopup" :communityId="communityId"></community-shop>
  96. <!-- 评论 -->
  97. <community-comment-popup v-model="showComment" v-if="showComment" :communityId="communityId">
  98. </community-comment-popup>
  99. <!-- #ifdef H5 -->
  100. <u-popup :custom-style="{'background': 'none'}" class="share-tips" v-model="showTips" mode="top">
  101. <view style="overflow: hidden;">
  102. <image src="/static/images/share_arrow.png" class="share-arrow" />
  103. <view class="white" style="text-align: center;margin-top: 280rpx;">
  104. <view class="bold lg">立即分享给好友吧</view>
  105. <view class="sm m-t-10">点击屏幕右上角将本页面分享给好友</view>
  106. </view>
  107. </view>
  108. </u-popup>
  109. <!-- #endif -->
  110. </view>
  111. </template>
  112. <script>
  113. import {
  114. getCommunityFollow,
  115. apiCommunityCommentLike
  116. } from '@/api/community.js';
  117. import {
  118. debounce
  119. } from "@/utils/tools.js"
  120. import MescrollMixin from "@/components/mescroll-uni/mescroll-mixins.js";
  121. import MescrollMoreItemMixin from "@/components/mescroll-uni/mixins/mescroll-more-item.js";
  122. export default {
  123. mixins: [MescrollMixin, MescrollMoreItemMixin],
  124. props: {
  125. active: {
  126. type: Number
  127. }
  128. },
  129. data() {
  130. return {
  131. height: '',
  132. canReset: true,
  133. isLikes: false,
  134. communityId: '',
  135. upOption: {
  136. empty: {
  137. icon: '/static/images/follow_null.png',
  138. tip: '暂未关注任何种草官哦~', // 提示
  139. fixed: true,
  140. top: "200rpx",
  141. }
  142. },
  143. lists: [],
  144. show: false,
  145. showGoodsPopup: false,
  146. showShopPopup: false,
  147. showTips: false,
  148. showComment: false
  149. }
  150. },
  151. watch: {
  152. active() {
  153. uni.$emit('hasNew', 0)
  154. this.mescroll.resetUpScroll()
  155. }
  156. },
  157. created() {
  158. this.handleCommunityLike = debounce(this.handleCommunityLike, 100)
  159. uni.getSystemInfo({
  160. success: (res) => {
  161. this.height = res.windowHeight - 46 + 'px';
  162. }
  163. });
  164. },
  165. methods: {
  166. initMescroll(event) {
  167. this.isInit = true; // 标记为true
  168. this.mescroll = event;
  169. },
  170. // 获取
  171. async upCallback(page) {
  172. const index = this.current;
  173. const pageNum = page.num
  174. const pageSize = page.size
  175. getCommunityFollow({
  176. page_no: pageNum,
  177. page_size: pageSize,
  178. }).then(res => {
  179. // 如果是第一页需手动置空列表
  180. if (pageNum == 1) this.lists = []
  181. // 重置列表数据
  182. const hasNext = !!res.data.more;
  183. res.data.list = this.handleContent(res.data.list)
  184. this.lists = [...this.lists, ...res.data.list]
  185. this.mescroll.endSuccess(res.data.list.length, hasNext);
  186. }).catch((err) => {
  187. this.mescroll.endErr()
  188. })
  189. },
  190. // 处理打开商品推荐
  191. handleOpenGoods(id) {
  192. this.communityId = id;
  193. this.showGoodsPopup = true;
  194. },
  195. // 处理打开获取店铺推荐
  196. handleOpenShop(id) {
  197. this.communityId = id;
  198. this.showShopPopup = true;
  199. },
  200. // 处理内容超过固定长度或换行的就显示展开
  201. handleContent(list) {
  202. return list.filter(item => {
  203. if (item.content.indexOf('\n') > -1) {
  204. const arr = item.content.split('\n')
  205. if (arr.length >= 3) {
  206. item.show = true
  207. if (arr[0].length >= 25 || arr[1].length >= 25 || arr[2].length > 20) {
  208. item.beforeContent = item.content.slice(0, arr[0].length + arr[1].length + arr[2].length - 10)
  209. } else {
  210. item.beforeContent = item.content.slice(0, arr[0].length + arr[1].length + arr[
  211. 2].length - 10)
  212. }
  213. } else {
  214. if (item.content.length >= 70) {
  215. item.show = true
  216. item.beforeContent = item.content.slice(0, 70)
  217. }
  218. }
  219. } else {
  220. if (item.content.length >= 70) {
  221. item.show = true
  222. item.beforeContent = item.content.slice(0, 70)
  223. }
  224. }
  225. return true
  226. })
  227. },
  228. // 展开内容
  229. handleShowContent(index) {
  230. this.$set(this.lists[index], 'show', false)
  231. },
  232. // 处理分享
  233. handleShare(item) {
  234. // #ifdef MP
  235. this.$emit('share', item)
  236. // #endif
  237. // #ifdef H5
  238. this.showTips = true
  239. // #endif
  240. // #ifndef MP
  241. this.$store.commit('setCommunity', {
  242. ...item,
  243. url: 'bundle_b/pages/community_detail/community_detail'
  244. })
  245. this.$store.dispatch('communityShare')
  246. // #endif
  247. },
  248. // 点赞
  249. handleCommunityLike(status, item) {
  250. switch (status) {
  251. case 0:
  252. this.$set(item, 'like', item.like + 1)
  253. this.$set(item, 'is_like', 1)
  254. break;
  255. case 1:
  256. this.$set(item, 'like', item.like - 1)
  257. this.$set(item, 'is_like', 0)
  258. break;
  259. }
  260. apiCommunityCommentLike({
  261. id: item.id,
  262. status: status ? 0 : 1,
  263. type: 1
  264. }).then(res => {
  265. if (res.code === 1) {
  266. // 点赞文章时 其他页面的状态也需要更改
  267. uni.$emit('changeItem', {
  268. like: item.like,
  269. is_like: item.is_like,
  270. id: item.id
  271. })
  272. } else {
  273. // 不成功把它们改回去
  274. switch (status) {
  275. case 0:
  276. this.$set(item, 'like', item.like - 1)
  277. this.$set(item, 'is_like', 0)
  278. break;
  279. case 1:
  280. this.$set(item, 'like', item.like + 1)
  281. this.$set(item, 'is_like', 1)
  282. break;
  283. }
  284. this.$toast({
  285. title: res.msg
  286. })
  287. }
  288. })
  289. },
  290. // 打开评论
  291. handleOpenComment(id) {
  292. this.communityId = id;
  293. this.showComment = true;
  294. }
  295. }
  296. }
  297. </script>
  298. <style lang="scss" scoped>
  299. .content-box {
  300. padding-bottom: 20rpx;
  301. background-color: $-color-white;
  302. .bb {
  303. border-bottom: 1px solid #f2f2f2;
  304. }
  305. .header {
  306. font-size: 28rpx;
  307. padding: 20rpx 24rpx;
  308. }
  309. .swiper-container {
  310. padding: 0 20rpx;
  311. }
  312. .goods-box {
  313. padding: 15rpx 24rpx;
  314. .tips {
  315. padding: 0 10rpx;
  316. color: $-color-primary;
  317. border-radius: 20rpx;
  318. border: 1px solid $-color-primary;
  319. }
  320. }
  321. .content {
  322. padding: 24rpx;
  323. padding-bottom: 0;
  324. .text {
  325. white-space: pre-line;
  326. line-height: 48rpx;
  327. font-size: 28rpx;
  328. color: $-color-normal;
  329. }
  330. .tags {
  331. padding-top: 24rpx;
  332. text {
  333. margin-right: 20rpx;
  334. border-radius: 26rpx;
  335. padding: 8rpx 24rpx;
  336. color: $-color-primary;
  337. background: rgba($-color-primary, .1);
  338. }
  339. }
  340. }
  341. .footer {
  342. padding: 0 24rpx;
  343. image {
  344. width: 44rpx;
  345. height: 44rpx;
  346. vertical-align: middle;
  347. margin: 24rpx 6rpx;
  348. }
  349. // 点赞动画
  350. .likes-box {
  351. position: relative;
  352. .likes {
  353. z-index: 99;
  354. left: -36rpx;
  355. width: 120rpx;
  356. height: 120rpx;
  357. margin-right: 6rpx;
  358. position: absolute;
  359. background: url('@/static/images/likes.png') no-repeat;
  360. background-position: left;
  361. background-size: cover;
  362. }
  363. // 没点赞
  364. .leave {
  365. background-position: left;
  366. }
  367. // 点赞
  368. .entry {
  369. background-position: right;
  370. transition: background .6s steps(28);
  371. }
  372. }
  373. }
  374. }
  375. .share-tips .share-arrow {
  376. width: 140rpx;
  377. height: 250rpx;
  378. float: right;
  379. margin: 15rpx 31rpx 0 0;
  380. }
  381. </style>