超市购物车
This commit is contained in:
1 parent
d3c67fed9b
commit
f2dd10aefb
6 files changed
+236
-32
No files matched your search
@@ -0,0 +1,89 @@
|
||||
<template>
|
||||
<crud-layout title="购物车" mainIsScroll tabBarType="just-flot-back" bg="/static/page/blue-bg.png">
|
||||
<view v-if="cartStore.totCount > 0" class="flex-row card p-x-15rpx p-y-25rpx m-t-20rpx" v-for="(v, i) in cartStore.cart" :key="i">
|
||||
<image class="size-160rpx rounded-12rpx" :src="filePath(v.picUrl)" mode="aspectFill" />
|
||||
<view class="flex-1 m-l-20rpx">
|
||||
<view class="sub-text-28 show-line">{{ v.productName }}</view>
|
||||
<view class="second-text-26 show-line">单位:{{ v.unit }}</view>
|
||||
<view class="flex-row justify-between items-center">
|
||||
<view class="second-text-30"> ¥{{ hooks.useMoney(v.productPrice) }} </view>
|
||||
<view class="second-text-30">x {{ v.productCount }}</view>
|
||||
</view>
|
||||
<view class="flex-row justify-between items-center">
|
||||
<view class="second-text-32 c-red!"> ¥{{ hooks.useMoney(v.totalPrice) }} </view>
|
||||
<view class="flex-row justify-between items-center">
|
||||
<view
|
||||
class="flex-row-center size-40rpx rounded-full border-1px border-solid border-color-#0094ff"
|
||||
@tap.stop="remove(v.productId)"
|
||||
>
|
||||
<view class="iconfont icon-a--" />
|
||||
</view>
|
||||
<view class="sub-text-28 m-x-20rpx">{{ v.productCount }}</view>
|
||||
<view class="flex-row-center size-40rpx rounded-full bg-#0094ff" @tap.stop="add(v.productId)">
|
||||
<view class="font-size-40rpx color-white iconfont icon-a-" />
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<view class="flex-col justify-center items-center pt-300rpx" v-else>
|
||||
<image src="@/static/page/cart_empty.png" class="w-350rpx h-350rpx" />
|
||||
<text class="sub-text-32 font-bold">购物车空空如也</text>
|
||||
</view>
|
||||
|
||||
<template #main-bottom>
|
||||
<view class="z-200 p-x-30rpx p-y-30rpx bg-white">
|
||||
<product-total :totPrice="cartStore.totPrice" :totCount="cartStore.totCount" @doContainer="" @submit="doBuy" />
|
||||
</view>
|
||||
</template>
|
||||
</crud-layout>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import ProductTotal from "./components/product-total.vue"
|
||||
import { isEmpty } from "radash"
|
||||
import { useCartStore } from "@/sheep/stores/cart"
|
||||
import { payApi } from "@/sheep/api"
|
||||
import { hooks, router } from "@/sheep"
|
||||
import { filePath } from "@/sheep/utils/file"
|
||||
|
||||
const cartStore = useCartStore()
|
||||
|
||||
// 点击提交订单
|
||||
const doBuy = async () => {
|
||||
uni.showModal({
|
||||
title: "提示",
|
||||
content: "是否确定购买",
|
||||
confirmColor: "#0094ff",
|
||||
success: async (res) => {
|
||||
if (!res.confirm) return
|
||||
submitPay()
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
// 提交订单
|
||||
const submitPay = async () => {
|
||||
try {
|
||||
if (isEmpty(cartStore.cart)) return uni.showToast({ title: "请至少购买一件商品", icon: "none" })
|
||||
|
||||
uni.showLoading({ title: "支付中...", mask: false })
|
||||
const { data, code }: any = await payApi.createHardwareOrder({ carParentId: cartStore.cart[0].parentCarId, hardType: "SUPERMARKET" })
|
||||
if (code != 0) throw new Error()
|
||||
uni.showToast({ title: "支付成功", icon: "none" })
|
||||
router.jump("/pages/tabbar/order")
|
||||
} catch (error) {
|
||||
console.error(error)
|
||||
} finally {
|
||||
uni.hideLoading()
|
||||
}
|
||||
}
|
||||
|
||||
const add = async (productId: string) => {
|
||||
await cartStore.addProductCount(productId)
|
||||
}
|
||||
const remove = async (productId: string) => {
|
||||
await cartStore.removeProductCount(productId)
|
||||
}
|
||||
</script>
|
||||
@@ -71,7 +71,7 @@
|
||||
|
||||
<template #footer>
|
||||
<button
|
||||
class="mx-12 border-rd-8 bg-#0094ff sub-text-30 py-2 c-white!"
|
||||
class="mx-12 rounded-3 bg-#0094ff sub-text-30 py-2 c-white!"
|
||||
:class="{ 'bg-#0094ff77!': Object.keys(state.selectedSku).length === 0 }"
|
||||
@tap="handleSkuAddToCart"
|
||||
>
|
||||
@@ -172,7 +172,6 @@ const handleSkuAddToCart = async () => {
|
||||
skuId: state.selectedSku.id,
|
||||
...state.selectedSku,
|
||||
productCount: state.goodsCount,
|
||||
// productId: state.selectedSku.id,
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
@@ -6,6 +6,7 @@ import { shopApi } from "@@/api"
|
||||
import { filePath } from "@/sheep/utils/file"
|
||||
import ProductSku from "./components/product-sku.vue"
|
||||
import { useCartStore } from "@/sheep/stores/cart"
|
||||
import { hooks, router } from "@/sheep"
|
||||
|
||||
const cartStore = useCartStore()
|
||||
|
||||
@@ -35,10 +36,18 @@ const addToCart = () => {
|
||||
}
|
||||
|
||||
// 选择sku加入到购物车
|
||||
const onSkuAddToCart = (selectedSku: any) => {
|
||||
cartStore.addGoodsItemToCart({ productDetail: state.detail, selectedSku })
|
||||
const onSkuAddToCart = (sku: any) => {
|
||||
cartStore.addGoodsItemToCart({ ...state.detail, ...sku, productId: sku.skuId })
|
||||
cartStore.updateShopCart()
|
||||
state.showSkuDialog = false
|
||||
}
|
||||
|
||||
const doCart = async () => {
|
||||
const isLogin = await hooks.useCheckLogin()
|
||||
if (isLogin) {
|
||||
router.jump("/pages/shop/cart")
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
@@ -70,7 +79,7 @@ const onSkuAddToCart = (selectedSku: any) => {
|
||||
<view class="flex-col justify-between card p-y-20rpx p-x-30rpx">
|
||||
<view class="prefix_title mb-15rpx">包装</view>
|
||||
<view class="flex flex-wrap">
|
||||
<view class="w-1/3 flex justify-center p-1" v-for="(item, index) in state.detail.skuList" :key="index">
|
||||
<view class="w-1/3 flex justify-center p-1" v-for="(item, index) in state.detail?.skuList" :key="index">
|
||||
<view class="p-2 bg-#eeeeee77 rounded-3 flex-col items-center">
|
||||
<view class="second-text-28">{{ item.spec + " / " + item.unit }}</view>
|
||||
<view class="second-text-28">内装:{{ item.packageNum }}</view>
|
||||
@@ -97,7 +106,15 @@ const onSkuAddToCart = (selectedSku: any) => {
|
||||
<view class="h-80rpx" />
|
||||
|
||||
<template #main-bottom>
|
||||
<view class="my-4 mx-12 z-200 rounded-3 text-center bg-#0094ff py-2 c-white" @tap="addToCart">加入购物车</view>
|
||||
<view class="flex-row justify-between items-center my-4 mx-12">
|
||||
<tm-badge bg-color="red" :label="cartStore.totCount">
|
||||
<view class="flex-col-center" @tap="doCart">
|
||||
<view class="color-#0094ff! iconfont icon-biaoqianlanicon_gouwuche-xuanzhong" />
|
||||
<view class="c-#0094ff text-20rpx">购物车</view>
|
||||
</view>
|
||||
</tm-badge>
|
||||
<view class="flex-1 ml-8 rounded-3 text-center bg-#0094ff py-2 c-white" @tap="addToCart">加入购物车</view>
|
||||
</view>
|
||||
</template>
|
||||
</crud-layout>
|
||||
|
||||
|
||||
@@ -24,22 +24,31 @@
|
||||
<tm-icon name="arrow-down-s-fill" color="#0779FD" size="40" />
|
||||
</view>
|
||||
</view>
|
||||
<tm-input
|
||||
v-model="state.params.productName"
|
||||
type="text"
|
||||
:height="66"
|
||||
:minHeight="66"
|
||||
:fontSize="28"
|
||||
:showClear="true"
|
||||
:focus="true"
|
||||
placeholder="请输入商品名称"
|
||||
style="border: 2px solid #0779fd; border-radius: 14rpx"
|
||||
:focus-highlight="false"
|
||||
>
|
||||
<template v-slot:rightIcon>
|
||||
<tm-button class="mr-1 py-3" size="xs" @click="searchProduct">搜索</tm-button>
|
||||
</template>
|
||||
</tm-input>
|
||||
<view class="flex-row justify-between items-center">
|
||||
<tm-input
|
||||
v-model="state.params.productName"
|
||||
type="text"
|
||||
:height="66"
|
||||
:minHeight="66"
|
||||
:fontSize="28"
|
||||
:showClear="true"
|
||||
:focus="true"
|
||||
placeholder="请输入商品名称"
|
||||
style="border: 2px solid #0779fd; border-radius: 14rpx"
|
||||
:focus-highlight="false"
|
||||
>
|
||||
<template v-slot:rightIcon>
|
||||
<tm-button class="mr-1 py-3" size="xs" @click="searchProduct">搜索</tm-button>
|
||||
</template>
|
||||
</tm-input>
|
||||
<tm-badge bg-color="red" :offset="[8, 4]" :label="cartStore.totCount">
|
||||
<view class="flex-col-center size-80rpx" @tap="doCart">
|
||||
<view class="color-#0094ff! iconfont icon-biaoqianlanicon_gouwuche-xuanzhong" />
|
||||
<view class="c-#0094ff text-20rpx">购物车</view>
|
||||
</view>
|
||||
</tm-badge>
|
||||
</view>
|
||||
|
||||
<scroll-view scroll-x class="whitespace-nowrap my-2">
|
||||
<tm-tag
|
||||
class="mx-1"
|
||||
@@ -168,7 +177,7 @@ onLoad(async () => {
|
||||
|
||||
await getAllMerchant()
|
||||
await getClassify()
|
||||
await getShopCart()
|
||||
await cartStore.getShopCart()
|
||||
})
|
||||
|
||||
onShow(() => {
|
||||
@@ -207,14 +216,6 @@ const getClassify = async () => {
|
||||
}
|
||||
}
|
||||
|
||||
// 获取购物车
|
||||
const getShopCart = async () => {
|
||||
if (state.curMerchant.id) {
|
||||
const { data } = await foodApi.getShopCar({ merchantId: state.curMerchant.id, hardType: "SUPERMARKET" })
|
||||
cartStore.saveShoppingCart(data ?? [])
|
||||
}
|
||||
}
|
||||
|
||||
// 切换超市
|
||||
const changeShop = () => {
|
||||
state.curMerchantRadioId = state.curMerchant.id || ""
|
||||
@@ -226,7 +227,7 @@ const confirmRadioMerchant = async () => {
|
||||
state.curMerchant = state.merchantList.find((item: any) => item.id == state.curMerchantRadioId)
|
||||
state.showDrawer = false
|
||||
await getClassify()
|
||||
await getShopCart()
|
||||
await cartStore.getShopCart()
|
||||
}
|
||||
|
||||
// 点击搜索
|
||||
@@ -253,4 +254,11 @@ const toDetail = async (v: any) => {
|
||||
router.jump("/pages/shop/product-detail", { id: v.id })
|
||||
}
|
||||
}
|
||||
|
||||
const doCart = async () => {
|
||||
const isLogin = await hooks.useCheckLogin()
|
||||
if (isLogin) {
|
||||
router.jump("/pages/shop/cart")
|
||||
}
|
||||
}
|
||||
</script>
|
||||
@@ -0,0 +1,91 @@
|
||||
import { defineStore } from "pinia"
|
||||
import { foodApi } from "../api"
|
||||
|
||||
export const useCartStore = defineStore("cartStore", {
|
||||
state: () => ({
|
||||
cart: JSON.parse(uni.getStorageSync("cart") || "[]"),
|
||||
}),
|
||||
getters: {
|
||||
totCount(state) {
|
||||
return state.cart.reduce((prev, cur) => {
|
||||
return prev + cur.productCount
|
||||
}, 0)
|
||||
},
|
||||
totPrice(state) {
|
||||
return state.cart
|
||||
.map((item) => Number(item.totalPrice))
|
||||
.reduce((prev, cur) => prev + cur, 0)
|
||||
.toFixed(2)
|
||||
},
|
||||
},
|
||||
actions: {
|
||||
// 更新购物车中商品数量的方法
|
||||
updataGoodsCount(goods) {
|
||||
// 从购物车数组对象中查找到需要更新的这件商品
|
||||
const findResult = this.cart.find((item) => {
|
||||
return item.goods_id === goods.goods_id
|
||||
})
|
||||
// 如果查找到,就把这件商品传递的最新数量保存,并本地存储
|
||||
if (findResult) {
|
||||
findResult.goods_count = goods.goods_count
|
||||
this.saveToStorage()
|
||||
}
|
||||
},
|
||||
|
||||
// ===================================================================
|
||||
|
||||
saveToStorage() {
|
||||
uni.setStorageSync("cart", JSON.stringify(this.cart))
|
||||
},
|
||||
saveShoppingCart(cartList: any) {
|
||||
this.cart = cartList
|
||||
this.saveToStorage()
|
||||
},
|
||||
addGoodsItemToCart(goodsItem: any) {
|
||||
const findResult = this.cart.find((item: any) => {
|
||||
return item.productId === goodsItem.productId
|
||||
})
|
||||
if (!findResult) {
|
||||
this.cart.unshift(goodsItem)
|
||||
} else {
|
||||
findResult.productCount++
|
||||
}
|
||||
this.saveToStorage()
|
||||
},
|
||||
async addProductCount(productId: string) {
|
||||
this.cart.forEach((item: any) => {
|
||||
if (item.productId === productId) {
|
||||
item.productCount++
|
||||
}
|
||||
})
|
||||
await this.updateShopCart()
|
||||
await this.getShopCart()
|
||||
},
|
||||
async removeProductCount(productId: string) {
|
||||
this.cart.forEach((item: any) => {
|
||||
if (item.productId === productId) {
|
||||
item.productCount--
|
||||
}
|
||||
})
|
||||
await this.updateShopCart()
|
||||
await this.getShopCart()
|
||||
},
|
||||
async getShopCart() {
|
||||
const { data } = await foodApi.getShopCar({ merchantId: "1931916121241079810", hardType: "SUPERMARKET" })
|
||||
this.saveShoppingCart(data ?? [])
|
||||
},
|
||||
async updateShopCart() {
|
||||
const list = this.cart
|
||||
.filter((v) => v.productCount && v.productCount > 0)
|
||||
.map((v) => {
|
||||
return {
|
||||
productCount: v.productCount,
|
||||
productId: v.productId,
|
||||
}
|
||||
})
|
||||
const { code }: any = await foodApi.updateShopCar({ merchantId: "1931916121241079810", list, hardType: "SUPERMARKET" })
|
||||
if (code == 0) return await this.getShopCart()
|
||||
uni.showToast({ title: "更新购物车失败", icon: "none" })
|
||||
},
|
||||
},
|
||||
})
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 1.6 MiB |
Reference in new issue
Block a user