From 220af7f756aa4879c0dca91289aacdae7a65f2d7 Mon Sep 17 00:00:00 2001 From: weiwei Date: Thu, 5 Jun 2025 11:36:18 +0800 Subject: [PATCH 1/7] =?UTF-8?q?=E8=A7=A3=E9=99=A4=E6=B3=A8=E9=87=8A?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/pages/shop/detail.vue | 50 +++++++++++++++++++-------------------- 1 file changed, 25 insertions(+), 25 deletions(-) diff --git a/src/pages/shop/detail.vue b/src/pages/shop/detail.vue index f9909e4..a2fe252 100644 --- a/src/pages/shop/detail.vue +++ b/src/pages/shop/detail.vue @@ -175,8 +175,8 @@ onShow(async () => { }) try { await getDetail() - // await getShopCar() - // await getClassify() + await getShopCar() + await getClassify() } catch (error) { uni.showToast({ title: "加载失败", @@ -222,29 +222,29 @@ const getPorduct = async () => { size: 9999, }) state.goodsList = data.records - // state.goodsList.forEach((i) => { - // if (i && i.foodSPURespVOList && i.foodSPURespVOList.length) { - // i.foodSPURespVOList.forEach((j) => { - // j.productCount = 0; - // j.productId = j.id; - // }); - // } - // }); - // const goodsList = [...state.goodsList]; - // if (state.carList && state.carList.length) { - // for (const i of goodsList) { - // if (i && i.foodSPURespVOList && i.foodSPURespVOList.length) { - // for (const j of i.foodSPURespVOList) { - // for (const v of state.carList) { - // if (j.id == v.productId) { - // j.productCount = v.productCount; - // } - // } - // } - // } - // } - // } - // state.goodsList = goodsList; + state.goodsList.forEach((i) => { + if (i && i.foodSPURespVOList && i.foodSPURespVOList.length) { + i.foodSPURespVOList.forEach((j) => { + j.productCount = 0 + j.productId = j.id + }) + } + }) + const goodsList = [...state.goodsList] + if (state.carList && state.carList.length) { + for (const i of goodsList) { + if (i && i.foodSPURespVOList && i.foodSPURespVOList.length) { + for (const j of i.foodSPURespVOList) { + for (const v of state.carList) { + if (j.id == v.productId) { + j.productCount = v.productCount + } + } + } + } + } + } + state.goodsList = goodsList } const doClassify = async (i: any) => { From bab4a4383baf3353a990d457a3855a5883ac2544 Mon Sep 17 00:00:00 2001 From: weiwei Date: Thu, 5 Jun 2025 16:12:34 +0800 Subject: [PATCH 2/7] =?UTF-8?q?=E5=9C=A8=E7=BA=BF=E5=95=86=E5=9F=8E?= =?UTF-8?q?=E9=A1=B5=E9=9D=A2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/App.vue | 23 ++- src/pages.json | 15 +- src/pages/canteen/detail.vue | 2 +- .../{product-car.vue => product-cart.vue} | 14 +- src/pages/shop/components/product-total.vue | 48 ++--- src/pages/shop/detail.vue | 165 ++++++++---------- src/pages/tabbar/onlineShop.vue | 82 +++++++++ src/sheep/utils/app.ts | 4 +- src/static/tabbar/online-shop-select.png | Bin 0 -> 5113 bytes src/static/tabbar/online-shop.png | Bin 0 -> 4996 bytes 10 files changed, 211 insertions(+), 142 deletions(-) rename src/pages/shop/components/{product-car.vue => product-cart.vue} (83%) create mode 100644 src/pages/tabbar/onlineShop.vue create mode 100644 src/static/tabbar/online-shop-select.png create mode 100644 src/static/tabbar/online-shop.png diff --git a/src/App.vue b/src/App.vue index ac5b9d9..f314ac1 100644 --- a/src/App.vue +++ b/src/App.vue @@ -2,11 +2,6 @@ import { isDevEnv, getLaunchParam } from "@/sheep/utils/app" import { getAppInfo } from "@@/utils/app" -// import { onLaunch, onShow, onHide } from "@dcloudio/uni-app" -// onLaunch(() => {}) -// onShow(() => {}) -// onHide(() => {}) - interface TabbarItem { pagePath: string text: string @@ -33,6 +28,14 @@ const tabbar: TabbarItem[] = [ launchParam: ["selfMerchant"], auth: ["user"], }, + { + pagePath: "pages/tabbar/onlineShop", + text: "在线商城", + iconPath: "/static/tabbar/online-shop.png", + selectedIconPath: "/static/tabbar/online-shop-select.png", + launchParam: ["onlineShop"], + auth: ["user"], + }, { pagePath: "pages/tabbar/coopMerchant", text: "合作商家", @@ -54,7 +57,7 @@ const tabbar: TabbarItem[] = [ text: "订单", iconPath: "/static/tabbar/order.png", selectedIconPath: "/static/tabbar/order-select.png", - launchParam: ["canteen", "selfMerchant", "coopMerchant"], + launchParam: ["canteen", "selfMerchant", "onlineShop", "coopMerchant"], auth: ["user"], }, { @@ -94,7 +97,7 @@ const tabbar: TabbarItem[] = [ text: "我的", iconPath: "/static/tabbar/my.png", selectedIconPath: "/static/tabbar/my-select.png", - launchParam: ["canteen", "selfMerchant", "coopMerchant"], + launchParam: ["canteen", "selfMerchant", "onlineShop", "coopMerchant"], auth: ["user", "merchant", "doorAdmin"], }, ] @@ -149,6 +152,9 @@ export default { case "selfMerchant": uni.switchTab({ url: "/pages/tabbar/selfMerchant" }) break + case "onlineShop": + uni.switchTab({ url: "/pages/tabbar/onlineShop" }) + break case "coopMerchant": uni.switchTab({ url: "/pages/tabbar/coopMerchant" }) break @@ -169,6 +175,7 @@ export default { return uni.switchTab({ url: "/pages/tabbar/individualOrder" }) case "user": if (launchParam === "selfMerchant") return uni.switchTab({ url: "/pages/tabbar/selfMerchant" }) + if (launchParam === "onlineShop") return uni.reLaunch({ url: "/pages/tabbar/onlineShop" }) if (launchParam === "coopMerchant") return uni.reLaunch({ url: "/pages/tabbar/coopMerchant" }) return case "doorAdmin": @@ -179,8 +186,6 @@ export default { } } }, - onShow() {}, - onHide() {}, methods: { async _initTabbar() { diff --git a/src/pages.json b/src/pages.json index df22365..669c84a 100644 --- a/src/pages.json +++ b/src/pages.json @@ -23,6 +23,13 @@ "disableScroll": true } }, + { + "path": "pages/tabbar/onlineShop", + "style": { + "navigationBarTitleText": "在线商城", + "disableScroll": true + } + }, { "path": "pages/tabbar/coopMerchant", "style": { @@ -483,6 +490,12 @@ "iconPath": "", "selectedIconPath": "" }, + { + "pagePath": "pages/tabbar/onlineShop", + "text": "", + "iconPath": "", + "selectedIconPath": "" + }, { "pagePath": "pages/tabbar/coopMerchant", "text": "", @@ -521,7 +534,7 @@ }, { "pagePath": "pages/tabbar/message", - "text": "通知公告", + "text": "", "iconPath": "", "selectedIconPath": "" }, diff --git a/src/pages/canteen/detail.vue b/src/pages/canteen/detail.vue index 01b2f3f..496d130 100644 --- a/src/pages/canteen/detail.vue +++ b/src/pages/canteen/detail.vue @@ -156,7 +156,7 @@ const updateFoodCart = async () => { } // 打开购物车 -const doVisibleCart = async () => (state.showCartDialog = true) +const doVisibleCart = () => (state.showCartDialog = true) // 购买 打开预订时间段选择对话框 const doBuy = async () => { diff --git a/src/pages/shop/components/product-car.vue b/src/pages/shop/components/product-cart.vue similarity index 83% rename from src/pages/shop/components/product-car.vue rename to src/pages/shop/components/product-cart.vue index d75f2fb..8873087 100644 --- a/src/pages/shop/components/product-car.vue +++ b/src/pages/shop/components/product-cart.vue @@ -1,13 +1,5 @@ diff --git a/src/pages/shop/components/product-sku.vue b/src/pages/shop/components/product-sku.vue index 2b88015..d2daab7 100644 --- a/src/pages/shop/components/product-sku.vue +++ b/src/pages/shop/components/product-sku.vue @@ -5,70 +5,61 @@ showFooter title="加入购物车" position="bottom" - size="60%" + size="70%" + bgColor="#ECF4F9" + :duration="100" @close="doClose" > - - - - - - - - {{ state.goodsDetail.productName }} - - - - 售价¥{{ retailPrice }} - 促销价¥{{ promotionPrice }} - - - 库存{{ state.goodsDetail.stock }} - 已售{{ state.goodsDetail.salesCount }} - + + + + 商品信息 + + + + {{ state.goodsDetail.productName }} + + 促销 ¥{{ state.selectedSku.promotionPrice }} + 原价 ¥{{ state.selectedSku.retailPrice }} + 内装数量:{{ state.selectedSku.packageNum }} + - - - 规格 + + + 包装单位 - - - - - - 购买数量 - - - - - - {{ String(state.goodsCount).padStart(2, "0") }} - - - + {{ v.spec + " " + v.unit }} - - + + + + + 购买数量 + + + + + {{ String(state.goodsCount).padStart(2, "0") }} + + + + + + @@ -77,38 +68,37 @@ import { shopApi } from "@/sheep/api" import { filePath } from "@/sheep/utils/file" import { computed, reactive, watch } from "vue" +import { hooks } from "@@/index" -const emit = defineEmits(["update:modelValue", "onAddToCar"]) +const emit = defineEmits(["update:modelValue", "onSkuAddToCart"]) + +const props = withDefaults( + defineProps<{ + modelValue: boolean + productData: any + }>(), + { + modelValue: false, + productData: {}, + }, +) -export type Props = { - modelValue: boolean - productData: any - onAddToCar?: () => void -} -const props = withDefaults(defineProps(), { - modelValue: false, - productData: {}, -}) const state = reactive({ goodsCount: 1, - selectedSku: {}, + selectedSku: { + retailPrice: 0, + promotionPrice: 0, + packageNum: 0, + }, goodsDetail: {}, }) -// 售价 -const retailPrice = computed(() => - state.selectedSku.retailPrice ? Number(state.selectedSku.retailPrice) * Number(state.goodsCount) : 0, -) -// 优惠价 -const promotionPrice = computed(() => - state.selectedSku.promotionPrice ? Number(state.selectedSku.promotionPrice) * Number(state.goodsCount) : 0, -) watch( () => props.modelValue, async (newValue) => { if (newValue) { // 获取商品详情 - const { data } = await shopApi.getSupermarketSpuDetail({ id: props.productData.productId }) + const { data } = await shopApi.getSupermarketSpuDetail({ id: props.productData.id }) state.goodsDetail = data if (data.skuList.length > 0) { state.selectedSku = state.goodsDetail.skuList[0] @@ -117,122 +107,37 @@ watch( }, ) -// SKU 列表 -// const skuList = computed(() => { -// let skuPrices = props.goodsInfo.skus; -// for (let price of skuPrices) { -// price.value_id_array = price.properties.map((item) => item.valueId); -// } -// return skuPrices; -// }); - -// 当前所选属性下,获取所有有库存的 SKU 们 -// function getCanUseSkuList() { -// let newSkus = []; -// for (let sku of skuList.value) { -// if (sku.stock <= 0) { -// continue; -// } -// let isOk = true; -// state.currentPropertyArray.forEach((propertyId) => { -// // propertyId 不为空,并且,这个 条 sku 没有被选中,则排除 -// if (propertyId.toString() !== "" && sku.value_id_array.indexOf(propertyId) < 0) { -// isOk = false; -// } -// }); -// if (isOk) { -// newSkus.push(sku); -// } -// } -// return newSkus; -// } - -// 选择规格 -function onSelectSku(skuItem: any) { - // const index = state.currentPropertyArray.findIndex((item: any) => item.id === skuItem.id); - // if (index === -1) { +// 选择规格/取消选择规格 +const onSelectSku = (skuItem: any) => { if (state.selectedSku.id === skuItem.id) { state.selectedSku = {} - } else { - state.selectedSku = skuItem + return } - // } else { - // state.currentPropertyArray.splice(index, 1); - // } - - // 清空已选择 - // let isChecked = true; // 选中 or 取消选中 - // if (state.currentPropertyArray[propertyId] !== undefined && state.currentPropertyArray[propertyId] === valueId) { - // 点击已被选中的,删除并填充 '' - // isChecked = false; - // state.currentPropertyArray.splice(propertyId, 1, ""); - // } else { - // 选中 - // state.currentPropertyArray[propertyId] = valueId; - // } - // 选中的 property 大类 - // let choosePropertyId: any = []; - // state.currentPropertyArray.forEach((currentPropertyId: string) => { - // if (currentPropertyId !== "") { - // // currentPropertyId 为空是反选 填充的 - // choosePropertyId.push(currentPropertyId); - // } - // }); - // 当前所选 property 下,所有可以选择的 SKU 们 - // let newSkuList = getCanUseSkuList(); - // 判断所有 property 大类是否选择完成 - // if (choosePropertyId.length === skuData.length && newSkuList.length) { - // newSkuList[0].name = state.selectedSku.goods_num || 1; - // state.selectedSku = newSkuList[0]; - // } else { - // state.selectedSku = {}; - // } - // if (choosePropertyId.length === skuData.value.length) { - // state.selectedSku = state.currentPropertyArray; - // } - // 改变 property 禁用状态 - // changeDisabled(isChecked, propertyId, valueId); + state.selectedSku = skuItem } // 加数量 const handleNumAdd = () => { - if (state.goodsCount >= state.goodsDetail.stock) { - return - } + if (state.goodsCount >= state.goodsDetail.stock) return uni.showToast({ title: "库存不足", icon: "none" }) state.goodsCount += 1 } // 减数量 const handleNumRemove = () => { - if (state.goodsCount <= 1) { - return - } + if (state.goodsCount <= 1) return state.goodsCount -= 1 } -// 点击加入购物车 -const handleClickAddToCar = async () => { - // 检查规格选择 - if (!state.selectedSku.id) { - uni.showToast({ - title: "请选择规格", - icon: "none", - duration: 1000, - }) - return - } +// 点击sku加入到购物车 +const handleSkuAddToCar = async () => { + // 检查包装单位选择 + if (!state.selectedSku.id) return uni.showToast({ title: "请选择包装单位", icon: "none" }) + // 检查库存 try { uni.showLoading({ title: "加载中", mask: true }) - const { code }: any = await shopApi.checkSpuStock({ - spuId: state.goodsDetail.id, - incrCount: state.goodsCount, - }) + const { code }: any = await shopApi.checkSpuStock({ spuId: state.goodsDetail.id, incrCount: state.goodsCount }) if (code != 0) { - return uni.showToast({ - title: "库存不足", - icon: "none", - duration: 1000, - }) + return uni.showToast({ title: "库存不足", icon: "none" }) } } catch (e) { console.error(e) @@ -240,22 +145,20 @@ const handleClickAddToCar = async () => { uni.hideLoading() } // 检查库存 - if (state.goodsDetail.stock === 0) { - uni.showToast({ - title: "库存不足", - icon: "none", - duration: 1000, - }) - return - } - emit("onAddToCar", { ...state.goodsDetail, productCount: state.goodsCount, productId: state.selectedSku.id }) + if (state.goodsDetail.stock === 0) return uni.showToast({ title: "库存不足", icon: "none" }) + + emit("onSkuAddToCart", { ...state.goodsDetail, productCount: state.goodsCount, productId: state.selectedSku.id }) } const doClose = () => { emit("update:modelValue", false) state.goodsCount = 1 - state.selectedSku = {} + state.selectedSku = { + retailPrice: 0, + promotionPrice: 0, + packageNum: 0, + } state.goodsDetail = {} } diff --git a/src/pages/shop/components/select-sku.vue b/src/pages/shop/components/select-sku.vue deleted file mode 100644 index 3eeb8c3..0000000 --- a/src/pages/shop/components/select-sku.vue +++ /dev/null @@ -1,447 +0,0 @@ - - - - - diff --git a/src/pages/shop/detail.vue b/src/pages/shop/detail.vue index 222a29b..c2e677b 100644 --- a/src/pages/shop/detail.vue +++ b/src/pages/shop/detail.vue @@ -71,7 +71,7 @@ - - {{ v.name }} - + {{ v.name }} - - - - + + @@ -118,7 +117,7 @@ - +