index.vue 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625
  1. <template>
  2. <view class="core">
  3. <!-- nav -->
  4. <u-navbar leftIconSize="0" :placeholder="true" bgColor="#ffffff">
  5. <view class="u-nav-slot" slot="left">
  6. <view class="u-nav-slot__input flex">
  7. <u--input v-model="goodsTitle" placeholder="搜索商品" border="none" prefixIcon="search" prefixIconStyle="font-size: 22px;color: #909399" />
  8. <view class="u-nav-slot__input__btn" @click="toGoodsList()">搜索</view>
  9. </view>
  10. </view>
  11. </u-navbar>
  12. <!-- 固定顶部搜索、分类 -->
  13. <view class="fixed-top">
  14. <view class="fixed-top-classify">
  15. <u-tabs @change="changeClassify" :scrollable="true" :list="classifyList" lineWidth="20" lineHeight="2"
  16. lineColor="#FF8D0B" :activeStyle="{
  17. color: '#333',
  18. transform: 'scale(1.1)'
  19. }" :inactiveStyle="{
  20. color: '#999',
  21. transform: 'scale(1.1)'
  22. }" itemStyle="padding-left: 15px; padding-right: 15px; height: 44px; text-align: center;">
  23. </u-tabs>
  24. </view>
  25. </view>
  26. <view class="core-none"></view>
  27. <!-- 轮播 -->
  28. <view class="core-swiper">
  29. <swiper class="core-swiper-centent" circular :indicator-dots="true" :autoplay="true" :interval="3000" indicator-active-color="#fff">
  30. <swiper-item class="swiper-item" v-for="(item, index) in swiperList" :key="index" @click="toPage(item)">
  31. <image :src="item.picUrl" mode=""></image>
  32. </swiper-item>
  33. </swiper>
  34. </view>
  35. <!-- 二级分类 -->
  36. <view class="core-category">
  37. <swiper class="core-category-swiper" :autoplay="false">
  38. <swiper-item class="swiper-item" v-for="(item, index) in classifyIndex == 0 ? classifyListFilter : classifyList[classifyIndex].list" :key="index">
  39. <view class="swiper-item__content" v-for="(items, indexs) in item" :key="indexs" @click="toTagGoods(items)">
  40. <image :src="items.picUrl" mode="aspectFit"></image>
  41. <view class="name">{{ items.name }}</view>
  42. </view>
  43. </swiper-item>
  44. </swiper>
  45. </view>
  46. <!-- 标签商品 -->
  47. <view class="tag-goods" v-for="(item, index) in exclusiveSingle" :key="index">
  48. <image class="tag-goods-imgBg" src="../../static/core/core_bg.png" mode=""></image>
  49. <view class="tag-goods-content">
  50. <view class="tag-goods-content-nav flex">
  51. <view class="tag-goods-content-nav__left flex">
  52. <image src="../../static/core/core_tag.png" mode=""></image>
  53. <view class="title">{{ item.name }}</view>
  54. <image src="../../static/core/core_tag.png" mode=""></image>
  55. </view>
  56. <view class="tag-goods-content-nav__right flex" @click="toTagGoods(item)">
  57. <view class="title">更多</view>
  58. <image src="../../static/core/core_right.png" mode=""></image>
  59. </view>
  60. </view>
  61. <view class="tag-goods-content-list">
  62. <view class="tag-goods-content-list-item flex" v-for="(items, indexs) in item.data" :key="indexs" @click="toGoodsDetail(items)">
  63. <view class="image flex">
  64. <image :src="items.picUrl" mode="aspectFit"></image>
  65. </view>
  66. <view class="title">{{ items.exchangePrice }}盲豆</view>
  67. </view>
  68. </view>
  69. </view>
  70. </view>
  71. <!-- 商品列表 -->
  72. <view class="core-goods">
  73. <view class="core-goods-list flex">
  74. <view class="core-goods-list-item flex" v-for="(item, index) in list" :key="index" @click="toGoodsDetail(item)">
  75. <view class="image-wrap flex">
  76. <image :src="item.picUrl" mode="aspectFit"></image>
  77. </view>
  78. <view class="content">
  79. <view class="content-title ells-one">{{ item.title }}</view>
  80. <view class="content-coin flex">
  81. <view class="content-coin__left flex">
  82. <image src="../../static/public/goods_coin.png" mode=""></image>
  83. <view class="num">×{{ item.exchangePrice }}</view>
  84. </view>
  85. <view class="content-coin__right" v-if="item.originPrice">原价:{{ item.originPrice }}</view>
  86. </view>
  87. <view class="content-price">¥{{ $numberFormat(item.value) }}</view>
  88. </view>
  89. </view>
  90. <view class="core-goods-list-item"></view>
  91. </view>
  92. </view>
  93. <custom-tab-bar :activeValue="'core'" />
  94. </view>
  95. </template>
  96. <script>
  97. import env from '../../config/env.js'
  98. import $http from '@/utils/request.js'
  99. import CustomTabBar from '../../components/custom-tab-bar/custom-tab-bar.vue'
  100. export default {
  101. components: {
  102. CustomTabBar,
  103. },
  104. data() {
  105. return {
  106. imgTop: [],
  107. goods: [],
  108. exclusive: [],
  109. exclusiveSingle: [],
  110. pageNum: 1,
  111. total: 0,
  112. list: [],
  113. /////////
  114. classifyList: [], // 分类列表
  115. classifyIndex: 0, // 分类选中下标
  116. classifyListFilter: [],
  117. swiperList: [], // 轮播图
  118. goodsTitle: '',
  119. };
  120. },
  121. onLoad() {
  122. this.pageList()
  123. this.getExclusive()
  124. this.getClassify()
  125. this.getSwiper()
  126. },
  127. methods: {
  128. pageList() {
  129. this.pageNum = 1
  130. this.total = 0
  131. this.list = []
  132. this.getList()
  133. },
  134. // 获取分类
  135. getClassify() {
  136. $http.post('/api/v1/mp/user/exchange/category/listTree', {}).then(res => {
  137. if(res.code == 0){
  138. let interval = 10
  139. this.classifyList = res && res.rows
  140. this.classifyList.forEach(item => {
  141. item.picUrl = env.filePublic + item.picUrl.split(',')[0] + '?imageView2/2/w/340'
  142. item.goodsCategoryList.forEach(ele => {
  143. ele.picUrl = env.filePublic + ele.picUrl.split(',')[0] + '?imageView2/2/w/340'
  144. })
  145. item.list = []
  146. if(item.goodsCategoryList.length > interval) {
  147. let num = Math.ceil(item.goodsCategoryList.length / interval)
  148. let arr = []
  149. let a = 0
  150. let stop = interval
  151. for(let i = 1; i <= num; i++) {
  152. arr = item.goodsCategoryList.slice(a, stop)
  153. a = i * interval
  154. stop = stop + interval
  155. }
  156. } else {
  157. item.list.push(item.goodsCategoryList)
  158. }
  159. })
  160. if(this.classifyList.length > interval) {
  161. let num = Math.ceil(this.classifyList.length / interval)
  162. let arr = []
  163. let a = 0
  164. let stop = interval
  165. for(let i = 1; i <= num; i++) {
  166. arr = this.classifyList.slice(a, stop)
  167. a = i * interval
  168. stop = stop + interval
  169. this.classifyListFilter.push(arr)
  170. }
  171. } else {
  172. this.classifyListFilter =[ [ ...this.classifyList ] ]
  173. }
  174. this.classifyList.unshift({ name: '全部' })
  175. }
  176. })
  177. },
  178. //轮播图
  179. getSwiper() {
  180. $http.post(`/api/v1/mp/user/exchange/banner/list`, {
  181. noToken: true,
  182. location: "top"
  183. }).then(res => {
  184. res.data.forEach(item => item.picUrl = env.filePublic + item.picUrl.split(',')[0])
  185. this.swiperList = res.data
  186. })
  187. },
  188. // 标签商品
  189. async getExclusive() {
  190. let resData = await $http.post(`/api/v1/mp/user/exchange/activity/list`, {
  191. noToken: true
  192. })
  193. let goodsList = []
  194. for (let item of resData.data) {
  195. let resDatas = await $http.post(`/api/v1/mp/user/exchange/goods/list?pageNum=1&pageSize=4`, {
  196. noToken: true,
  197. tagIds: item.tagId
  198. })
  199. goodsList.push({
  200. data: resDatas.rows,
  201. name: item.name,
  202. tagId: item.tagId
  203. })
  204. }
  205. goodsList.forEach(item => {
  206. item.data.forEach(items => {
  207. items.picUrl = env.filePublic + items.picUrl.split(',')[0] + '?imageView2/2/w/340'
  208. })
  209. })
  210. this.exclusiveSingle = goodsList
  211. },
  212. // 商品列表
  213. getList() {
  214. uni.showLoading({
  215. title: '加载中'
  216. });
  217. let data = {
  218. categoryId: this.categoryId,
  219. tagIds: this.tagIds,
  220. ...this.coinNum,
  221. noToken: true
  222. }
  223. $http.post(`/api/v1/mp/user/exchange/goods/list?pageNum=${this.pageNum}&pageSize=20`,data).then(
  224. res => {
  225. uni.hideLoading();
  226. if (res.code == 0) {
  227. res.rows.forEach(item => {
  228. let picUrlArr = item.picUrl.split(',')
  229. item.picUrl = env.filePublic + picUrlArr[0] + '?imageView2/2/w/340'
  230. })
  231. this.total = res.total
  232. this.list = this.list.concat(res.rows)
  233. }
  234. }).catch(() => {
  235. uni.hideLoading();
  236. })
  237. },
  238. // 切换分类
  239. changeClassify(e) {
  240. this.classifyIndex = e.index
  241. },
  242. // 跳转点击事件
  243. toPage(item) {
  244. if (item.type == "link") {
  245. uni.navigateTo({
  246. url: `/packageOperate/webview/index?url=${ item.linkUrl }`,
  247. })
  248. } else if (item.type == "tag") {
  249. uni.navigateTo({
  250. url: `/packageGoods/goods/list?name=${ item.name }&tagIds=${ item.goodsTags ? item.goodsTags : '' }`
  251. })
  252. }
  253. },
  254. // 商品详情
  255. toGoodsDetail(item) {
  256. uni.navigateTo({
  257. url: `/packageGoods/goods/detail?id=${ item.goodsId }`
  258. })
  259. },
  260. // 商品列表
  261. toGoodsList() {
  262. uni.navigateTo({
  263. url: `/packageGoods/goods/list?title=${ this.goodsTitle }`
  264. })
  265. },
  266. // 商品标签
  267. toTagGoods(item) {
  268. uni.navigateTo({
  269. url: `/packageGoods/goods/list?name=${ item.name }&tagIds=${ item.tagId ? item.tagId : '' }&categoryId=${ item.categoryId ? item.categoryId : '' }`
  270. })
  271. },
  272. },
  273. onReachBottom() {
  274. // 判断是否有数据
  275. if (this.total > this.pageNum * 20) {
  276. setTimeout(() => {
  277. ++this.pageNum
  278. this.getList()
  279. }, 500)
  280. } else {
  281. uni.$u.toast('已经到底了')
  282. }
  283. },
  284. onShareAppMessage(res) {
  285. return {
  286. title: '盲票,玩的就是有趣',
  287. path: '/pages/index/index',
  288. // imageUrl:'../../static/icon/lucky_bg.png',
  289. }
  290. }
  291. }
  292. </script>
  293. <style lang="scss" scoped>
  294. .core {
  295. background-color: #fff;
  296. &-none {
  297. height: 100rpx;
  298. }
  299. }
  300. // 搜索
  301. .u-nav-slot {
  302. text {
  303. font-size: 32rpx;
  304. }
  305. &__input {
  306. position: relative;
  307. height: 70rpx;
  308. width: 518rpx;
  309. padding-left: 30rpx;
  310. background: #F4F5F6;
  311. border-radius: 35rpx;
  312. &__btn {
  313. z-index: 200;
  314. width: 140rpx;
  315. height: 70rpx;
  316. line-height: 70rpx;
  317. font-size: 30rpx;
  318. text-align: center;
  319. font-weight: bold;
  320. color: #fff;
  321. background-color: #FF8D0B;
  322. border-radius: 35rpx;
  323. }
  324. }
  325. }
  326. // 固定搜索、分类
  327. .fixed-top {
  328. position: fixed;
  329. z-index: 100;
  330. width: 100%;
  331. background-color: #fff;
  332. // 搜索
  333. &-search {
  334. justify-content: space-between;
  335. padding: 14rpx 30rpx 34rpx;
  336. &__input {
  337. position: relative;
  338. flex: 1;
  339. height: 84rpx;
  340. padding-left: 46rpx;
  341. background: #F4F5F6;
  342. border-radius: 20rpx;
  343. &__btn {
  344. position: absolute;
  345. right: 0;
  346. width: 110rpx;
  347. height: 76rpx;
  348. line-height: 76rpx;
  349. font-size: 34rpx;
  350. text-align: center;
  351. font-weight: bold;
  352. color: #FFC062;
  353. background-color: #333333;
  354. border-radius: 18rpx;
  355. }
  356. }
  357. image {
  358. width: 52rpx;
  359. height: 52rpx;
  360. margin-left: 50rpx;
  361. }
  362. }
  363. // 分类
  364. &-classify {
  365. padding-bottom: 20rpx;
  366. }
  367. }
  368. // 轮播
  369. .core-swiper {
  370. margin-bottom: 20rpx;
  371. &-centent {
  372. height: 330rpx;
  373. .swiper-item {
  374. width: 100%;
  375. height: 100%;
  376. image {
  377. width: 100%;
  378. height: 100%;
  379. }
  380. }
  381. }
  382. }
  383. // 二级分类
  384. .core-category {
  385. width: 100%;
  386. height: 360rpx;
  387. margin-bottom: 34rpx;
  388. &-swiper {
  389. width: 100%;
  390. height: 100%;
  391. .swiper-item {
  392. width: 100%;
  393. height: 100%;
  394. display: flex;
  395. flex-wrap: wrap;
  396. &__content {
  397. display: flex;
  398. align-items: center;
  399. flex-direction: column;
  400. justify-content: space-between;
  401. width: 20%;
  402. height: 50%;
  403. image {
  404. width: 90%;
  405. height: 70%;
  406. }
  407. }
  408. }
  409. }
  410. }
  411. // 标签商品
  412. .tag-goods {
  413. display: flex;
  414. align-items: center;
  415. position: relative;
  416. margin-bottom: 34rpx;
  417. height: 400rpx;
  418. &-imgBg {
  419. position: absolute;
  420. top: 0;
  421. width: 100vw;
  422. height: 400rpx;
  423. }
  424. &-content {
  425. width: 100vw;
  426. position: absolute;
  427. top: 0;
  428. z-index: 5;
  429. padding: 26rpx 32rpx;
  430. &-nav {
  431. justify-content: space-between;
  432. height: 40rpx;
  433. margin-bottom: 34rpx;
  434. &__left {
  435. image {
  436. width: 40rpx;
  437. height: 30rpx;
  438. }
  439. .title {
  440. font-family: YouSheBiaoTiHei;
  441. font-weight: 400;
  442. font-size: 40rpx;
  443. color: #FFFFFF;
  444. padding: 0 36rpx;
  445. }
  446. }
  447. &__right {
  448. .title {
  449. font-family: YouSheBiaoTiHei;
  450. font-weight: 400;
  451. color: #FFFFFF;
  452. margin-right: 12rpx;
  453. }
  454. image {
  455. width: 22rpx;
  456. height: 20rpx;
  457. }
  458. }
  459. }
  460. &-list {
  461. display: flex;
  462. height: 260rpx;
  463. overflow-x: auto;
  464. &-item {
  465. flex-direction: column;
  466. margin-right: 14rpx;
  467. .image {
  468. width: 220rpx;
  469. height: 200rpx;
  470. background: #FFFFFF;
  471. box-shadow: 0px 0px 4px 0px rgba(100, 100, 100, 0.13);
  472. border-radius: 4rpx;
  473. margin-bottom: 24rpx;
  474. image {
  475. width: 100%;
  476. height: 100%;
  477. }
  478. }
  479. .title {
  480. text-align: center;
  481. line-height: 28rpx;
  482. color: #FFFFFF;
  483. }
  484. }
  485. }
  486. }
  487. }
  488. // 商品列表
  489. .core-goods {
  490. padding: 0 34rpx;
  491. &-list {
  492. width: 100%;
  493. justify-content: space-between;
  494. flex-wrap: wrap;
  495. &-item {
  496. flex-direction: column;
  497. justify-content: flex-start;
  498. width: 48%;
  499. padding-bottom: 36rpx;
  500. background: #FFFFFF;
  501. box-shadow: 0px 0px 3px 0px rgba(100, 100, 100, 0.1);
  502. border-radius: 16rpx;
  503. margin-bottom: 30rpx;
  504. .image-wrap {
  505. width: 100%;
  506. height: 320rpx;
  507. margin-bottom: 18rpx;
  508. image {
  509. width: 100%;
  510. height: 100%;
  511. border-radius: 16rpx 16rpx 0 0;
  512. }
  513. }
  514. .content {
  515. width: 100%;
  516. padding: 0 22rpx;
  517. &-title {
  518. height: 28rpx;
  519. font-size: 28rpx;
  520. line-height: 28rpx;
  521. font-weight: bold;
  522. margin-bottom: 40rpx;
  523. }
  524. &-coin {
  525. height: 30rpx;
  526. font-size: 24rpx;
  527. justify-content: flex-start;
  528. margin-bottom: 34rpx;
  529. &__left {
  530. margin-right: 24rpx;
  531. image {
  532. width: 34rpx;
  533. height: 30rpx;
  534. }
  535. }
  536. &__right {
  537. color: #666666;
  538. text-decoration: line-through;
  539. }
  540. }
  541. &-price {
  542. font-size: 24rpx;
  543. color: #666666;
  544. }
  545. }
  546. }
  547. &-item:last-child {
  548. box-shadow: none;
  549. }
  550. }
  551. }
  552. </style>
  553. <style lang="scss" scoped>
  554. </style>