footprint.vue 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213
  1. <template>
  2. <view class="collect-container">
  3. <view class="collect-container__head bg-white" :style="{ height: headHeight + 'px' }">
  4. <view :style="{ height: headHeight + 'px', paddingTop: headTop + 'px' }">
  5. <view class="navigater flex align-center justify-between">
  6. <view class="back" :style="{ height: headHeight + 'px', lineHeight: headHeight + 'px' }" @tap="handleBack">
  7. <text class="wlIcon-fanhui1"></text>
  8. </view>
  9. <scroll-view scroll-x class="nav text-center">
  10. <view v-for="(item, index) in navList" :key="index" class="cu-item flex-sub"
  11. :class="[currentItemId === item.type ? 'text-orange cur' : '', index === 1 ? 'hidden-nav-item' : '']"
  12. @tap="handleSelect(item.type, index)">
  13. <text class="text-30">{{ item.type_text }}</text>
  14. </view>
  15. </scroll-view>
  16. </view>
  17. </view>
  18. </view>
  19. <!-- 主体 -->
  20. <swiper class="collect-container__main" :current-item-id="currentItemId" :style="{ height: windowHeight + 'px' }"
  21. @change="changeCurrent" @animationfinish="animationFinish">
  22. <swiper-item v-for="(data, keys) in navList" :key="keys" :item-id="data.type"
  23. :class="data.type === 'groups' ? 'hidden-swiper-item' : ''">
  24. <wanl-empty src="find_default3x" :text="$t('footprint.empty')" v-if="data.arrData.length === 0 && data.loaded" />
  25. <scroll-view class="content" scroll-y @scrolltolower="loadData">
  26. <view v-for="(item, footprint) in data.arrData" :key="footprint">
  27. <view class="wanl-gray text-sm margin-sm">
  28. {{ footprint }}
  29. </view>
  30. <view class="box">
  31. <view class="item" v-for="(goods, index) in item" :key="index">
  32. <image :src="$appKit.oss(goods.goods.image, 136, 126)" @tap="handleGoods(goods.goods_id)"></image>
  33. <view class="text-price margin-sm text-orange">{{ goods.goods.price }}</view>
  34. </view>
  35. </view>
  36. </view>
  37. <uni-load-more :status="data.loadingType" :content-text="contentText" />
  38. </scroll-view>
  39. </swiper-item>
  40. </swiper>
  41. </view>
  42. </template>
  43. <script>
  44. import { pullFootprintList } from '@/features/mall/mall-gateway'
  45. export default {
  46. data() {
  47. return {
  48. headHeight: 0,
  49. windowHeight: 0,
  50. headTop: 0,
  51. currentId: 0,
  52. currentItemId: 'goods',
  53. navList: [],
  54. contentText: {
  55. contentdown: ' ',
  56. contentrefresh: '',
  57. contentnomore: ''
  58. }
  59. }
  60. },
  61. onLoad() {
  62. const sysInfo = uni.getSystemInfoSync()
  63. const statusBarHeight = sysInfo.statusBarHeight || 0
  64. this.headTop = statusBarHeight
  65. this.headHeight = statusBarHeight + uni.upx2px(90)
  66. this.windowHeight = sysInfo.windowHeight - uni.upx2px(90)
  67. this.navList = [{
  68. type: 'goods',
  69. type_text: this.$t('footprint.my'),
  70. dataList: [],
  71. arrData: [],
  72. loadingType: 'more',
  73. current_page: 1
  74. }, {
  75. type: 'groups',
  76. type_text: this.$t('footprint.groups'),
  77. dataList: [],
  78. arrData: [],
  79. loadingType: 'more',
  80. current_page: 1
  81. }]
  82. this.contentText.contentrefresh = this.$t('footprint.loading')
  83. this.loadData()
  84. },
  85. methods: {
  86. async loadData(source) {
  87. let navItem = this.navList[this.currentId]
  88. if (!navItem) return
  89. if (navItem.loadingType == 'noMore') return
  90. if (source === 'tabChange' && navItem.loaded === true) return
  91. if (navItem.loadingType === 'loading') return
  92. navItem.loadingType = 'loading'
  93. try {
  94. const res = await pullFootprintList({
  95. type: navItem.type,
  96. page: navItem.current_page
  97. })
  98. navItem.current_page = res.current_page
  99. if (res.last_page === res.current_page) {
  100. navItem.loadingType = 'noMore'
  101. } else {
  102. navItem.loadingType = 'more'
  103. navItem.current_page++
  104. }
  105. res.data.forEach(item => {
  106. navItem.dataList.push(item)
  107. })
  108. navItem.arrData = this.formatData(navItem.dataList)
  109. this.$set(navItem, 'loaded', true)
  110. } catch (e) {
  111. navItem.loadingType = 'more'
  112. console.error('[footprint] load failed:', e)
  113. }
  114. },
  115. handleSelect(id, index) {
  116. this.currentItemId = id
  117. this.currentId = index
  118. },
  119. handleGoods(id) {
  120. if (this.currentItemId === 'goods') {
  121. uni.navigateTo({ url: `/pages/product/goods?id=${id}` })
  122. } else if (this.currentItemId === 'groups') {
  123. uni.navigateTo({ url: `/pages/apps/groups/goods?id=${id}` })
  124. }
  125. },
  126. changeCurrent(e) {
  127. this.currentItemId = e.detail.currentItemId
  128. this.currentId = e.detail.current
  129. this.loadData('tabChange')
  130. },
  131. handleBack() {
  132. uni.navigateBack({ delta: 1 })
  133. },
  134. animationFinish(e) {
  135. this.changeCurrent(e)
  136. },
  137. formatData(data) {
  138. var groups = {}
  139. data.forEach(res => {
  140. var cate = this.getLocalTime(res.createtime)
  141. if (!groups[cate]) {
  142. groups[cate] = []
  143. }
  144. groups[cate].push(res)
  145. })
  146. return groups
  147. },
  148. getLocalTime(nS) {
  149. return new Date(parseInt(nS) * 1000).toLocaleDateString().replace(/\//g, '-')
  150. }
  151. }
  152. }
  153. </script>
  154. <style lang="scss">
  155. .collect-container {
  156. &__head {
  157. .navigater {
  158. position: relative;
  159. .back {
  160. position: absolute;
  161. left: 25rpx;
  162. z-index: 9999;
  163. text {
  164. font-size: 36rpx;
  165. font-weight: bold;
  166. }
  167. }
  168. }
  169. }
  170. &__main {
  171. position: relative;
  172. z-index: 99;
  173. .content {
  174. height: 100%;
  175. .box {
  176. display: flex;
  177. flex-wrap: wrap;
  178. justify-content: space-between;
  179. &:after {
  180. content: "";
  181. width: 33%;
  182. }
  183. .item {
  184. width: 33%;
  185. background-color: #ffffff;
  186. margin-bottom: 5rpx;
  187. image {
  188. height: 230rpx;
  189. }
  190. }
  191. }
  192. }
  193. }
  194. }
  195. .hidden-nav-item {
  196. display: none !important;
  197. }
  198. .hidden-swiper-item {
  199. display: none !important;
  200. }
  201. </style>