index.vue 6.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178
  1. <template>
  2. <view class="bg-[#F6F6F6] min-h-screen overflow-hidden order-list" :style="themeColor()">
  3. <view class="fixed left-0 top-0 right-0 z-10 box-border px-[30rpx] bg-white">
  4. <view class="flex whitespace-nowrap justify-between">
  5. <view :class="['text-[28rpx] leading-[90rpx] flex-1 text-center', { 'class-select': collectState === item.status}]" @click="orderStateFn(item.status)" v-for="(item, index) in collectList">{{ item.name }}</view>
  6. </view>
  7. </view>
  8. <mescroll-body ref="mescrollRef" top="90rpx" @init="mescrollInit" @down="downCallback" @up="getCollectFn">
  9. <view class="mx-[30rpx] mt-[20rpx]" v-if="list.length">
  10. <view v-if="collectState == 'goods'">
  11. <template v-for="(item, index) in list" :key="index">
  12. <view class="mb-[20rpx] bg-[#fff] p-[20rpx] rounded-[16rpx]">
  13. <view class="flex box-border" @click="toLink(item.goods.goods_id)">
  14. <view class="w-[150rpx] h-[150rpx]">
  15. <u--image class="rounded-[10rpx] overflow-hidden" width="150rpx" height="150rpx" :src="img(item.goods.goods_cover ? item.goods.goods_cover : '')" model="aspectFill">
  16. <template #error>
  17. <u-icon name="photo" color="#999" size="50"></u-icon>
  18. </template>
  19. </u--image>
  20. </view>
  21. <view class="ml-[20rpx] flex flex-1 flex-col justify-between box-border">
  22. <view class="text-[28rpx] text-item leading-[40rpx] text-[#303133]">
  23. {{ item.goods_name }}
  24. </view>
  25. <view class="flex justify-end items-center">
  26. <view @click.stop="cancelCollectGoods(item.goods.goods_id)">
  27. <u-button :customStyle="{width:'150rpx',height:'56rpx',color:'#333', fontSize:'24rpx',lineHeight:'56rpx',margin:'0rpx'}" shape="circle" :text="t('uncollect')"></u-button>
  28. </view>
  29. </view>
  30. </view>
  31. </view>
  32. </view>
  33. </template>
  34. </view>
  35. <view v-else>
  36. <template v-for="(item, index) in list" :key="index">
  37. <view class="mb-[20rpx] bg-[#fff] p-[20rpx] rounded-[16rpx] flex justify-between items-center box-border" @click="toShopDetail(item.site.site_id)">
  38. <view class="flex items-center">
  39. <u--image class="rounded-[10rpx] overflow-hidden" width="60rpx" height="60rpx" :src="img(item.site.icon ? item.site.icon : '')" model="aspectFill">
  40. <template #error>
  41. <u-icon name="photo" color="#999" size="20"></u-icon>
  42. </template>
  43. </u--image>
  44. <view class="ml-[20rpx]">{{item.site.site_name}}</view>
  45. </view>
  46. <view @click.stop="cancelCollectShop(item.site.site_id,0)">
  47. <u-button :customStyle="{width:'150rpx',height:'56rpx',color:'#333', fontSize:'24rpx',lineHeight:'56rpx',margin:'0rpx'}" shape="circle" :text="t('followed')"></u-button>
  48. </view>
  49. </view>
  50. </template>
  51. </view>
  52. </view>
  53. <mescroll-empty :option="{tip : '暂无数据'}" v-if="!list.length && loading"></mescroll-empty>
  54. </mescroll-body>
  55. </view>
  56. </template>
  57. <script setup lang="ts">
  58. import { ref } from 'vue';
  59. import { t } from '@/locale'
  60. import { img, redirect } from '@/utils/common';
  61. import { getCollectList, cancelCollect } from '@/addon/mall/api/goods';
  62. import { getShopFollowList , editShopCollect} from '@/addon/mall/api/shop';
  63. import MescrollBody from '@/components/mescroll/mescroll-body/mescroll-body.vue';
  64. import MescrollEmpty from '@/components/mescroll/mescroll-empty/mescroll-empty.vue';
  65. import useMescroll from '@/components/mescroll/hooks/useMescroll.js';
  66. import { onLoad, onPageScroll, onReachBottom } from '@dcloudio/uni-app';
  67. const { mescrollInit, downCallback, getMescroll } = useMescroll(onPageScroll, onReachBottom);
  68. let list = ref<Array<Object>>([]);
  69. let loading = ref<boolean>(false);
  70. let collectState = ref('goods')
  71. let collectList = ref([{ name: '商品',status: 'goods'},{ name: '店铺',status: 'shop'}]);
  72. const getCollectFn = (mescroll) => {
  73. loading.value = false;
  74. let data: object = {
  75. page: mescroll.num,
  76. limit: mescroll.size
  77. };
  78. const api = collectState.value == 'goods' ? getCollectList : getShopFollowList
  79. api(data).then((res) => {
  80. let newArr = (res.data.data as Array<Object>);
  81. //设置列表数据
  82. if (mescroll.num == 1) {
  83. list.value = []; //如果是第一页需手动制空列表
  84. }
  85. list.value = list.value.concat(newArr);
  86. mescroll.endSuccess(newArr.length);
  87. loading.value = true;
  88. }).catch(() => {
  89. loading.value = true;
  90. mescroll.endErr(); // 请求失败, 结束加载
  91. })
  92. }
  93. const orderStateFn = (status) => {
  94. collectState.value = status
  95. list.value = [];
  96. getMescroll().resetUpScroll();
  97. };
  98. // 取消店铺关注
  99. const cancelCollectShop = (id:any,is_follow:any) =>{
  100. editShopCollect({
  101. site_id: id,
  102. is_follow: is_follow
  103. }).then(res => {
  104. list.value = [];
  105. getMescroll().resetUpScroll();
  106. })
  107. }
  108. // 商品取消收藏
  109. const cancelCollectGoods= (goods_id:number)=>{
  110. cancelCollect(goods_id).then(res => {
  111. list.value = [];
  112. getMescroll().resetUpScroll();
  113. })
  114. }
  115. //进入店铺
  116. const toShopDetail = (id) => {
  117. redirect({ url: '/app/pages/site/index', param: { site_id: id } })
  118. }
  119. // 商品详情
  120. const toLink = (id) => {
  121. redirect({ url: '/addon/mall/pages/goods/detail', param: { goods_id: id } })
  122. }
  123. </script>
  124. <style>
  125. .order-list .mescroll-body {
  126. padding-bottom: constant(safe-area-inset-bottom) !important;
  127. padding-bottom: env(safe-area-inset-bottom) !important;
  128. }
  129. </style>
  130. <style lang="scss" scoped>
  131. .text-item {
  132. overflow: hidden;
  133. text-overflow: ellipsis;
  134. display: -webkit-box;
  135. -webkit-line-clamp: 2;
  136. -webkit-box-orient: vertical;
  137. }
  138. .font-scale {
  139. transform: scale(0.75);
  140. }
  141. .text-color {
  142. color: var(--primary-color);
  143. }
  144. .bg-color {
  145. background-color: var(--primary-color);
  146. }
  147. .class-select {
  148. position: relative;
  149. font-weight: 500;
  150. color: var(--primary-color);
  151. &::before {
  152. content: "";
  153. position: absolute;
  154. bottom: 0;
  155. height: 4rpx;
  156. border-radius: 4rpx;
  157. background-color: var(--primary-color);
  158. width: 40rpx;
  159. left: 50%;
  160. transform: translateX(-50%);
  161. }
  162. }
  163. .noData{
  164. height: calc(100vh - 130rpx - constant(safe-area-inset-bottom));
  165. height: calc(100vh - 130rpx - env(safe-area-inset-bottom));
  166. }
  167. </style>