goods.vue 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439
  1. <template>
  2. <view class="goods">
  3. <scroll-view class="scroll-y" @scroll="handleScroll" :scroll-into-view="topItem" scroll-with-animation
  4. scroll-y="true">
  5. <navbarTransparent title="产品" />
  6. <view id="top"></view>
  7. <!-- 背景图 -->
  8. <view class="goods-img">
  9. <image v-if="bannerImg" style="width: 100vw; height: 82vw;" :src="bannerImg" mode="scaleToFill"></image>
  10. </view>
  11. <!-- 内容 -->
  12. <view class="main">
  13. <view class="search">
  14. <u-input placeholderStyle='color:#999' id="search-input" placeholder="搜索" border='none'
  15. v-model="search" @input="searchText(isActive,items[isActive].id)">
  16. <template slot="suffix" style='margin-right:40rpx;'>
  17. <u-image :showLoading="true" :showError='true' src="/static/icon/search.png" width="40rpx"
  18. height="32rpx"></u-image>
  19. </template>
  20. </u-input>
  21. </view>
  22. <view class="tab_nav">
  23. <view class="navTitle" v-for="(item,index) in items" :key="index">
  24. <view class="navTitle-item">
  25. <view :class="{'active':isActive === index}" @click="checked(index,item.id)">
  26. {{item.name}}
  27. </view>
  28. </view>
  29. </view>
  30. </view>
  31. </view>
  32. <view class="msg-null" v-if="goodsList.length == 0 ">
  33. <image src="https://t9.9026.com/imgs/dataNull.png" style="width: 394rpx;height: 396rpx;" mode="">
  34. </image>
  35. <view class="msg-null-text">
  36. <text>暂无数据</text>
  37. </view>
  38. </view>
  39. <view class="content" v-if="goodsList.length > 0 ">
  40. <view class="home-hotel-img-content">
  41. <template v-for="(item,index) in goodsList">
  42. <view v-if="item.status==1" @click="goGoodsDetail(item.id)" class="home-hotel-img-content-item"
  43. :key="index" :style="{marginTop:item.marginTop || 0 }">
  44. <image class="home-hotel-img-content-item-img"
  45. :class="item.short?'home-hotel-img-content-item-img': 'home-hotel-img-content-item-img-long' "
  46. :src="item.cover_img" mode=""></image>
  47. <view class="text">
  48. <text class="text-top">{{item.name}}</text>
  49. <!-- <text class="text-main">{{item.hotel.name}}</text> -->
  50. <text class="text-main"></text>
  51. </view>
  52. </view>
  53. </template>
  54. </view>
  55. <!-- 触底 -->
  56. <view class="home-bottom" v-if="goodsList.length > 0 ">
  57. <uni-load-more :status="status" color="#CCCCCC" :content-text="contentText" />
  58. </view>
  59. </view>
  60. </scroll-view>
  61. <!-- <view class="return-btn" v-if="isShow" @click="handleBackTop">
  62. <image style="width: 128rpx;height: 128rpx;" src="/static/icon/returntop.png" mode=""></image>
  63. </view> -->
  64. <view class="return-btn" @click="handleBackTop">
  65. <image style="width: 128rpx;height: 128rpx;" src="/static/icon/returntop.png" mode=""></image>
  66. </view>
  67. </view>
  68. </template>
  69. <script>
  70. import util from '@/utils/util.js'
  71. import navbarTransparent from "@/components/extra/navbarTransparent.vue"
  72. export default {
  73. components: {
  74. navbarTransparent
  75. },
  76. data() {
  77. return {
  78. //搜索
  79. search: '',
  80. //背景图
  81. bannerImg: '',
  82. // 返回的按钮是否显示
  83. isShow: false,
  84. topItem: '', //返回顶部的标记点
  85. contentText: {
  86. contentdown: '查看更多',
  87. contentrefresh: '加载中',
  88. contentnomore: '—— 已经到底啦 ——'
  89. },
  90. //分段器
  91. items: [],
  92. //激活指定table菜单
  93. isActive: 0,
  94. //第三方产品分类categoryId
  95. categoryId: '',
  96. goodsList: [],
  97. // 分页
  98. page: 1,
  99. pagesize: 15,
  100. totalElements: '',
  101. allListItem: '',
  102. // 组件uni-load-more
  103. status: 'noMore',
  104. };
  105. },
  106. onLoad() {
  107. this.shortLong()
  108. this.getCategoryList()
  109. //获取产品活动列表背景图
  110. this.bannerImg = this.$store.getters.allset.activity_page.value.bg_img
  111. },
  112. // 触底加载
  113. onReachBottom() {
  114. // 触底的时候请求数据,即为上拉加载更多
  115. var allTotal = this.page * this.pagesize
  116. console.log(allTotal, '----allTotal');
  117. //this.page为加载次数,this.pagesize为每一次加载的数据条数
  118. if (allTotal < this.totalElements) {
  119. //this.totalElements为请求数据的总条数。只要现有条数小于总条数就就执行一下代码
  120. this.allListItem = false;
  121. this.page++;
  122. //加载次数递加
  123. this.status = "loading"
  124. this.$api.product.getProducts({ //请求更多数据列表
  125. page: this.page,
  126. category_id: this.categoryId,
  127. keyword: this.search
  128. }).then(res => {
  129. let ret = [...this.goodsList, ...res.data.data]
  130. this.goodsList = ret
  131. console.log(ret)
  132. })
  133. } else {
  134. this.allListItem = true;
  135. console.log('已加载全部数据')
  136. this.status = "noMore"
  137. }
  138. },
  139. methods: {
  140. // 获取分类列表
  141. getCategoryList() {
  142. this.$api.category.getCategoryList({
  143. page: 1,
  144. type: 2
  145. }).then(res => {
  146. if (res.code == 0) {
  147. this.items = res.data.data
  148. this.categoryId = this.items[0].id
  149. console.log(this.categoryId, '--->this.categoryId');
  150. this.getGoodsList(this.categoryId)
  151. }
  152. })
  153. },
  154. //菜单index切换
  155. checked(index, id) {
  156. this.page = 1
  157. this.categoryId = id
  158. this.isActive = index
  159. this.getGoodsList(id)
  160. },
  161. //产品列表type:1,第三方购买产品
  162. getGoodsList(category_id) {
  163. this.$api.product.getProducts({
  164. type: 1,
  165. page: 0,
  166. keyword: this.search || '',
  167. category_id: `${category_id}`
  168. }).then(res => {
  169. this.goodsList = res.data.data.filter(item=>{
  170. return item.status == 1
  171. })
  172. this.totalElements = res.data.total
  173. this.pagesize = res.data.per_page
  174. this.shortLong()
  175. console.log(this.goodsList, '------>产品图');
  176. })
  177. },
  178. handleScroll(e) {
  179. //只有scrollTop有用,先拿scrollTop
  180. let {
  181. scrollTop
  182. } = e.detail
  183. //滑动大于500让按钮显示
  184. this.isShow = scrollTop > 500
  185. //因为点第二次不行,这里记得重置清空一下
  186. this.topItem = ''
  187. },
  188. handleBackTop() {
  189. // this.topItem = 'top'
  190. uni.pageScrollTo({
  191. scrollTop: 0
  192. })
  193. },
  194. shortLong() {
  195. this.goodsList.forEach((item, index, arr) => {
  196. if (index % 4 === 0) {
  197. item.short = true
  198. }
  199. if (index % 4 === 1) {
  200. item.long = true
  201. }
  202. if (index % 4 === 2) {
  203. item.long = true
  204. item.marginTop = -68 + "rpx"
  205. }
  206. if (index % 4 === 3) {
  207. item.short = true
  208. }
  209. })
  210. console.log(this.goodsList, '1111111111111');
  211. },
  212. // //去大转盘
  213. // goGoodsDetailImg() {
  214. // uni.navigateTo({
  215. // url: '/pages/goods/goods-lucky/index'
  216. // })
  217. // },
  218. //去产品详情
  219. goGoodsDetail(id) {
  220. uni.navigateTo({
  221. url: `/pages/goods/goods-detail/index?id=${id}&type=1`
  222. })
  223. },
  224. // 搜索防抖
  225. searchText: util.debounce(function(index, id) {
  226. this.goSearch(index, id)
  227. }, 1000),
  228. //搜索
  229. goSearch(index, id) {
  230. uni.showLoading({
  231. title: '加载中'
  232. })
  233. this.$api.product.getProducts({
  234. type: 1,
  235. page: 0,
  236. name: this.search,
  237. category_id: id
  238. }).then(res => {
  239. if (res.code == 0) {
  240. uni.hideLoading()
  241. this.isActive = index
  242. this.goodsList = res.data.data
  243. this.totalElements = res.data.total
  244. this.pagesize = res.data.per_page
  245. }
  246. })
  247. },
  248. }
  249. }
  250. </script>
  251. <style lang="scss" scoped>
  252. .goods {
  253. height: 100%;
  254. }
  255. .tab_nav {
  256. width: 100%;
  257. height: 100rpx;
  258. display: flex;
  259. align-items: center;
  260. font-family: PingFang-SC-Heavy, PingFang-SC;
  261. overflow-x: scroll;
  262. }
  263. .msg-null {
  264. display: flex;
  265. flex-direction: column;
  266. align-items: center;
  267. justify-content: center;
  268. .msg-null-text {
  269. margin-top: 40rpx;
  270. font-size: 28rpx;
  271. color: #333;
  272. }
  273. }
  274. .scroll-y {
  275. // height: 100vh;
  276. }
  277. .content {
  278. background-color: #FFF;
  279. padding: 10rpx 30rpx 0rpx;
  280. .home-hotel-img-content {
  281. display: flex;
  282. align-items: flex-start;
  283. justify-content: space-between;
  284. flex-wrap: wrap;
  285. .home-hotel-img-content-item {
  286. width: 332rpx;
  287. background: #FFFFFF;
  288. box-shadow: 0px 4rpx 8rpx 0px rgba(0, 0, 0, 0.04);
  289. border-radius: 12rpx;
  290. margin-bottom: 26rpx;
  291. overflow: hidden;
  292. .home-hotel-img-content-item-img {
  293. width: 332rpx;
  294. height: 332rpx;
  295. object-fit: cover;
  296. object-position: center;
  297. }
  298. .home-hotel-img-content-item-img-long {
  299. width: 332rpx;
  300. height: 400rpx;
  301. object-fit: cover;
  302. object-position: center;
  303. }
  304. .text {
  305. display: flex;
  306. flex-direction: column;
  307. align-items: flex-start;
  308. justify-content: center;
  309. padding: 18rpx 22rpx 32rpx;
  310. .text-top {
  311. font-size: 28rpx;
  312. font-weight: bold;
  313. color: #333;
  314. }
  315. .text-main {
  316. margin-top: 20rpx;
  317. font-size: 24rpx;
  318. color: #999999;
  319. }
  320. }
  321. }
  322. }
  323. }
  324. .return-btn {
  325. position: fixed;
  326. bottom: 140rpx;
  327. right: 14rpx;
  328. }
  329. .home-bottom {
  330. background-color: #FFF;
  331. padding-bottom: 84rpx;
  332. }
  333. .tab_nav .navTitle {
  334. width: 154rpx;
  335. flex: none;
  336. height: 28rpx;
  337. font-size: 32rpx;
  338. color: #666;
  339. position: relative;
  340. display: flex;
  341. align-items: center;
  342. justify-content: center;
  343. margin-right: 16rpx;
  344. }
  345. .navTitle-item {
  346. width: 154rpx;
  347. flex: none;
  348. height: 28rpx;
  349. font-size: 32rpx;
  350. color: #666;
  351. position: relative;
  352. display: flex;
  353. align-items: center;
  354. justify-content: center;
  355. }
  356. .active {
  357. color: #D9A94D;
  358. font-weight: bold;
  359. &::after {
  360. display: inline-block;
  361. content: '';
  362. width: 48rpx;
  363. height: 12rpx;
  364. background: linear-gradient(90deg, #F3D69F 0%, #D9A94D 100%);
  365. border-radius: 6px;
  366. position: absolute;
  367. bottom: -26rpx;
  368. left: 51rpx;
  369. }
  370. }
  371. .search {
  372. ::v-deep .u-input {
  373. width: 690rpx !important;
  374. height: 68rpx !important;
  375. background: #F1F1F1;
  376. border-radius: 74rpx;
  377. }
  378. ::v-deep .u-input__content__field-wrapper {
  379. padding-left: 36rpx;
  380. }
  381. ::v-deep .u-input__content__field-wrapper__field {
  382. color: #999999 !important;
  383. font-size: 28rpx !important;
  384. }
  385. }
  386. .goods-img {
  387. width: 100%;
  388. height: 82vw;
  389. }
  390. .main {
  391. position: relative;
  392. top: -36rpx;
  393. padding: 48rpx 30rpx 0;
  394. border-radius: 16rpx 16rpx 0px 0px;
  395. height: 238rpx;
  396. background: #FFFFFF;
  397. box-shadow: 0px 4rpx 8rpx 0px rgba(0, 0, 0, 0.04);
  398. }
  399. </style>