follow.vue 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184
  1. <template>
  2. <view class="page">
  3. <PageHeader title="" style="border: 1px solid #F2F6F2;">
  4. <template slot="center">
  5. <view class="tabs">
  6. <view class="tab" :class="{ active: activeTab === 'following' }" @click="switchTab('following')">关注
  7. </view>
  8. <view class="tab" :class="{ active: activeTab === 'followers' }" @click="switchTab('followers')">粉丝
  9. </view>
  10. </view>
  11. </template>
  12. </PageHeader>
  13. <view class="reserveASeat"></view>
  14. <view class="follow-list">
  15. <view class="follow-item" v-for="(item, index) in currentList" :key="index"
  16. >
  17. <CircleAvatar class="avator" v-if="item.avator" :src="item.avator"> @click="goToUserHomepage(item.user_id)"</CircleAvatar>
  18. <view class="info" @click="goToUserHomepage(item.user_id)">
  19. <view class="top-box">
  20. <view class="name">{{ item.nickname }}</view>
  21. <image src="../../static/icon/wd_icon_nan.png" mode="widthFix" v-if="item.sex_id == 1" />
  22. <image src="../../static/icon/wd_icon_nv.png" mode="widthFix" v-else-if="item.sex_id == 2" />
  23. <view class="level">Lv{{ item.level }}</view>
  24. </view>
  25. <view class="desc">{{ item.description }}</view>
  26. </view>
  27. <view :class="item.is_attention ? 'unfollow-btn' : 'unfollow-btn active'" @click="toggleFollow(item)">
  28. <image src="../../static/me/wd_icon_guanzhu.png"></image>
  29. {{ item.is_attention ? '取消关注' : '关注' }}
  30. </view>
  31. </view>
  32. </view>
  33. </view>
  34. </template>
  35. <script>
  36. import PageHeader from '@/components/PageHeader/PageHeader.vue';
  37. import CircleAvatar from "@/components/CircleAvatar/CircleAvatar.vue";
  38. export default {
  39. components: {
  40. PageHeader,
  41. CircleAvatar
  42. },
  43. data() {
  44. return {
  45. activeTab: 'following', // 当前激活的标签
  46. followList: [],
  47. fansList: [],
  48. isLoadingFollow: false, // 是否正在加载关注列表
  49. hasMoreFollow: true, // 是否有更多关注数据可加载
  50. followOffset: 0,
  51. }
  52. },
  53. computed: {
  54. // 根据当前标签返回对应的列表数据
  55. currentList() {
  56. return this.activeTab === 'following' ? this.followList : this.fansList;
  57. }
  58. },
  59. onLoad() {
  60. this.switchTab('following');
  61. },
  62. methods: {
  63. // 切换标签
  64. switchTab(tab) {
  65. if (tab) {
  66. this.activeTab = tab;
  67. }
  68. this.isLoadingFollow = false // 是否正在加载关注列表
  69. this.hasMoreFollow = true // 是否有更多关注数据可加载
  70. this.followOffset = 0
  71. this.followList= []
  72. // 加载对应的数据
  73. this.loadFollowList();
  74. },
  75. toggleFollow(item) {
  76. // 关注的逻辑
  77. uni.request({
  78. url: this.$apiHost + '/Member/attention',
  79. data: {
  80. uuid: getApp().globalData.uuid,
  81. id: item.user_id,
  82. },
  83. header: {
  84. "content-type": "application/json",
  85. 'sign': getApp().globalData.headerSign
  86. },
  87. success: (res) => {
  88. console.log("关注结果:", res.data);
  89. uni.showToast({
  90. title: res.data.str,
  91. icon: 'none'
  92. });
  93. if (res.data.success === "yes") {
  94. item.is_attention = !item.is_attention;
  95. }
  96. },
  97. fail: (e) => {
  98. console.log("关注失败:", e);
  99. uni.showToast({
  100. title: '网络请求失败',
  101. icon: 'none'
  102. });
  103. }
  104. });
  105. // 这里可以添加调用后端API的逻辑
  106. },
  107. loadFollowList() {
  108. if (this.isLoadingFollow) return;
  109. this.isLoadingFollow = true;
  110. // 关系类型: following(我关注的用户) 或 followers(关注我的用户)
  111. uni.request({
  112. url: this.$apiHost + "/User/getAttentions",
  113. data: {
  114. uuid: getApp().globalData.uuid,
  115. skey: getApp().globalData.skey,
  116. offset: this.followOffset,
  117. type: this.activeTab,
  118. },
  119. header: {
  120. "content-type": "application/json",
  121. sign: getApp().globalData.headerSign,
  122. },
  123. success: (res) => {
  124. console.log("用户列表数据:", res.data);
  125. // 确保在任何情况下都完成加载
  126. if (
  127. res.data.success == "yes" &&
  128. res.data.list &&
  129. res.data.list.length > 0
  130. ) {
  131. // 只有当列表有数据时才追加
  132. if (this.activeTab == 'following') {
  133. this.followList = [...this.followList, ...res.data.list];
  134. }
  135. if (this.activeTab == 'followers') {
  136. this.fansList = [...this.fansList, ...res.data.list];
  137. }
  138. this.followOffset += res.data.list.length;
  139. if (res.data.list.length < 20) {
  140. this.hasMoreFollow = false;
  141. }
  142. } else {
  143. // 如果列表为空,确保标记没有更多数据
  144. this.hasMoreFollow = false;
  145. }
  146. // 无论是否有数据,都需要通知z-paging组件完成刷新
  147. },
  148. complete: () => {
  149. this.isLoadingFollow = false;
  150. },
  151. fail: (e) => {
  152. this.isLoadingFollow = false;
  153. },
  154. });
  155. },
  156. goToUserHomepage(id) {
  157. if (!id) {
  158. return;
  159. }
  160. uni.navigateTo({
  161. url: "/pages/my/userHomepage?id=" + id,
  162. });
  163. },
  164. }
  165. }
  166. </script>
  167. <style scoped lang="scss">
  168. @import 'follow.scss';
  169. .reserveASeat{
  170. height: calc(90rpx + var(--status-bar-height) + 30rpx );
  171. }
  172. </style>