collect.vue 7.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167
  1. <template>
  2. <div class="w-full min-h-[70vh] bg-page pt-6">
  3. <div class="main-container flex justify-between" >
  4. <sidebar></sidebar>
  5. <el-card class="box-card flex-1 ml-4" shadow="never" v-loading="goodsTableData.loading">
  6. <el-tabs v-model="activeName" class="demo-tabs" @tab-change="handleClick">
  7. <el-tab-pane :label="t('productCollection')" name="product"></el-tab-pane>
  8. <el-tab-pane :label="t('storeCollection')" name="store"></el-tab-pane>
  9. </el-tabs>
  10. <div v-if="activeName == 'product'">
  11. <div v-if="goodsTableData.data.length && !goodsTableData.loading">
  12. <div class="flex flex-wrap min-h-[500px]">
  13. <template v-for="(item,index) in goodsTableData.data" :key="index">
  14. <div class="w-[224px] p-[16px] bg-[#fff] h-[344px] mb-[20px] cursor-pointer goods-item border-[1px] border-solid border-[#efefef]" :class="{'mr-[20px]': (index + 1) % 5 }" @click="toGoodsDetail(item.goods.goods_id)">
  15. <div class="w-[192px] h-[192px]">
  16. <el-image class="w-[192px] h-[192px]" :src="img(item.goods_cover_thumb_mid ? item.goods_cover_thumb_mid : '')" fit="cover" />
  17. </div>
  18. <div class="mt-[12px] font-bold text-[22px] text-[var(--el-color-primary)]">¥{{item.goods_sku.price}}</div>
  19. <div class="mt-[12px] flex items-center multi-hidden text-[14px] leading-[20px] text-[#5a5a5a] h-[40px]">
  20. {{item.goods_name}}
  21. </div>
  22. <div class="flex justify-between items-center mt-[12px]">
  23. <div class="flex items-center">
  24. <span class="iconfont icon-Vector-25 text-[#999] mr-[6px]"></span>
  25. <span v-if="item.site" class="text-[14px] text-[#999] max-w-[100px] truncate">{{ item.site.site_name}}</span>
  26. </div>
  27. <span title="取消收藏" class="text-[16px] text-[var(--el-color-primary)] iconfont icon-yishoucang cursor-pointer" @click.stop="cancelCollectGoods(item.goods.goods_id)"></span>
  28. </div>
  29. </div>
  30. </template>
  31. </div>
  32. <div class="mt-[16px] flex justify-end">
  33. <el-pagination v-model:current-page="goodsTableData.page" v-model:page-size="goodsTableData.limit" layout="total, sizes, prev, pager, next, jumper" :total="goodsTableData.total" @size-change="loadGoodsList()" @current-change="loadGoodsList" />
  34. </div>
  35. </div>
  36. <div class="min-h-[300px]" v-if="!goodsTableData.data.length && !goodsTableData.loading">
  37. <el-empty description="暂无数据" :image-size="200" :image="img('static/resource/images/system/empty.png')"/>
  38. </div>
  39. </div>
  40. <div v-if="activeName == 'store'">
  41. <div v-if="shopTableData.data.length">
  42. <div class="flex flex-wrap">
  43. <template v-for="(item,index) in shopTableData.data" :key="index">
  44. <div class="px-[15px] flex flex-col items-center justify-center w-[210px] h-[240px] box-border border-[1px] border-solid border-[#efefef]" :class="{'mr-[20px]': (index + 1)% 3}">
  45. <div class="w-[61px] h-[61px] mt-[30px] mb-[15px]">
  46. <img :src="img(item.site.icon)" class="max-h-[61px] max-w-full align-middle" v-if="item.site.icon"/>
  47. <img src="@/assets/images/shop_default.png" class="max-h-[61px] max-w-full align-middle" v-else/>
  48. </div>
  49. <div class="font-700 text-[#333] text-[16px]">{{item.site.site_name}}</div>
  50. <div class="mt-[20px] w-[100%] px-[12px] flex items-center justify-between">
  51. <el-button link @click="toShopDetail(item.site.site_id)">进店逛逛</el-button>
  52. <div class="w-[1px] h-[20px] bg-[#f3f3f3]"></div>
  53. <el-button link @click="cancelCollectShop(item.site.site_id,0)">取消关注</el-button>
  54. </div>
  55. </div>
  56. </template>
  57. </div>
  58. <div class="mt-[16px] flex justify-end">
  59. <el-pagination v-model:current-page="shopTableData.page" v-model:page-size="shopTableData.limit" layout="total, sizes, prev, pager, next, jumper" :total="shopTableData.total" @size-change="loadShopList()" @current-change="loadShopList" />
  60. </div>
  61. </div>
  62. <div class="min-h-[300px]" v-if="!shopTableData.data.length">
  63. <el-empty description="暂无数据" :image-size="200" :image="img('static/resource/images/system/empty.png')"/>
  64. </div>
  65. </div>
  66. </el-card>
  67. </div>
  68. </div>
  69. </template>
  70. <script lang="ts" setup>
  71. import { reactive, ref } from 'vue'
  72. import type { UploadProps } from 'element-plus'
  73. import { getCollectList, cancelCollect} from '@/addon/mall/api/goods'
  74. import { getShopFollowList , editShopCollect} from '@/addon/mall/api/shop'
  75. import { useRouter } from 'vue-router'
  76. const router = useRouter()
  77. const activeName = ref('product')
  78. // 获取会员列表
  79. const goodsTableData = reactive({
  80. page: 1,
  81. limit: 10,
  82. total: 0,
  83. loading: true,
  84. data: []
  85. })
  86. const loadGoodsList = (page: number = 1) => {
  87. goodsTableData.loading = true
  88. goodsTableData.page = page
  89. getCollectList({
  90. page: goodsTableData.page,
  91. limit: goodsTableData.limit,
  92. }).then(res => {
  93. goodsTableData.loading = false
  94. goodsTableData.data = res.data.data
  95. goodsTableData.total = res.data.total
  96. }).catch(() => {
  97. goodsTableData.loading = false
  98. })
  99. }
  100. loadGoodsList()
  101. // 获取店铺列表
  102. const shopTableData = reactive({
  103. page: 1,
  104. limit: 10,
  105. total: 0,
  106. loading: true,
  107. data: []
  108. })
  109. const loadShopList = (page: number = 1) => {
  110. shopTableData.loading = true
  111. shopTableData.page = page
  112. getShopFollowList({
  113. page: shopTableData.page,
  114. limit: shopTableData.limit,
  115. }).then(res => {
  116. shopTableData.loading = false
  117. shopTableData.data = res.data.data
  118. shopTableData.total = res.data.total
  119. }).catch(() => {
  120. shopTableData.loading = false
  121. })
  122. }
  123. loadShopList()
  124. const handleClick = (event:any) => {
  125. activeName.value = event
  126. }
  127. // 店铺详情
  128. const toShopDetail = (id:any) => {
  129. router.push(`/shop/detail?site_id=${id}`)
  130. }
  131. // 店铺取消关注
  132. const cancelCollectShop = (id:any,is_follow:any) =>{
  133. editShopCollect({
  134. site_id: id,
  135. is_follow: is_follow
  136. }).then(res => {
  137. loadShopList()
  138. })
  139. }
  140. // 商品详情
  141. const toGoodsDetail = (goods_id:number) => {
  142. router.push(`/goods/detail?id=${goods_id}`)
  143. }
  144. // 商品取消收藏
  145. const cancelCollectGoods= (goods_id:number)=>{
  146. cancelCollect(goods_id).then(res => {
  147. loadGoodsList()
  148. })
  149. }
  150. </script>
  151. <style lang="scss" scoped>
  152. .box-card{
  153. border: none !important;
  154. }
  155. .text-color{
  156. color: var(--jjext-color-brand);
  157. }
  158. </style>