多租户商城-商户小程序端
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

1084 lines
32 KiB

2 years ago
2 years ago
2 years ago
  1. <template>
  2. <view class="content">
  3. <!-- 骨架屏 -->
  4. <u-skeleton
  5. el-color="#efefef"
  6. bg-color="#fff"
  7. :loading="loading && isFirstComeIn"
  8. :animation="true"
  9. ></u-skeleton>
  10. <global-loading />
  11. <!-- 购物车 -->
  12. <view class="u-skeleton">
  13. <view v-if="!isEmpty">
  14. <u-sticky bg-color="#fff">
  15. <view class="cart-bg u-skeleton-fillet">
  16. <view class="cart-num-box">
  17. <image
  18. class=" u-skeleton-fillet"
  19. src="https://wechat.hnthee.com/ceres-local-file/image/logo_wechat.png"
  20. ></image>
  21. <text
  22. class="btn-box "
  23. @click="showManage = !showManage"
  24. v-if="!showManage"
  25. >管理
  26. </text>
  27. <text
  28. class="btn-box"
  29. @click="showManage = !showManage"
  30. v-if="showManage"
  31. >完成
  32. </text>
  33. </view>
  34. <view>
  35. <text class="num-box u-skeleton-fillet">
  36. <text class="num">{{ settleAccountsObj.allNum }}</text>
  37. 件宝贝
  38. </text>
  39. </view>
  40. </view>
  41. </u-sticky>
  42. <view class="cart-list-box">
  43. <view
  44. class="itemBox"
  45. v-for="(item, index) in dataList"
  46. :key="item.shopId"
  47. >
  48. <view
  49. class="item"
  50. v-if="item.skus.length >0"
  51. >
  52. <view class="shop-box">
  53. <image
  54. mode="aspectFill u-skeleton-fillet"
  55. v-if="item.selected === 1"
  56. src="https://ceres.zkthink.com/static/images/selectActive.png"
  57. class="cart-select-img"
  58. @click.stop="handleSelectShop(index,0)"
  59. ></image>
  60. <image
  61. mode="aspectFill u-skeleton-fillet"
  62. v-else
  63. src="https://ceres.zkthink.com/static/images/selectEmpty.png"
  64. class="cart-select-img"
  65. @click.stop="handleSelectShop(index,1)"
  66. ></image>
  67. <view
  68. class="shop-name-box u-skeleton-fillet"
  69. @click="$jump(`${jumpObj.store}?storeId=${item.shopId}`)"
  70. >
  71. <image
  72. src="https://ceres.zkthink.com/static/images/orderStoreIcon.png"
  73. class="shop-img"
  74. ></image>
  75. <text class="shop-name">{{ item.shopName }}</text>
  76. <image
  77. src="https://ceres.zkthink.com/static/images/arrowRight.png"
  78. class="arrow-right-img"
  79. ></image>
  80. </view>
  81. </view>
  82. <view
  83. class="rulesBox flex-items"
  84. v-if="item.currentRules && item.currentRules.number"
  85. >
  86. <image
  87. class="mar-right-20"
  88. src="https://ceres.zkthink.com/static/images/zuheIcon.png"
  89. ></image>
  90. <view class="fs24 font-color-C83732">
  91. 已满足{{ item.currentRules.price }}元任选{{ item.currentRules.number }}
  92. </view>
  93. </view>
  94. <view
  95. v-for="(skuItem, cIndex) in dataList[index].skus"
  96. class="product-list-box "
  97. >
  98. <view
  99. class="pro-item"
  100. @click="$jump(`${jumpObj.detail}?shopId=${item.shopId}&productId=${skuItem.productId}&skuId=${skuItem.skuId}`)"
  101. >
  102. <image
  103. mode="aspectFill u-skeleton-fillet"
  104. v-if="skuItem.selected == 1"
  105. src="https://ceres.zkthink.com/static/images/selectActive.png"
  106. @click.stop="handleSelectSku(index,cIndex,0)"
  107. class="cart-select-img"
  108. ></image>
  109. <image
  110. mode="aspectFill u-skeleton-fillet"
  111. v-else
  112. src="https://ceres.zkthink.com/static/images/selectEmpty.png"
  113. @click.stop="handleSelectSku(index,cIndex,1)"
  114. class="cart-select-img"
  115. ></image>
  116. <view class="pro-r">
  117. <image
  118. :src="skuItem.image"
  119. onerror="this.src='url(https://ceres.zkthink.com/static/root/default.png) no-repeat center';this.οnerrοr=null"
  120. class="pro-img default-img u-skeleton-fillet"
  121. ></image>
  122. <view class="pro-r-r u-skeleton-fillet">
  123. <view class="pro-name">{{ skuItem.productName }}</view>
  124. <view class="sku-box">
  125. <text v-if="skuItem.value">{{ skuItem.value }}</text>
  126. <text v-else>默认规格</text>
  127. <!-- <text></text> -->
  128. </view>
  129. <view class="pro-price-num-box">
  130. <view class="pro-price-box">
  131. <text class="fuhao"></text>
  132. <text>{{ skuItem.price }}</text>
  133. </view>
  134. <view class="pro-num-box">
  135. <text
  136. class="num-btn r"
  137. @click.stop="handleSubSkuNumber(index,cIndex)"
  138. >-
  139. </text>
  140. <text class="num">{{ skuItem.number }}</text>
  141. <text
  142. class="num-btn l"
  143. @click.stop="handleAddSkuNumber(index,cIndex)"
  144. >+
  145. </text>
  146. </view>
  147. </view>
  148. </view>
  149. </view>
  150. </view>
  151. </view>
  152. </view>
  153. </view>
  154. </view>
  155. <!-- #ifdef H5 -->
  156. <view class="cart-bottom-box-h5">
  157. <!-- #endif -->
  158. <!-- #ifndef H5 -->
  159. <view class="cart-bottom-box-app">
  160. <!-- #endif -->
  161. <view class="cart-bottom">
  162. <view class="left">
  163. <image
  164. mode="aspectFill"
  165. v-if="settleAccountsObj.isAllCheck"
  166. src="https://ceres.zkthink.com/static/images/selectActive.png"
  167. class="cart-select-img"
  168. @click="handleSelectAll(0)"
  169. ></image>
  170. <image
  171. mode="aspectFill"
  172. v-else
  173. src="https://ceres.zkthink.com/static/images/selectEmpty.png"
  174. class="cart-select-img"
  175. @click="handleSelectAll(1)"
  176. ></image>
  177. <text>全选</text>
  178. </view>
  179. <view
  180. class="right"
  181. v-if="!showManage"
  182. >
  183. <view class="price-box">
  184. <text>合计</text>
  185. <text class="price">¥{{ settleAccountsObj.checkMoney }}</text>
  186. </view>
  187. <view
  188. class="btn-confirm"
  189. @click="settlementTap"
  190. >结算{{ settleAccountsObj.checkNum }}
  191. </view>
  192. </view>
  193. <view
  194. class="right"
  195. v-if="showManage"
  196. >
  197. <view
  198. class="btn-delete"
  199. @click="handleOpenDelete"
  200. >删除
  201. </view>
  202. </view>
  203. </view>
  204. </view>
  205. </view>
  206. </view>
  207. <!-- 购物车为空 -->
  208. <view
  209. v-if="isEmpty"
  210. class="emptyCart-box flex-items-plus flex-column"
  211. >
  212. <image
  213. class="emptyCart-img"
  214. src="https://ceres.zkthink.com/static/images/cartEmpty.png"
  215. ></image>
  216. <label class="font-color-999 fs26 mar-top-30">你的购物车还没有宝贝哦</label>
  217. <label class="font-color-999 fs26 mar-top-10">快去首页选一个吧</label>
  218. <view
  219. class="goToShopping"
  220. @click="$jumpToTabbar(jumpObj.shopping)"
  221. >去购物
  222. </view>
  223. </view>
  224. <!-- 热门推荐 -->
  225. <HotTemplate class="u-skeleton-fillet"/>
  226. <view style="width: 100%;height: 120rpx;background-color:#fff;"></view>
  227. <!-- 删除确认弹窗 -->
  228. <DeleteModal
  229. :showTip.sync="showDeleteModal"
  230. @confirm="handleDoDelete"
  231. ></DeleteModal>
  232. </view>
  233. </view>
  234. </template>
  235. <script>
  236. import HotTemplate from '../../../components/hoteRecommed/index.vue'
  237. import DeleteModal from "./components/DeleteModal";
  238. import api from "../../../components/canvasShow/config/api";
  239. import { defaultCartList, getCartNumberBySelect, getPriceBySelect } from "./cartUtils";
  240. import lodash from 'lodash'
  241. let cacheKey = ''
  242. const NET = require('../../../utils/request')
  243. const API = require('../../../config/api')
  244. export default {
  245. components: {
  246. HotTemplate,
  247. DeleteModal
  248. },
  249. data() {
  250. return {
  251. isFirstComeIn:true, // 是否是首次进入
  252. loading: true, // 是否在加载
  253. showManage: false, // 是否开启管理
  254. dataList: [
  255. {skus: []}
  256. ], // 购物车数据
  257. showDeleteModal: false, // 是否展示删除
  258. isEmpty: false, // 购物车是否为空
  259. userInfo: {}, // 用户信息
  260. // 跳转对象
  261. jumpObj: {
  262. store: '/pages_category_page1/store/index',
  263. detail: '/pages_category_page1/goodsModule/goodsDetails',
  264. shopping: '/pages/tabbar/index/index'
  265. },
  266. // 底部结算条对象
  267. settleAccountsObj: {
  268. allNum: 0,// 所有sku数量(头部)
  269. checkNum: 0, // 选中sku的数量
  270. checkMoney: 0, // 选中sku的总价
  271. isAllCheck: false, // 是否宣布选中
  272. }
  273. }
  274. },
  275. onShow() {
  276. this.isFirstComeIn = true
  277. this.loading = true
  278. this.userInfo = uni.getStorageSync('storage_key')
  279. cacheKey = this.userInfo.buyerUserId + "cart_info"
  280. this.dataList = defaultCartList
  281. this.isEmpty = false
  282. this.getDataList()
  283. },
  284. methods: {
  285. /**
  286. * 获取购物车列表
  287. */
  288. getDataList:lodash.debounce(async function () {
  289. this.isEmpty = false
  290. this.loading = true
  291. try {
  292. const res = await NET.request(API.ShoppingCart, {}, 'GET')
  293. this.dataList = res.data
  294. this.settleAccountsObj.allNum = this.dataList.length
  295. if (this.dataList.length === 0) {
  296. this.isEmpty = true
  297. uni.setStorageSync('allCartNum', 0)
  298. uni.removeTabBarBadge({
  299. index: 2
  300. })
  301. }
  302. // sku为空的山沟
  303. const emptySkuShopArray = []
  304. this.dataList.forEach((shopObj, shopIndex) => {
  305. shopObj['currentIds'] = []
  306. shopObj['priceNumber'] = 0
  307. shopObj['rules'] = []
  308. shopObj['currentRules'] = {}
  309. shopObj['ids'] = 0
  310. // 处理下架商品
  311. for (let i = shopObj.skus.length - 1; i >= 0; i--) {
  312. // shelveState是否上架
  313. if (shopObj.skus[i].shelveState === 0) {
  314. // 删掉下架商品
  315. // todo 失效商品
  316. shopObj.skus.splice(i, 1)
  317. continue
  318. }
  319. if (shopObj.skus[i].activityType === 6 && shopObj.skus[i].selected === 1) {
  320. shopObj.currentIds.push(shopObj.skus[i].priceId)
  321. shopObj.priceNumber += shopObj.skus[i].number
  322. }
  323. }
  324. for (let i = 0; i < shopObj.skus.length; i++) {
  325. if (shopObj.skus[i].activityType === 6) {
  326. shopObj.ids = shopObj.skus[i].priceId
  327. break
  328. }
  329. }
  330. // 根据店铺索引获取规则
  331. this.getData(shopObj).then(res => {
  332. shopObj.rules = res.data ? res.data[0].rules : {}
  333. this.handleSetGroupGood(shopIndex)
  334. })
  335. shopObj.skus.length === 0?emptySkuShopArray.push(shopObj):undefined
  336. })
  337. this.isEmpty = emptySkuShopArray.length >=this.dataList.length
  338. this.handleRenderCart()
  339. // 数据回来就直接关闭骨架屏
  340. this.loading = false
  341. this.isFirstComeIn = false
  342. await this.handleUpdateMoneyAndNum()
  343. } finally {
  344. uni.hideLoading()
  345. }
  346. },500),
  347. /**
  348. * 获取组合定价
  349. * @param item
  350. * @return {Promise<unknown>}
  351. */
  352. getData(item) {
  353. return new Promise(((resolve, reject) => {
  354. if (item.ids) {
  355. NET.request(api.getPrices, {
  356. shopId: item.shopId,
  357. ids: item.ids,
  358. page: 1,
  359. pageSize: 10
  360. }, 'GET').then(res => {
  361. resolve(res)
  362. }).catch(e => {
  363. reject(e)
  364. })
  365. } else {
  366. resolve([])
  367. }
  368. }))
  369. },
  370. /**
  371. * 单个SKU数量减
  372. * @param shopIndex 店铺索引
  373. * @param skuIndex index店铺下sku商品索引
  374. */
  375. async handleSubSkuNumber(shopIndex, skuIndex) {
  376. const selectSku = this.dataList[shopIndex].skus[skuIndex]
  377. if (selectSku.number <= 1) {
  378. return uni.showToast({
  379. title: '亲!至少一件哦!',
  380. icon: "none"
  381. })
  382. }
  383. --selectSku.number
  384. await this.handleUpdateCart(selectSku.skuId, selectSku.number)
  385. setTimeout(async ()=>{
  386. await this.getDataList()
  387. },500)
  388. },
  389. /**
  390. * 单个SKU数量加
  391. * @param shopIndex 店铺索引
  392. * @param skuIndex index店铺下sku商品索引
  393. */
  394. async handleAddSkuNumber(shopIndex, skuIndex) {
  395. const selectSku = this.dataList[shopIndex].skus[skuIndex]
  396. if (selectSku.number >= selectSku.stockNumber) {
  397. selectSku.number = selectSku.stockNumber
  398. return uni.showToast({
  399. title: '库存不足!',
  400. icon: 'none'
  401. })
  402. }
  403. if (selectSku.number < selectSku.stockNumber) {
  404. ++selectSku.number
  405. await this.handleUpdateCart(selectSku.skuId, selectSku.number)
  406. setTimeout(async ()=>{
  407. await this.getDataList()
  408. },500)
  409. }
  410. },
  411. /**
  412. * 更新总价和总数底部结算栏头部总数
  413. * @return {Promise<void>}
  414. */
  415. async handleUpdateMoneyAndNum() {
  416. const {allNumber, checkNumber, isAllCheck} = await getCartNumberBySelect(this.dataList)
  417. const {money} = await getPriceBySelect(this.dataList)
  418. this.settleAccountsObj.checkMoney = money
  419. this.settleAccountsObj.isAllCheck = isAllCheck
  420. this.settleAccountsObj.allNum = allNumber
  421. this.settleAccountsObj.checkNum = checkNumber
  422. },
  423. /**
  424. * 请求服务端更新购物车数量
  425. * @param skuId :需要更新的skuId
  426. * @param number: 数量
  427. */
  428. handleUpdateCart:lodash.debounce(async function(skuId, number) {
  429. // 重新算钱和数量
  430. await NET.request(API.UpdateNumberCart, {
  431. skuId: skuId,
  432. number: number
  433. }, 'POST')
  434. },500),
  435. /**
  436. * 选中店铺
  437. * @param shopIndex 店铺索引
  438. * @param type 0否1是
  439. */
  440. handleSelectShop(shopIndex, type) {
  441. const shopObj = this.dataList[shopIndex]
  442. const shopCarts = [{
  443. shopId: shopObj.shopId,
  444. skus: []
  445. }]
  446. shopObj.selected = type
  447. // 设置当前店铺下的所有sku
  448. shopObj.skus.forEach(skuObj => {
  449. skuObj.selected = type
  450. shopCarts[0].skus.push({
  451. skuId: skuObj.skuId,
  452. selected: skuObj.selected
  453. })
  454. })
  455. this.handleSetGroupGood(shopIndex)
  456. this.handleUpdateSelected(shopCarts)
  457. }
  458. ,
  459. /**
  460. * 商品单选
  461. * @param shopIndex 店铺索引dataList
  462. * @param skuIndex sku索引dataList[index].skus
  463. * @param type 是否选中 0否1是
  464. */
  465. handleSelectSku(shopIndex, skuIndex, type) {
  466. const shopObj = this.dataList[shopIndex]
  467. const skuObj = this.dataList[shopIndex].skus[skuIndex]
  468. skuObj.selected = type
  469. let shopCarts = [{
  470. shopId: shopObj.shopId,
  471. skus: [{
  472. skuId: skuObj.skuId,
  473. selected: skuObj.selected,
  474. }]
  475. }]
  476. if (type === 1) {
  477. // 过滤店铺内未选择的sku
  478. const noSelectSkuList = shopObj.skus.filter(sku => sku.selected === 0);
  479. if (noSelectSkuList.length >= 0) {
  480. shopObj.selected = 0
  481. } else {
  482. shopObj.selected = 1
  483. }
  484. } else {
  485. shopObj.selected = type
  486. }
  487. // 渲染组合商品
  488. this.handleSetGroupGood(shopIndex)
  489. this.handleUpdateSelected(shopCarts)
  490. }
  491. ,
  492. /**
  493. * 全选
  494. * @param type 是否选中 0否1是
  495. */
  496. handleSelectAll(type) {
  497. this.dataList.forEach((shopObj, shopIndex) => {
  498. // 组合支付商品数量
  499. const goodsOfJointNumber = shopObj.skus.reduce((prev, skuObj) => {
  500. skuObj.selected = type
  501. // 如果是组合支付
  502. if (skuObj.selected === 1 && skuObj.activityType === 6) {
  503. return prev + skuObj.number
  504. }
  505. }, 0)
  506. shopObj.selected = type
  507. shopObj.priceNumber = goodsOfJointNumber
  508. shopObj.currentRules = {}
  509. // 处理选中的组合商品
  510. if (type === 1) {
  511. this.handleSetGroupGood(shopIndex)
  512. }
  513. })
  514. this.handleUpdateSelected([])
  515. }
  516. ,
  517. /**
  518. * 处理组合商品(设置currentRules渲染横幅)
  519. * @param shopIndex
  520. */
  521. handleSetGroupGood(shopIndex) {
  522. const shopObj = this.dataList[shopIndex]
  523. shopObj.currentRules = {}
  524. shopObj.priceNumber = 0
  525. shopObj.skus.forEach((skuObj) => {
  526. if (skuObj.activityType === 6 && skuObj.selected === 1) {
  527. shopObj.priceNumber += skuObj.number
  528. }
  529. })
  530. const shopRules = this.dataList[shopIndex].rules
  531. for (let i = 0; i < shopRules.length; i++) {
  532. if (shopRules[i].number === shopObj.priceNumber) {
  533. shopObj.currentRules = shopRules[i]
  534. break
  535. } else if (shopRules[shopRules.length - 1].number < shopObj.priceNumber) {
  536. shopObj.currentRules = shopRules[shopRules.length - 1]
  537. break
  538. }
  539. }
  540. }
  541. ,
  542. /**
  543. * 更新缓存sku勾选和价格数量显示
  544. * @param shopCarts:{shopId:number,skus:{skuId:number,select:number}}[] 只有一个对象店铺全选传空数组
  545. */
  546. handleUpdateSelected(shopCarts) {
  547. this.handleSetCache(shopCarts)
  548. this.handleUpdateMoneyAndNum()
  549. }
  550. ,
  551. /**
  552. * 设置购物车本地缓存先存入本地缓存再调用handleRenderCart根据本地缓存渲染
  553. * @param shopCarts:{shopId:number,skus:{skuId:number,select:number}}[] 只有一个对象店铺全选传空数组
  554. */
  555. handleSetCache(shopCarts) {
  556. let cartInfo = uni.getStorageSync(cacheKey);
  557. if (cartInfo === '') {
  558. // 全选
  559. if (shopCarts.length <= 0) {
  560. // 全选直接缓存整个列表
  561. uni.setStorageSync(cacheKey, JSON.stringify(this.dataList))
  562. // 渲染视图
  563. this.handleRenderCart()
  564. return
  565. }
  566. // 无购物车信息
  567. cartInfo = shopCarts
  568. uni.setStorageSync(cacheKey, JSON.stringify(cartInfo))
  569. } else {
  570. cartInfo = JSON.parse(cartInfo)
  571. // 全选
  572. if (shopCarts.length <= 0) {
  573. // 全选直接缓存整个列表
  574. uni.setStorageSync(cacheKey, JSON.stringify(this.dataList))
  575. // 渲染视图
  576. this.handleRenderCart()
  577. return
  578. }
  579. // 看了代码逻辑结构,一次只会传一个商铺过来,大胆取0
  580. const shopItem = shopCarts[0]
  581. const cacheHaveInfo = cartInfo.findIndex(item => item.shopId === shopItem.shopId)
  582. if (cacheHaveInfo < 0) {
  583. // 如果缓存中不存在当前商店信息,写入缓存
  584. cartInfo.push(shopItem)
  585. } else {
  586. // 获取到缓存项
  587. const cacheShopItem = cartInfo[cacheHaveInfo]
  588. // 判断传入的sku大小,sku length为1就是点单项,sku length>1就是点击了整个店铺
  589. if (shopItem.skus.length > 1) {
  590. // 点击整个店铺,直接赋值
  591. cartInfo[cacheHaveInfo] = shopItem
  592. } else {
  593. // 点击单项sku,获取到sku // 数据结构只会传入一项
  594. const shopItemSkuItem = shopItem.skus[0];
  595. // 在缓存中寻找
  596. const cacheShopItemSkuItemIndex = cacheShopItem.skus.findIndex(item => item.skuId === shopItemSkuItem.skuId);
  597. cacheShopItemSkuItemIndex >= 0 ? cacheShopItem.skus[cacheShopItemSkuItemIndex] = shopItemSkuItem : cacheShopItem.skus.push(shopItemSkuItem)
  598. }
  599. }
  600. // 逻辑处理完毕更新缓存
  601. uni.setStorageSync(cacheKey, JSON.stringify(cartInfo))
  602. // 渲染视图
  603. this.handleRenderCart()
  604. }
  605. }
  606. ,
  607. /**
  608. * 根据本地缓存渲染购物车勾选
  609. * @constructor
  610. */
  611. handleRenderCart() {
  612. // 取消所有勾选
  613. this.dataList.forEach(shop => {
  614. shop.selected = 0
  615. shop.skus.forEach(sku => {
  616. sku.selected = 0
  617. })
  618. })
  619. // 校验缓存中的数据是否存在于购物车中
  620. this.handleCheckCacheAndUpdate()
  621. // 缓存内购物车信息
  622. let cartInfo = uni.getStorageSync(cacheKey);
  623. if (cartInfo === '') return
  624. cartInfo = JSON.parse(cartInfo)
  625. // 遍历购物车信息,寻找缓存比对
  626. this.dataList.forEach(nowCartShopItem => {
  627. let shopSelect = 1
  628. const cacheCartShopItem = cartInfo.find(item => item.shopId === nowCartShopItem.shopId);
  629. if (cacheCartShopItem) {
  630. // 如果缓存中有当前店铺,遍历当前购物车sku
  631. nowCartShopItem.skus.forEach(nowCartSkuItem => {
  632. const cacheCartSkuItem = cacheCartShopItem.skus.find(item => item.skuId === nowCartSkuItem.skuId);
  633. if (cacheCartSkuItem) {
  634. // 如果有一个未选中当前店铺就不能全选
  635. !cacheCartSkuItem.selected ? shopSelect = 0 : ''
  636. nowCartSkuItem.selected = cacheCartSkuItem.selected
  637. } else {
  638. shopSelect = 0
  639. }
  640. })
  641. } else {
  642. shopSelect = 0
  643. }
  644. nowCartShopItem.selected = shopSelect
  645. })
  646. }
  647. ,
  648. /**
  649. * 比较缓存内数据和后端数据是否一致,并且更新缓存
  650. * @constructor
  651. */
  652. handleCheckCacheAndUpdate() {
  653. // 缓存内购物车信息
  654. let cartInfo = uni.getStorageSync(cacheKey);
  655. if (cartInfo === '') return
  656. cartInfo = JSON.parse(cartInfo)
  657. // 校验缓存中的数据是否存在于购物车中
  658. cartInfo.forEach((cacheCartShopItem, cacheCartShopIndex) => {
  659. const nowCartShopItem = this.dataList.find(item => item.shopId === cacheCartShopItem.shopId);
  660. if (!nowCartShopItem) {
  661. cartInfo.splice(cacheCartShopIndex, 1)
  662. } else {
  663. // 存在就校验缓存中的sku在不在后端返回的列表内
  664. cacheCartShopItem.skus.forEach((cacheCartSkuItem, cacheCartSkuIndex) => {
  665. const nowCartSkuItem = nowCartShopItem.skus.find(item => item.skuId === cacheCartSkuItem.skuId)
  666. if (!nowCartSkuItem) {
  667. cacheCartShopItem.skus.splice(cacheCartSkuIndex, 1)
  668. }
  669. })
  670. }
  671. })
  672. uni.setStorageSync(cacheKey, JSON.stringify(cartInfo))
  673. }
  674. ,
  675. /**
  676. * 打开删除弹窗
  677. */
  678. handleOpenDelete() {
  679. if (!this.settleAccountsObj.checkNum) return uni.showToast({
  680. title: '请先选择对应商品',
  681. icon: 'none'
  682. })
  683. this.showDeleteModal = true
  684. }
  685. ,
  686. /**
  687. * 执行删除
  688. * @return {Promise<void>}
  689. */
  690. async handleDoDelete() {
  691. let ids = []
  692. for (const shopObj of this.dataList) {
  693. ids = [...ids, ...shopObj.skus.filter(sku => (sku.selected === 1 || sku.selected === true)).map(sku => sku.skuId)]
  694. }
  695. await NET.request(API.DeleteCart, {ids}, 'POST')
  696. this.showDeleteModal = false
  697. await this.getDataList()
  698. }
  699. ,
  700. /**
  701. * 结算购物车
  702. * @return {Promise<void>}
  703. */
  704. async settlementTap() {
  705. const {shopList} = await getPriceBySelect(this.dataList)
  706. uni.setStorageSync('skuItemDTOList', shopList)
  707. this.$jump('/pages_category_page1/orderModule/orderConfirm?type=2')
  708. }
  709. }
  710. }
  711. </script>
  712. <style
  713. lang="scss"
  714. scoped
  715. >
  716. .content {
  717. //overflow: hidden;
  718. //opacity: 0;
  719. .cart-bg {
  720. width: 100%;
  721. height: 180rpx;
  722. background-color: #fff;
  723. .cart-num-box {
  724. display: flex;
  725. flex-direction: row;
  726. align-items: center;
  727. justify-content: space-between;
  728. image {
  729. width: 286rpx;
  730. height: 72rpx;
  731. }
  732. .btn-box {
  733. font-size: 30rpx;
  734. color: #333333;
  735. padding: 30rpx;
  736. box-sizing: border-box;
  737. display: inline-block;
  738. }
  739. }
  740. .num-box {
  741. padding: 30rpx 0 30rpx 30rpx;
  742. box-sizing: border-box;
  743. font-size: 30rpx;
  744. color: #C5CACF;
  745. }
  746. }
  747. .cart-list-box {
  748. box-sizing: border-box;
  749. .itemBox {
  750. .item {
  751. background: #fff;
  752. border-bottom: 16rpx solid #F8F9FA;
  753. .shop-box {
  754. margin-top: 5rpx;
  755. display: flex;
  756. flex-direction: row;
  757. align-items: center;
  758. border-bottom: 1px solid #eee;
  759. position: relative;
  760. .cart-select-img {
  761. width: 40rpx;
  762. height: 40rpx;
  763. margin: 30rpx;
  764. box-sizing: border-box;
  765. }
  766. .shop-name-box {
  767. display: flex;
  768. flex-direction: row;
  769. align-items: center;
  770. .shop-img {
  771. width: 36rpx;
  772. height: 36rpx;
  773. margin-right: 10rpx;
  774. }
  775. .shop-name {
  776. font-size: 30rpx;
  777. color: #333;
  778. font-weight: bold;
  779. display: inline-block;
  780. margin-left: 10rpx;
  781. }
  782. .arrow-right-img {
  783. width: 30rpx;
  784. height: 30rpx;
  785. box-sizing: border-box;
  786. margin-left: 30rpx;
  787. position: absolute;
  788. right: 30rpx;
  789. }
  790. }
  791. }
  792. .rulesBox {
  793. height: 86rpx;
  794. background: #F9F6F1;
  795. padding: 0 20rpx;
  796. image {
  797. width: 126rpx;
  798. height: 46rpx;
  799. }
  800. }
  801. .product-list-box {
  802. margin: 8rpx 0;
  803. .pro-item {
  804. display: flex;
  805. flex-direction: row;
  806. align-items: center;
  807. .cart-select-img {
  808. width: 40rpx;
  809. height: 40rpx;
  810. margin: 30rpx;
  811. box-sizing: border-box;
  812. }
  813. .pro-r {
  814. flex: 1;
  815. border-bottom: 1px solid #eee;
  816. display: flex;
  817. flex-direction: row;
  818. padding: 30rpx 30rpx 30rpx 0;
  819. box-sizing: border-box;
  820. overflow: hidden;
  821. .pro-img {
  822. width: 180rpx;
  823. height: 180rpx;
  824. border-radius: 10rpx;
  825. margin-right: 30rpx;
  826. }
  827. .pro-r-r {
  828. flex: 1;
  829. font-size: 26rpx;
  830. color: #333;
  831. overflow: hidden;
  832. display: flex;
  833. flex-direction: column;
  834. justify-content: space-between;
  835. .pro-name {
  836. height: 66rpx;
  837. line-height: 33rpx;
  838. display: -webkit-box;
  839. overflow: hidden;
  840. text-overflow: ellipsis;
  841. word-break: break-all;
  842. -webkit-box-orient: vertical;
  843. -webkit-line-clamp: 2;
  844. }
  845. .sku-box {
  846. width: auto;
  847. display: inline;
  848. height: 40rpx;
  849. border-radius: 4rpx;
  850. padding: 0 0 0 10rpx;
  851. box-sizing: border-box;
  852. font-size: 24rpx;
  853. color: #999;
  854. text {
  855. border: 2rpx solid #E4E5E6;
  856. padding: 2rpx 10rpx;
  857. }
  858. }
  859. .pro-price-num-box {
  860. display: flex;
  861. flex-direction: row;
  862. align-items: center;
  863. justify-content: space-between;
  864. .pro-price-box {
  865. font-size: 36rpx;
  866. color: #333333;
  867. font-weight: 400;
  868. .fuhao {
  869. font-size: 24rpx;
  870. }
  871. }
  872. .pro-num-box {
  873. width: 140rpx;
  874. height: 40rpx;
  875. border: 1px solid #ddd;
  876. border-radius: 4rpx;
  877. display: flex;
  878. flex-direction: row;
  879. justify-content: space-between;
  880. overflow: hidden;
  881. .num-btn {
  882. font-size: 34rpx;
  883. color: #999999;
  884. display: inline-block;
  885. width: 40rpx;
  886. text-align: center;
  887. line-height: 32rpx;
  888. height: 40rpx;
  889. }
  890. .num-btn.r {
  891. border-right: 1px solid #ddd;
  892. }
  893. .num-btn.l {
  894. border-left: 1px solid #ddd;
  895. }
  896. .num {
  897. font-size: 26rpx;
  898. color: #333;
  899. }
  900. }
  901. }
  902. }
  903. }
  904. }
  905. .pro-item:last-of-type .pro-r {
  906. border-bottom: none;
  907. }
  908. }
  909. }
  910. }
  911. .itemBox:first-child {
  912. .shop-box {
  913. border-top: 2rpx solid #eee;
  914. }
  915. }
  916. .itemBox:last-child {
  917. .item {
  918. border-bottom: none;
  919. }
  920. }
  921. }
  922. .emptyCart-box {
  923. margin: 100rpx 0;
  924. .emptyCart-img {
  925. width: 216rpx;
  926. height: 156rpx;
  927. }
  928. .goToShopping {
  929. width: 282rpx;
  930. height: 84rpx;
  931. line-height: 84rpx;
  932. text-align: center;
  933. background: #333333;
  934. margin-top: 40rpx;
  935. color: #FFEBC4;
  936. font-size: 28rpx;
  937. }
  938. }
  939. .cart-bottom-box-h5 {
  940. position: fixed;
  941. bottom: 80rpx;
  942. width: 100%;
  943. z-index: 99;
  944. }
  945. .cart-bottom-box-app {
  946. position: fixed;
  947. bottom: 0rpx;
  948. width: 100%;
  949. z-index: 99;
  950. }
  951. .cart-bottom {
  952. height: 120rpx;
  953. background: #fff;
  954. display: flex;
  955. flex-direction: row;
  956. align-items: center;
  957. justify-content: space-between;
  958. border-top: 1rpx solid #eee;
  959. }
  960. .left {
  961. display: flex;
  962. flex-direction: row;
  963. align-items: center;
  964. font-size: 28rpx;
  965. color: #666;
  966. .cart-select-img {
  967. width: 40rpx;
  968. height: 40rpx;
  969. margin: 30rpx;
  970. box-sizing: border-box;
  971. }
  972. }
  973. .right {
  974. display: flex;
  975. flex-direction: row;
  976. align-items: center;
  977. box-sizing: border-box;
  978. .price-box {
  979. font-size: 30rpx;
  980. color: #333;
  981. .price {
  982. font-size: 40rpx;
  983. color: #C83732;
  984. font-weight: bold;
  985. }
  986. }
  987. .btn-confirm {
  988. width: 232rpx;
  989. height: 120rpx;
  990. background: #333333;
  991. margin-left: 18rpx;
  992. text-align: center;
  993. line-height: 120rpx;
  994. font-size: 28rpx;
  995. color: #FFEBC4;
  996. }
  997. .btn-delete {
  998. width: 232rpx;
  999. height: 120rpx;
  1000. line-height: 120rpx;
  1001. text-align: center;
  1002. font-size: 28rpx;
  1003. color: #FFFFFF;
  1004. background: #C83732;
  1005. }
  1006. }
  1007. }
  1008. </style>