超市商品详情和包装单位选择修改

This commit is contained in:
weiwei committed 2025-06-19 10:58:19 +08:00
1 parent cd483e00d5
commit d3c67fed9b
3 files changed
+94 -42

No files matched your search

+21 -12
View File
@@ -1,6 +1,6 @@
<template>
<tm-drawer
z-index="100"
z-index="800"
v-model:show="props.modelValue"
showFooter
showClose
@@ -86,6 +86,7 @@ import { shopApi } from "@/sheep/api"
import { filePath } from "@/sheep/utils/file"
import { reactive, watch } from "vue"
import { usePreviewImage } from "@/sheep/hooks/use-img"
import { isEmpty } from "radash"
const emit = defineEmits(["update:modelValue", "onSkuAddToCart"])
@@ -101,13 +102,13 @@ const props = withDefaults(
)
const state = reactive<any>({
goodsCount: 1,
goodsDetail: {},
selectedSku: {
retailPrice: 0,
promotionPrice: 0,
packageNum: 0,
},
goodsDetail: {},
goodsCount: 1,
})
watch(
@@ -115,9 +116,13 @@ watch(
async (newValue) => {
if (newValue) {
// 获取商品详情
const { data } = await shopApi.getSupermarketSpuDetail({ id: props.productData.id })
state.goodsDetail = data
if (data.skuList.length > 0) {
// const { data } = await shopApi.getSupermarketSpuDetail({ id: props.productData.id })
// state.goodsDetail = data
// if (data.skuList.length > 0) {
// state.selectedSku = state.goodsDetail.skuList[0]
// }
state.goodsDetail = props.productData
if (!isEmpty(state.goodsDetail)) {
state.selectedSku = state.goodsDetail.skuList[0]
}
}
@@ -153,9 +158,7 @@ const handleSkuAddToCart = async () => {
try {
uni.showLoading({ title: "加载中", mask: true })
const { code }: any = await shopApi.checkSpuStock({ spuId: state.goodsDetail.id, incrCount: state.goodsCount })
if (code != 0) {
return uni.showToast({ title: "库存不足", icon: "none" })
}
if (code != 0) return uni.showToast({ title: "库存不足", icon: "none" })
} catch (e) {
console.error(e)
} finally {
@@ -164,18 +167,24 @@ const handleSkuAddToCart = async () => {
// 检查库存
if (state.goodsDetail.stock === 0) return uni.showToast({ title: "库存不足", icon: "none" })
emit("onSkuAddToCart", { ...state.goodsDetail, productCount: state.goodsCount, productId: state.selectedSku.id })
emit("onSkuAddToCart", {
spuId: state.goodsDetail.id,
skuId: state.selectedSku.id,
...state.selectedSku,
productCount: state.goodsCount,
// productId: state.selectedSku.id,
})
}
const doClose = () => {
emit("update:modelValue", false)
state.goodsCount = 1
state.goodsDetail = {}
state.selectedSku = {
retailPrice: 0,
promotionPrice: 0,
packageNum: 0,
}
state.goodsDetail = {}
state.goodsCount = 1
}
</script>
+44 -16
View File
@@ -4,10 +4,15 @@ import { onLoad, onShow } from "@dcloudio/uni-app"
import { isEmpty } from "radash"
import { shopApi } from "@@/api"
import { filePath } from "@/sheep/utils/file"
import ProductSku from "./components/product-sku.vue"
import { useCartStore } from "@/sheep/stores/cart"
const cartStore = useCartStore()
const state = reactive<any>({
detailId: null,
detail: null,
showSkuDialog: false,
})
onLoad((options: any) => {
@@ -21,12 +26,23 @@ onShow(() => {
const getDetail = async () => {
const { data } = await shopApi.getSupermarketSpuDetail({ id: state.detailId })
state.detail = data
state.detail = data ?? {}
}
// 加入购物车
const addToCart = () => {
state.showSkuDialog = true
}
// 选择sku加入到购物车
const onSkuAddToCart = (selectedSku: any) => {
cartStore.addGoodsItemToCart({ productDetail: state.detail, selectedSku })
state.showSkuDialog = false
}
</script>
<template>
<crud-layout title="订单详情" tabBarType="just-flot-back" bg="/static/page/blue-bg.png">
<crud-layout title="订单详情" mainIsScroll tabBarType="just-flot-back" bg="/static/page/blue-bg.png">
<swiper
class="w-100vw h-30vh"
circular
@@ -43,27 +59,30 @@ const getDetail = async () => {
<view class="p-15rpx">
<view class="flex-col justify-between card p-y-20rpx p-x-30rpx">
<view class="prefix_title mb-15rpx">商品</view>
<view class="sub-text-32">{{ state.detail.productName }}</view>
<view class="sub-text-32">{{ state.detail?.productName }}</view>
<view class="flex-row items-center justify-between m-t-15rpx">
<!-- <view class="second-text-46 color-#f63a36!">¥{{ state.detail.price }}</view> -->
<!-- <view class="m-l-20rpx second-text-28 line-through">¥{{ state.detail.marketPrice }}</view> -->
<view class="second-text-26">库存{{ state.detail.stock }}</view>
<view class="second-text-26">已售{{ state.detail.salesCount }}</view>
<view class="second-text-26">库存{{ state.detail?.stock }}</view>
<view class="second-text-26">已售{{ state.detail?.salesCount }}</view>
</view>
</view>
<view class="h-15rpx" />
<view class="flex-col justify-between card p-y-20rpx p-x-30rpx">
<view class="prefix_title mb-15rpx">包装单位</view>
<!-- <view class="flex justify-between p-2 m-2" v-for="(item, index) in state.detail.skuList" :key="index">
<view class="second-text-28">{{ item.spec + " / " + item.unit }}</view>
<view class="second-text-28">装数:{{ item.packageNum }}</view>
<view class="flex items-center">
<view class="second-text-30 c-red!"> 促销 ¥{{ parseFloat(item.promotionPrice) || item.retailPrice || 0 }} </view>
<view class="m-l-20rpx second-text-28 line-through">原价 ¥{{ item.retailPrice || 0 }}</view>
<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="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>
<view class="flex items-center">
<view class="second-text-30 c-red!">¥{{ parseFloat(item.promotionPrice) || item.retailPrice || 0 }}</view>
<view class="ml-4rpx second-text-30 line-through">¥{{ item.retailPrice || 0 }}</view>
</view>
</view>
</view>
</view> -->
</view>
</view>
<view class="h-15rpx" />
<view class="flex-col justify-between card p-y-20rpx p-x-30rpx">
<view class="prefix_title mb-15rpx">评价</view>
@@ -71,10 +90,19 @@ const getDetail = async () => {
<view class="h-15rpx" />
<view class="flex-col justify-between card p-y-20rpx p-x-30rpx">
<view class="prefix_title mb-15rpx">详情</view>
<view class="m-t-15rpx" v-html="state.detail.description"></view>
<view class="m-t-15rpx" v-html="state.detail?.description"></view>
</view>
</view>
<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>
</template>
</crud-layout>
<!-- 单位与数量选择 -->
<product-sku v-model="state.showSkuDialog" :productData="state.detail" @onSkuAddToCart="onSkuAddToCart" />
</template>
<style lang="scss" scoped>
+29 -14
View File
@@ -102,17 +102,17 @@
<view
v-for="(item, index) in state.merchantList"
:key="index"
class="w-full flex items-center p-2"
class="w-full flex items-center p-2 rounded-3"
:class="[state.curMerchantRadioId == item.id ? 'bg-#e8e8e8' : '']"
>
<tm-radio class="w-full h-full px-2" :value="item.id">
<template v-slot:label="checked">
<view class="flex items-center">
<image class="w-130rpx h-130rpx" :src="filePath(item.logoPic)" />
<image class="w-130rpx h-130rpx rounded-2" :src="filePath(item.logoPic)" mode="aspectFill" />
<view class="ml-2 flex-1 flex-col">
<tm-text font-size="30">{{ item.name }}</tm-text>
<tm-text font-size="28">地址:{{ item.addressDes }}</tm-text>
<tm-text font-size="28">手机:{{ item.phone }}</tm-text>
<view class="second-text-26">地址:{{ item.addressDes }}</view>
<view class="second-text-26">手机:{{ item.phone }}</view>
</view>
</view>
</template>
@@ -139,8 +139,11 @@ import { LazyImg, Waterfall } from "vue-waterfall-plugin-next"
import "vue-waterfall-plugin-next/dist/style.css"
import { isEmpty } from "radash"
import { filePath } from "@@/utils/file"
import { merchantApi, shopApi } from "@@/api"
import { foodApi, merchantApi, shopApi } from "@@/api"
import { hooks, router } from "@@/index"
import { useCartStore } from "@/sheep/stores/cart"
const cartStore = useCartStore()
const state = reactive<any>({
params: {
@@ -149,11 +152,13 @@ const state = reactive<any>({
size: 10,
productName: "",
},
merchantList: [],
curMerchant: {},
classifyList: [],
curMerchantRadioId: "",
showDrawer: false,
curMerchantRadioId: "",
})
const pageRef = ref<any>(null)
@@ -163,6 +168,7 @@ onLoad(async () => {
await getAllMerchant()
await getClassify()
await getShopCart()
})
onShow(() => {
@@ -201,24 +207,26 @@ 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 || ""
state.showDrawer = true
}
// 确定选择超市
// 确定切换超市
const confirmRadioMerchant = async () => {
state.curMerchant = state.merchantList.find((item: any) => item.id == state.curMerchantRadioId)
state.showDrawer = false
await getClassify()
}
// 切换分类
const doClassify = async (id: string) => {
if (state.params.categoryId == id) return
state.params.categoryId = id
pageRef.value && pageRef.value.reload(true)
await getShopCart()
}
// 点击搜索
@@ -226,6 +234,13 @@ const searchProduct = () => {
pageRef.value && pageRef.value.reload(true)
}
// 切换分类
const doClassify = async (categoryId: string) => {
if (state.params.categoryId == categoryId) return
state.params.categoryId = categoryId
pageRef.value && pageRef.value.reload(true)
}
const pageHook = hooks.usePage(pageRef, shopApi.getSupermarketSpuList, null, "data.records")
const query = (page: number, pagesize: number) => {