list2.vue 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666
  1. <template>
  2. <view class="container">
  3. <navbar :config="config" backColor="#666666"></navbar>
  4. <view class="topsearch u-p30 u-flex-center-sb" @click="gosearch()">
  5. <view class="u-flex1 u-flex-center leftbox">
  6. <text class="iconfont u-font30 u-666 u-ml30">&#xe7a6;</text>
  7. <text class="u-font22 u-CCC u-ml20">请输入搜索关键字</text>
  8. </view>
  9. <text class="u-font28 u-1A1A1A u-ml30">搜索</text>
  10. </view>
  11. <view class="goodsbox" @touchmove.stop.prevent="moveHandle">
  12. <scroll-view scroll-y="true" class="leftList">
  13. <view class="row u-font28 u-666 u-text1" v-for="(item, index) in categoryList" :key="item.id"
  14. :class="[index === showCategoryIndex ? 'on' : '']" @click="showCategory(index,item.id)">
  15. {{item.name}}
  16. </view>
  17. </scroll-view>
  18. <view class="rightlist">
  19. <view class="secoundList u-flex-center u-border-one-one" v-if="categoryTwo.length>0">
  20. <scroll-view scroll-x="true" class="list-cell ">
  21. <view class="sList u-mr45" v-for="(item, index) in categoryTwo" :key="item.id"
  22. @click="twoChildren(index,item.id)" :class="[index == twoIndex ? 'on' : '']">{{item.name}}
  23. </view>
  24. </scroll-view>
  25. <!-- <view class="rightIcons" @click="openCaseList">
  26. <text class="iconfont u-font30 u-181818 tes ">&#xe6c7;</text>
  27. </view> -->
  28. </view>
  29. <!-- <view class="showHidden" v-if="showHidden">
  30. <view class="contCase">
  31. <view class="u-flex-warp u-flex-center">
  32. <view class="caseitem u-font24 u-999 active">面霜</view>
  33. <view class="caseitem u-font24 u-999">面霜</view>
  34. <view class="caseitem u-font24 u-999">面霜</view>
  35. <view class="caseitem u-font24 u-999">面霜</view>
  36. <view class="caseitem u-font24 u-999">面霜</view>
  37. </view>
  38. </view>
  39. </view> -->
  40. <scroll-view scroll-y="true" class="Listbox" :class="{'Listbox-one':categoryTwo.length==0}" refresher-enabled="true" :refresher-triggered="triggered" @refresherrefresh="onRefresh" @scrolltolower="tolower">
  41. <view class="u-plr30">
  42. <view class="itemList u-flex-center-sb u-border-one-one" v-for="(item) in goodsList"
  43. :key="item.id">
  44. <image class="u-goods160" :src="item.cover" mode="" @click="goProductDetails(item.id)">
  45. </image>
  46. <view class="u-flex-column-start u-ml30 u-flex1" @click="goProductDetails(item.id)">
  47. <view class="u-text2">{{item.title}}</view>
  48. <view class="u-font32 u-bold u-flex-center-sb viewWidth u-FF0000 u-mt10">
  49. <rich-text :nodes="$mUtil.priceBigSmall(item.min_sale_price)"></rich-text>
  50. </view>
  51. </view>
  52. <view @click="addCart(item.id,item.shop_id)" class="addShopCard bgc iconfont">&#xe73d;
  53. </view>
  54. </view>
  55. <nodata v-if="noData" :config="{top:15,content:'暂无商品~'}"></nodata>
  56. <loadMore v-if="goodsList.length>0" :status="status"></loadMore>
  57. </view>
  58. </scroll-view>
  59. </view>
  60. </view>
  61. <!--规格-->
  62. <uniPopup type="bottom" ref="specOpen">
  63. <view class="u-bg-fff spec">
  64. <view class="u-plr30 flex-sb u-border-one-one pb30">
  65. <view class="u-flex-center">
  66. <image class="u-goods200" :src="choseConfig.cover?choseConfig.cover:cover"></image>
  67. <view class="u-ml20">
  68. <view class="u-999 u-font24 u-flex-center">
  69. <view class="u-FF0000 u-font36">
  70. <rich-text
  71. :nodes="$mUtil.priceBigSmall(choseConfig.sale_price?choseConfig.sale_price:moPrice)">
  72. </rich-text>
  73. </view>
  74. <text
  75. class="u-del u-ml15">¥{{choseConfig.market_price?choseConfig.market_price:moDelPrice}}
  76. </text>
  77. <!-- <text class="u-ml10">7.5折</text> -->
  78. </view>
  79. <view class="u-font22 u-999 u-mt5">库存 {{stock}} 件</view>
  80. <view class="u-1A1A1A u-mt25">{{choseConfig.sku_set_name?choseConfig.sku_set_name:'请选择'}}
  81. </view>
  82. </view>
  83. </view>
  84. <view class="iconfont u-999 closeIcon" @click="specOpenClose">&#xe603;</view>
  85. </view>
  86. <view>
  87. <view class="overHeight">
  88. <view class="u-mt30" v-for="(item,index) in skuTab" :key="item.head.id">
  89. <view class="u-plr30">{{item.head.name}}</view>
  90. <view class="u-mt20 u-border-one-one pb30">
  91. <view class="u-plr30 u-flex u-flex-warp">
  92. <view class="spec-item " :class="childrenItem.flag?'activeColor':''"
  93. @click="chonseSku(index,childrenItem.id)" v-for="childrenItem in item.values"
  94. :key="childrenItem.id">{{childrenItem.name}}</view>
  95. </view>
  96. </view>
  97. </view>
  98. </view>
  99. <view class="u-plr30 u-mt30">
  100. <view class="u-flex-center-sb">
  101. <view>购买数量</view>
  102. <view class="u-flex-center">
  103. <view class="iconfont minus" @click="resNum">&#xe60b;</view>
  104. <view class="num">{{add_num}}</view>
  105. <view class="iconfont plus-sign " @click="addNum">&#xe81a;</view>
  106. </view>
  107. </view>
  108. <view class="specOpen-btn">
  109. <view>
  110. <button class="u-btn-two" @click="btnBuy()">加入购物车</button>
  111. </view>
  112. </view>
  113. </view>
  114. </view>
  115. </view>
  116. </uniPopup>
  117. <!--页面加载动画-->
  118. <ldLoading isFullScreen :active="loading"></ldLoading>
  119. </view>
  120. </template>
  121. <script>
  122. import uniPopup from "../../components/uni-popup/uni-popup.vue"
  123. export default {
  124. components: {
  125. uniPopup
  126. },
  127. data() {
  128. return {
  129. showHidden: false,
  130. twoIndex: null,
  131. price: 100,
  132. categoryTwo: [],
  133. goodsList: [],
  134. showCategoryIndex: 0,
  135. categoryList: [
  136. ],
  137. config: {
  138. back: false, //false是tolbar页面 是则不写
  139. title: '商品分类',
  140. color: '#1a1a1a',
  141. //背景颜色;参数一:透明度(0-1);参数二:背景颜色(array则为线性渐变,string为单色背景)
  142. backgroundColor: [1, "#fff"],
  143. statusBarFontColor: '#ffffff'
  144. },
  145. loading: true,
  146. checkId: null,
  147. status: 'more', //more|loading|noMore
  148. triggered: false,
  149. skuTab: [], //sku二位数组
  150. goodsSkuList: [], //sku组合值
  151. choseConfig: {},
  152. moPrice: '',
  153. moDelPrice: '',
  154. noData: false,
  155. cover: '',
  156. add_num: 1,
  157. hasId: '',
  158. stock: 0,
  159. goods_id: null,
  160. limit_buy_num: 0,
  161. shopid: '',
  162. params: {
  163. category_id: null,
  164. limit: 10,
  165. page: 1
  166. }
  167. }
  168. },
  169. onShow() {
  170. this.showCategoryIndex = 0
  171. this.rest()
  172. this.getAllNav()
  173. },
  174. onPullDownRefresh() {
  175. this.rest()
  176. this.getShopList()
  177. uni.stopPullDownRefresh()
  178. },
  179. onReachBottom() {
  180. this.status = 'loading'
  181. this.params.page++
  182. this.getShopList()
  183. },
  184. methods: {
  185. goProductDetails(id) {
  186. uni.navigateTo({
  187. url: "../product/goods/goods?id=" + id
  188. })
  189. },
  190. // 减数量
  191. resNum() {
  192. if (this.add_num > 1) {
  193. this.add_num--
  194. }
  195. },
  196. //加数量
  197. addNum() {
  198. this.add_num++
  199. },
  200. chonseSku(index, id) {
  201. this.skuTab[index].values.forEach(res => {
  202. res.flag = false
  203. if (res.id == id) {
  204. res.flag = true
  205. }
  206. })
  207. let choseId = []
  208. this.skuTab.forEach(res => {
  209. res.values.forEach(Key => {
  210. if (Key.flag) {
  211. choseId.push(Key.id)
  212. }
  213. })
  214. })
  215. let totalId = choseId.join('|')
  216. this.hasId = totalId
  217. this.goodsSkuList.forEach(res => {
  218. if (res.sku_hash_code == totalId) {
  219. this.choseConfig = res
  220. this.stock = res.able_stock
  221. this.able_stock = res.able_stock
  222. }
  223. })
  224. },
  225. //加入购物车
  226. btnBuy() {
  227. let data = {
  228. goods_id: this.goods_id,
  229. sku_hash_code: this.hasId,
  230. add_num: this.add_num,
  231. source_shop_id: this.shopid
  232. }
  233. // 判断是否选中sku
  234. if (this.skuTab.length > 0 && this.hasId == "") {
  235. this.$mUtil.toast('请选中sku')
  236. return false
  237. }
  238. // 判断限购
  239. if (this.add_num > this.limit_buy_num && this.limit_buy_num != 0) {
  240. this.$mUtil.toast('商品限购' + this.limit_buy_num + '件')
  241. return false
  242. }
  243. //判断库存
  244. if (this.goodsSkuList.length > 0 && this.able_stock < this.add_num) {
  245. this.$mUtil.toast('商品库存只有' + this.able_stock + '件')
  246. return false
  247. }
  248. this.$http.post(`/cart/add`, data)
  249. .then(res => {
  250. if (res && res.code == 200) {
  251. this.$mUtil.toast('添加成功')
  252. this.$refs.specOpen.close()
  253. this.choseConfig = {}
  254. this.add_num = 1
  255. }
  256. })
  257. },
  258. addCart(id, shopid) {
  259. this.shopid = shopid
  260. if (id) {
  261. this.checkSku(id, shopid)
  262. }
  263. // if(flag){
  264. // this.$mUtil.toast('代理商品不能加入购物车')
  265. // }else{
  266. // //加入购物车
  267. // if(id){
  268. // this.checkSku(id)
  269. // }
  270. // }
  271. },
  272. //关闭规格弹窗
  273. specOpenClose() {
  274. this.choseConfig = {}
  275. this.add_num = 1
  276. this.$refs.specOpen.close()
  277. },
  278. rest() {
  279. this.noData = false
  280. this.params.page = 1
  281. this.goodsList = []
  282. },
  283. onRefresh(e) {
  284. this.triggered = true
  285. this.rest()
  286. this.getShopList()
  287. },
  288. //滚动
  289. tolower(e) {
  290. this.status = 'loading'
  291. this.params.page++
  292. this.getShopList()
  293. },
  294. //查询sku
  295. checkSku(id, shopid) {
  296. this.$http.get(`/goods/skus/${shopid}/${id}`)
  297. .then(res => {
  298. if (res && res.code == 200) {
  299. res.data.goods.sku_table.forEach(keys => {
  300. keys.values.forEach(val => {
  301. val.flag = false
  302. })
  303. })
  304. this.limit_buy_num = res.data.goods.limit_buy_num
  305. this.goods_id = res.data.goods.id
  306. this.skuTab = res.data.goods.sku_table
  307. this.goodsSkuList = res.data.goods_sku_list
  308. this.moPrice = res.data.goods.min_sale_price
  309. this.moDelPrice = res.data.goods.max_sale_price
  310. this.cover = res.data.goods.cover
  311. this.stock = res.data.total_stock
  312. if (res.data.goods.sku_table.length > 0) {
  313. if (res.data.goods_auth) {
  314. if (res.data.goods_auth.added) {
  315. this.$refs.specOpen.open()
  316. } else {
  317. this.$mUtil.toast('该商品已经下架')
  318. }
  319. } else {
  320. this.$mUtil.toast('没有经营权限')
  321. }
  322. } else {
  323. this.hasId = ''
  324. this.btnBuy()
  325. }
  326. }
  327. })
  328. },
  329. getShopList() {
  330. this.$http.get(`/goods/all/pages`, this.params)
  331. .then(res => {
  332. this.loading = false;
  333. this.triggered = false
  334. if (res && res.code == 200) {
  335. this.goodsList = this.goodsList.concat(res.page.list)
  336. if (this.goodsList.length == 0) {
  337. this.noData = true
  338. } else {
  339. this.noData = false
  340. }
  341. if (res.page.totalPage <= res.page.currPage) {
  342. this.status = 'noMore'
  343. } else {
  344. this.status = 'more'
  345. }
  346. }
  347. })
  348. },
  349. getAllNav() {
  350. let shop = uni.getStorageSync('shop')
  351. let shopid = shop.id ? shop.id : ''
  352. this.loading = false;
  353. this.$http.get(`/category/all`)
  354. .then(res => {
  355. if (res && res.code == 200) {
  356. this.categoryList = res.list
  357. this.params.category_id = res.list[0].id
  358. if (res.list.length > 0) {
  359. this.checkId = res.list[0].id
  360. }
  361. this.categoryTwo = res.list[0].children
  362. this.getShopList()
  363. }
  364. })
  365. },
  366. moveHandle() {},
  367. //搜索页
  368. gosearch() {
  369. uni.navigateTo({
  370. url: "../product/search/search?category_id=" + this.params.category_id
  371. })
  372. },
  373. // 二级分类切换显示
  374. twoChildren(index, id) {
  375. console.log(index)
  376. this.twoIndex = index
  377. this.params.category_id = id
  378. this.rest()
  379. this.getShopList()
  380. },
  381. // 分类切换显示
  382. showCategory(index, id) {
  383. this.showCategoryIndex = index
  384. this.twoIndex = null
  385. this.params.category_id = id
  386. this.categoryTwo = this.categoryList[index].children
  387. this.rest()
  388. this.getShopList()
  389. },
  390. }
  391. }
  392. </script>
  393. <style lang="scss">
  394. .leftbox {
  395. height: 60rpx;
  396. line-height: 60rpx;
  397. background-color: rgba($color: #E6E6E6, $alpha: .4);
  398. border-radius: 30rpx;
  399. }
  400. .addShopCard {
  401. position: absolute;
  402. width: 54rpx;
  403. height: 54rpx;
  404. border-radius: 50%;
  405. color: #fff;
  406. line-height: 54rpx;
  407. text-align: center;
  408. font-size: 32rpx;
  409. right: 0rpx;
  410. bottom: 30rpx;
  411. }
  412. .bgc {
  413. background-color: #0B844A;
  414. }
  415. .bga {
  416. background-color: #ccc;
  417. }
  418. .showHidden {
  419. position: absolute;
  420. bottom: 0;
  421. top: 92rpx;
  422. width: 570rpx;
  423. z-index: 2;
  424. background-color: rgba($color: #000000, $alpha: .5);
  425. .contCase {
  426. background-color: #fff;
  427. padding: 30rpx 0 30rpx 30rpx;
  428. .caseitem {
  429. background-color: #F5F5F5;
  430. border-radius: 46rpx;
  431. width: 145rpx;
  432. height: 68rpx;
  433. line-height: 68rpx;
  434. text-align: center;
  435. margin-right: 30rpx;
  436. margin-bottom: 30rpx;
  437. box-sizing: border-box;
  438. }
  439. .caseitem.active {
  440. background: #abc5b5;
  441. border: 2rpx solid #284534;
  442. color: #0B844A;
  443. }
  444. }
  445. }
  446. .goodsbox {
  447. width: 100%;
  448. background-color: #fff;
  449. display: flex;
  450. .leftList {
  451. background-color: rgba($color: #E6E6E6, $alpha: .4);
  452. width: 180rpx;
  453. left: 0upx;
  454. .row {
  455. height: 132rpx;
  456. text-align: center;
  457. line-height: 132rpx;
  458. position: relative;
  459. padding: 0 20rpx;
  460. }
  461. .row.on {
  462. background-color: #fff;
  463. color: #1A1A1A;
  464. font-size: 30rpx;
  465. font-weight: bold;
  466. }
  467. .row.on:after {
  468. width: 6rpx;
  469. height: 40rpx;
  470. background-color: #0B844A;
  471. position: absolute;
  472. left: 0;
  473. top: 46rpx;
  474. content: '';
  475. }
  476. }
  477. .leftList,
  478. .rightlist {
  479. position: absolute;
  480. top: calc(200upx + var(--status-bar-height));
  481. /* #ifdef APP-PLUS */
  482. top: calc(200upx + var(--status-bar-height));
  483. /* #endif */
  484. bottom: 0upx;
  485. }
  486. .rightlist {
  487. right: 0rpx;
  488. width: 570rpx;
  489. .Listbox {
  490. position: absolute;
  491. top: 90rpx;
  492. bottom: 0upx;
  493. right: 0;
  494. .listcont {
  495. padding: 30rpx;
  496. }
  497. }
  498. .Listbox-one {
  499. position: absolute;
  500. top: 0rpx;
  501. }
  502. .itemList {
  503. margin-top: 40rpx;
  504. padding-bottom: 40rpx;
  505. position: relative;
  506. }
  507. .secoundList {
  508. width: 510rpx;
  509. left: 30rpx;
  510. position: relative;
  511. height: 90rpx;
  512. line-height: 90rpx;
  513. .list-cell {
  514. white-space: nowrap;
  515. }
  516. .sList {
  517. display: inline-block;
  518. }
  519. .sList.on {
  520. color: #0B844A;
  521. font-weight: bold;
  522. }
  523. .rightIcons {
  524. width: 45rpx;
  525. height: 90rpx;
  526. line-height: 90rpx;
  527. background-color: #fff;
  528. position: absolute;
  529. right: 0;
  530. text-align: right;
  531. top: 0rpx;
  532. .tes {
  533. display: block;
  534. transform: rotate(90deg);
  535. }
  536. }
  537. }
  538. }
  539. }
  540. //弹窗
  541. .spec {
  542. .pb30 {
  543. padding-bottom: 30rpx;
  544. }
  545. .closeIcon {
  546. position: absolute;
  547. right: 30rpx;
  548. top: 30rpx;
  549. }
  550. border-radius: 18rpx 18rpx 0rpx 0rpx;
  551. padding-top: 30rpx;
  552. max-height: 900rpx;
  553. overflow-y: auto;
  554. .spec-item {
  555. background-color: #F6F6F6;
  556. border: 1px solid #F6F6F6;
  557. padding: 12rpx 30rpx;
  558. font-size: 24rpx;
  559. color: #1A1A1A;
  560. border-radius: 4px;
  561. }
  562. .activeColor {
  563. background-color: #E1E6E3;
  564. border: 1px solid #01321D;
  565. color: #01321D;
  566. border-radius: 4px;
  567. }
  568. .spec-item:not(:last-child) {
  569. margin-right: 24rpx;
  570. }
  571. //减号
  572. .minus {
  573. width: 50rpx;
  574. height: 50rpx;
  575. line-height: 50rpx;
  576. text-align: center;
  577. background: #dedede;
  578. border-radius: 8rpx 0rpx 0rpx 8rpx;
  579. }
  580. .num {
  581. width: 74rpx;
  582. height: 46rpx;
  583. line-height: 46rpx;
  584. text-align: center;
  585. border: 1px solid #dedede;
  586. }
  587. //加号
  588. .plus-sign {
  589. width: 50rpx;
  590. height: 50rpx;
  591. line-height: 50rpx;
  592. text-align: center;
  593. background: #dedede;
  594. border-radius: 0rpx 8rpx 8rpx 0rpx;
  595. }
  596. .specOpen-btn {
  597. margin-top: 68rpx;
  598. padding-bottom: 34rpx;
  599. button {
  600. background-color: #0B844A;
  601. color: #FFFFFF;
  602. }
  603. }
  604. }
  605. </style>