index.vue 7.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214
  1. <template>
  2. <view class="wanlshop-shop-container">
  3. <view :style="{ height: sys.headHeight + 'px' }">
  4. <shop-head class="wanlshop-shop-container__head" :headHeight="sys.headHeight" :headTop="sys.headTop"
  5. :tabbarId="tabbarId" :headTabbarId="headTabbarId" :shopId="shopData.id" :shopDescription="shopData.description"
  6. :pagesNum="pagesNum" @headId="handleHeadTabbarId" />
  7. </view>
  8. <view class="wanlshop-shop-container__main">
  9. <swiper class="page" v-show="tabbarId === 'home'" :current-item-id="headTabbarId"
  10. :style="{ height: sys.mainHeight + 'px' }" @change="changeCurrent" @animationfinish="animationFinish">
  11. <swiper-item item-id="page">
  12. <shop-page :windowHeight="sys.mainHeight" :pageModules="shopData.page" :shopData="shopData"
  13. @handleFollow="handleFollow" />
  14. </swiper-item>
  15. <swiper-item item-id="news">
  16. <shop-product :windowHeight="sys.mainHeight" :tabbarHeight="sys.tabbarHeight" :tabId="headTabbarId"
  17. :option="{ shop_id: shopData.id }" />
  18. </swiper-item>
  19. </swiper>
  20. <shop-product v-if="tabbarId === 'goods'" class="goods" :windowHeight="sys.mainHeight"
  21. :tabbarHeight="sys.tabbarHeight" :tabId="tabbarId" :option="{ shop_id: shopData.id }" />
  22. <shop-find v-if="tabbarId === 'find'" class="find" :windowHeight="sys.mainHeight" :tabbarHeight="sys.tabbarHeight"
  23. :userNo="shopData.find_user && shopData.find_user.user_no" />
  24. <shop-classify v-if="tabbarId === 'classify'" class="classify" :shopId="shopData.id" :mainHeight="sys.mainHeight"
  25. :categoryStyle="shopData.categoryStyle === 0 ? 1 : shopData.categoryStyle" :categoryData="shopData.category" />
  26. </view>
  27. <view class="wanlshop-shop-container__tabbar"
  28. :style="{ height: sys.tabbarHeight + 'px', paddingBottom: sys.tabbarBottom + 'px' }">
  29. <view class="cu-bar tabbar">
  30. <view class="action" @tap="handleTabbar('home')">
  31. <view v-if="handleActive('home')">
  32. <view class="cu-avatar round" :style="{ backgroundImage: 'url(' + (shopData.avatar || '') + ')' }" />
  33. </view>
  34. <view v-else>
  35. <view class="wlIcon wlIcon-dianpu text-bold"></view>
  36. <view>{{ $t('mall.shop.home') }}</view>
  37. </view>
  38. </view>
  39. <view class="action" :class="{ active: handleActive('goods') }" @tap="handleTabbar('goods')">
  40. <view class="wlIcon wlIcon-baobei text-bold"></view>
  41. <view>{{ $t('mall.shop.allGoods') }}</view>
  42. </view>
  43. <view class="action" :class="{ active: handleActive('find') }" @tap="handleTabbar('find')">
  44. <view class="wlIcon wlIcon-guanzhu1 text-bold"></view>
  45. <view>{{ $t('mall.shop.discover') }}</view>
  46. </view>
  47. <view class="action" :class="{ active: handleActive('classify') }" @tap="handleTabbar('classify')">
  48. <view class="wlIcon wlIcon-fenlei1 text-bold"></view>
  49. <view>{{ $t('mall.shop.category') }}</view>
  50. </view>
  51. <view class="action">
  52. <view @tap="toChat">
  53. <view class="wlIcon wlIcon-kefu text-bold"></view>
  54. <view>{{ $t('mall.shop.customerService') }}</view>
  55. </view>
  56. </view>
  57. </view>
  58. </view>
  59. </view>
  60. </template>
  61. <script>
  62. import { pullMallShopInfo, postShopFollow } from '@/features/mall/mall-gateway'
  63. import ShopHead from '@/components/shop/shop-head.vue'
  64. import ShopPage from '@/components/shop/shop-page.vue'
  65. import ShopProduct from '@/components/shop/shop-product.vue'
  66. import ShopFind from '@/components/shop/shop-find.vue'
  67. import ShopClassify from '@/components/shop/shop-classify.vue'
  68. export default {
  69. components: { ShopHead, ShopPage, ShopProduct, ShopFind, ShopClassify },
  70. data() {
  71. return {
  72. tabbarId: 'home',
  73. headTabbarId: 'page',
  74. pagesNum: 0,
  75. sys: { headTop: 0, headHeight: 0, mainHeight: 0, tabbarBottom: 0, tabbarHeight: 0 },
  76. shopData: {
  77. id: 0, avatar: '', shopname: '', state: 0, islive: 0, isself: 0, categoryStyle: 1,
  78. find_user: { user_no: '', fans: 0 },
  79. isFollow: 0
  80. }
  81. }
  82. },
  83. onReady() {
  84. const sys = uni.getSystemInfoSync()
  85. const headHeight = sys.statusBarHeight + uni.upx2px(88)
  86. const tabbarHeight = (sys.safeAreaInsets ? sys.safeAreaInsets.bottom : 0) + uni.upx2px(100)
  87. this.sys = {
  88. headTop: sys.statusBarHeight,
  89. headHeight: headHeight,
  90. mainHeight: sys.windowHeight - headHeight,
  91. tabbarBottom: sys.safeAreaInsets ? sys.safeAreaInsets.bottom : 0,
  92. tabbarHeight: tabbarHeight
  93. }
  94. },
  95. onLoad(query) {
  96. this.pagesNum = getCurrentPages().length
  97. const id = query.id || query.scene || 0
  98. this.loadData(id)
  99. },
  100. methods: {
  101. async loadData(id) {
  102. try {
  103. const data = await pullMallShopInfo(id)
  104. this.shopData = data
  105. } catch (e) {
  106. console.error('加載店鋪失敗', e)
  107. }
  108. },
  109. async handleFollow() {
  110. if (!this.$store.state.user.isLogin) {
  111. uni.navigateTo({ url: '/pages/user/auth/newpreLogin' })
  112. return
  113. }
  114. try {
  115. const user_no = this.shopData.find_user && this.shopData.find_user.user_no
  116. if (!user_no) return
  117. const result = await postShopFollow(user_no)
  118. // result 返回 {data: 1} 表示关注,{data: 0} 表示取消关注
  119. const followState = result.data
  120. this.shopData.isFollow = followState
  121. if (followState === 1) {
  122. this.shopData.find_user.fans += 1
  123. } else if (followState === 0) {
  124. this.shopData.find_user.fans -= 1
  125. }
  126. // 更新统计数据
  127. if (this.shopData.isself === 1) {
  128. const concern = this.$store.state.statistics.dynamic.concern
  129. this.$store.commit('statistics/dynamic', {
  130. concern: followState === 1 ? concern + 1 : concern - 1
  131. })
  132. }
  133. } catch (e) {
  134. console.error('关注操作失败', e)
  135. }
  136. },
  137. animationFinish(e) {
  138. this.changeCurrent(e)
  139. },
  140. changeCurrent(e) {
  141. this.headTabbarId = e.detail.currentItemId
  142. },
  143. handleTabbar(name) {
  144. this.tabbarId = name
  145. },
  146. handleActive(name) {
  147. return this.tabbarId === name
  148. },
  149. handleHeadTabbarId(name) {
  150. this.headTabbarId = name
  151. },
  152. toChat() {
  153. uni.navigateTo({ url: '/pages/notice/chat?shop_id=' + this.shopData.id })
  154. }
  155. }
  156. }
  157. </script>
  158. <style lang="scss" scoped>
  159. .wanlshop-shop-container {
  160. background-color: #ffffff;
  161. &__head {
  162. position: fixed;
  163. top: 0;
  164. z-index: 999;
  165. width: 100%;
  166. background-color: #ffffff;
  167. }
  168. &__main {
  169. .classify {
  170. background-color: #f9f9f9;
  171. }
  172. .find {
  173. background-color: #f9f9f9;
  174. border-radius: 30rpx 30rpx 0 0;
  175. overflow: hidden;
  176. }
  177. }
  178. &__tabbar {
  179. position: fixed;
  180. left: 0;
  181. right: 0;
  182. bottom: 0;
  183. background-color: rgba(255, 255, 255, 0.96);
  184. z-index: 999;
  185. .cu-bar {
  186. color: #555;
  187. .action {
  188. [class*="wlIcon-"] {
  189. font-size: 45rpx;
  190. }
  191. &.active {
  192. color: #f40;
  193. }
  194. .cu-avatar {
  195. background-color: #f1f1f1;
  196. height: 74rpx;
  197. width: 74rpx;
  198. }
  199. }
  200. }
  201. }
  202. }
  203. </style>