feat:共富

This commit is contained in:
ctw committed 2025-10-29 16:14:00 +08:00
1 parent 0fe72f08ae
commit 8f5e1d0641
4 files changed
+87 -45

No files matched your search

+1 -1
View File
@@ -110,7 +110,7 @@ const search = () => {
const doGoodsDetail = (id: string) => {
if (!id) return uni.showToast({ title: "商品id不存在", icon: "none" })
uni.navigateTo({
url: `/pages/prosperity-shop/goods-detail?id=${id}`,
url: `/pages/prosperity-shop/goods-detail?id=${id}&merchantId=${state.params.merchantId}`,
})
}
</script>
+77 -42
View File
@@ -1,7 +1,7 @@
<template>
<crud-layout mainIsScroll bg="/static/page/blue-bg.png" @scroll="onScroll">
<view class="w-full h-400rpx relative">
<image :src="filePath(state.detail.images)" class="w-full h-full bg-#eeeeee" mode="aspectFill" />
<image :src="filePath(mchDetail.images)" class="w-full h-full bg-#eeeeee" mode="aspectFill" />
<view class="absolute w-full h-full top-0 left-0" :style="filterStyle"></view>
</view>
<view
@@ -12,19 +12,20 @@
<image class="w-36rpx h-36rpx" src="@/static/page/shop-goods-search.png" />
<text v-if="scrollDetail.scrollTop > 30" class="bg-#eeeeee44 whitespace-nowrap overflow-hidden second-text-26 ml-2">搜索商品</text>
</view>
<view v-if="state.detail.id" class="card p-20rpx mt-10rpx mx-20rpx">
<view class="w-full sub-text-32 truncate">{{ state.detail.name }}</view>
<view v-if="mchDetail.id" class="card p-20rpx mt-10rpx mx-20rpx">
<view class="w-full sub-text-32 truncate">{{ mchDetail.name }}</view>
<text class="sub-text-24 c-#0094ff! px-2 bg-#0094ff22 rounded-2 mr-4">营业</text>
<text class="second-text-24 truncate mt-1">营业人 {{ state.detail.contactName }}·{{ state.detail.contactPhone }}</text>
<text class="second-text-24 truncate mt-1">营业人 {{ mchDetail.contactName }}·{{ mchDetail.contactPhone }}</text>
<view class="second-text-26 mt-1">
<image class="w-24rpx h-24rpx mr-1" src="@/static/page/address.svg" />
<text>{{ state.detail.address }}</text>
<text>{{ mchDetail.address }}</text>
</view>
<marquee class="second-text-24 mt-1">{{ state.detail.remark }}</marquee>
<marquee class="second-text-24 mt-1">{{ mchDetail.remark }}</marquee>
</view>
<view class="flex mt-2">
<scroll-view scroll-y class="menu w-200rpx mb-20rpx bg-#f6f6f6 pl-20rpx" style="height: calc(100vh - 420rpx)">
<scroll-view scroll-y class="menu w-200rpx mb-20rpx bg-#f6f6f6 pl-20rpx" style="height: calc(100vh - 300rpx)">
<view
class="menu_item flex-row-center"
v-for="(v, i) in state.category"
@@ -52,42 +53,47 @@
<text class="second-text-26 mr-2">单位 {{ v.unit }}</text>
<text class="second-text-26">库存 {{ v.totalStock }}</text>
</view>
<view>
<template v-if="v.priceType == '2'">
<text class="second-text-28 line-through mr-1">
<text class="text-26rpx">¥</text>
<text class="font-bold">{{ displayPrice(v.originalPrice, "") }}</text>
</text>
<text class="color-red">
<text class="text-26rpx">¥</text>
<text class="text-32rpx font-bold">{{ displayPrice(v.spuPrice, "").split(".")[0] }}.</text>
<text class="text-30rpx font-bold">{{ displayPrice(v.spuPrice, "").split(".")[1] }}</text>
</text>
</template>
<template v-else>
<text class="color-red">
<text class="text-26rpx">¥</text>
<text class="text-32rpx font-bold">{{ displayPrice(v.minPrice, "").split(".")[0] }}.</text>
<text class="text-30rpx font-bold">{{ displayPrice(v.minPrice, "").split(".")[1] }}</text>
</text>
</template>
<text class="view-clip px-1 text-18rpx c-white bg-red ml-1 rounded-r-1 rounded-lt-1">到手价</text>
<view class="flex items-center justify-between">
<view class="flex items-center">
<template v-if="v.priceType == '2'">
<text class="second-text-28 line-through mr-1">
<text class="text-26rpx">¥</text>
<text>{{ displayPrice(v.originalPrice, "") }}</text>
</text>
<text class="color-red">
<text class="text-26rpx">¥</text>
<text class="text-32rpx">{{ displayPrice(v.spuPrice, "").split(".")[0] }}.</text>
<text class="text-30rpx">{{ displayPrice(v.spuPrice, "").split(".")[1] }}</text>
</text>
</template>
<template v-else>
<text class="color-red">
<text class="text-26rpx">¥</text>
<text class="text-32rpx">{{ displayPrice(v.minPrice, "").split(".")[0] }}.</text>
<text class="text-30rpx">{{ displayPrice(v.minPrice, "").split(".")[1] }}</text>
</text>
</template>
<text class="view-clip px-1 text-20rpx c-white bg-red ml-1 rounded-r-1 rounded-lt-1">到手价</text>
</view>
<view class="second-text-24 px-2 py-2rpx bg-#0094ff c-white! border-rd-8" @tap.stop="doSelectSku(v.id)">选规格</view>
</view>
</view>
</view>
</scroll-view>
<view v-else class="mx-auto mt-10 second-text-28">暂无商品</view>
</view>
<template #main-bottom>
<view class="z-200 p-x-30rpx p-y-30rpx bg-white">
<product-total :totPrice="totPrice" :totCount="totalCount" @doContainer="" @submit="doBuy" />
</view>
</template>
</crud-layout>
<product-sku v-model="state.showSkuDialog" :goodsInfo="state.goodsDetail" @onSkuAddToCart="onSkuAddToCart" />
</template>
<script setup lang="ts">
import { reactive } from "vue"
import { computed, reactive } from "vue"
import { prosperityShopApi } from "@/sheep/api"
import { onLoad } from "@dcloudio/uni-app"
import { filePath } from "@/sheep/utils/file"
@@ -96,44 +102,53 @@ import { displayPrice } from "@/sheep/utils/formatMoney"
import useShopDetailScroll from "./use-shop-detail-scroll"
import useCartBuy from "./use-cart-buy"
import ProductTotal from "./components/product-total.vue"
import ProductSku from "./components/product-sku.vue"
const state = reactive<any>({
id: "",
detail: {},
mchId: "",
mchDetail: {},
category: [],
curCategoryIndex: 0,
goodsList: [],
goodsDetail: {},
showSkuDialog: false,
})
const mchDetail = computed(() => state.mchDetail)
const { scrollDetail, onScroll, filterStyle, searchStyle } = useShopDetailScroll()
const { totPrice, totalCount, doBuy } = useCartBuy()
const { totPrice, totalCount, skuAddToCart, doBuy } = useCartBuy()
onLoad(async (option: any) => {
if (!option.id) return uni.showToast({ title: "参数错误", icon: "error" })
const { id } = option
if (!id) return uni.showToast({ title: "参数错误", icon: "error" })
state.mchId = id
uni.showLoading({ title: "加载中..." })
state.id = option.id
await getShopDetail(option.id)
await getGoodsCategoryTree(option.id)
await getMchDetail(id)
await getGoodsCategoryTree(id)
await getGoodsList()
uni.hideLoading()
})
const getShopDetail = async (id: string) => {
// 获取商户详情
const getMchDetail = async (id: string) => {
const { code, data, msg } = await prosperityShopApi.getShopDetail(id)
if (code != 0) return uni.showToast({ title: msg || "超市详情获取失败", icon: "none" })
state.detail = data
state.mchDetail = data
}
// 获取商品分类
const getGoodsCategoryTree = async (id: string) => {
const { code, data, msg } = await prosperityShopApi.getGoodsCategoryTree({ merchantId: id })
if (code != 0) return uni.showToast({ title: msg || "商品分类获取失败", icon: "none" })
state.category = treeToList(data) ?? []
}
// 获取商品列表
const getGoodsList = async () => {
const params = {
current: 1,
size: 99999,
merchantId: state.id,
merchantId: state.mchId,
categoryId: state.category[state.curCategoryIndex].id,
}
const { code, data, msg } = await prosperityShopApi.getGoodsList(params)
@@ -141,6 +156,7 @@ const getGoodsList = async () => {
state.goodsList = data?.records ?? []
}
// 切换分类
const doCategory = async (index: number) => {
if (state.curCategoryIndex == index) return
state.curCategoryIndex = index
@@ -149,16 +165,35 @@ const doCategory = async (index: number) => {
uni.hideLoading()
}
// 去查看商品详情
const doGoodsDetail = (id: string) => {
if (!id || !state.id) return uni.showToast({ title: "商品id不存在", icon: "none" })
if (!id || !state.mchId) return uni.showToast({ title: "id错误", icon: "none" })
uni.navigateTo({
url: `/pages/prosperity-shop/goods-detail?id=${id}&merchantId=${state.id}`,
url: `/pages/prosperity-shop/goods-detail?id=${id}&merchantId=${state.mchId}`,
})
}
// 去搜索商品
const goSearch = () => {
if (!state.detail.id) return uni.showToast({ title: "超市id不存在", icon: "none" })
uni.navigateTo({ url: `/pages/prosperity-shop/goods-search?merchantId=${state.detail.id}` })
if (!state.mchDetail.id) return uni.showToast({ title: "超市id不存在", icon: "none" })
uni.navigateTo({ url: `/pages/prosperity-shop/goods-search?merchantId=${state.mchDetail.id}` })
}
// 选规格
const doSelectSku = async (id: string) => {
if (!id) return uni.showToast({ title: "商品id不存在", icon: "none" })
uni.showLoading({ title: "加载中..." })
const { code, data, msg } = await prosperityShopApi.getGoodsDetail(id)
if (code != 0) return uni.showToast({ title: msg || "商品详情获取失败", icon: "none" })
uni.hideLoading()
state.goodsDetail = data
state.showSkuDialog = true
}
// 选择sku加入到购物车
const onSkuAddToCart = (sku: any) => {
skuAddToCart({ ...state.goodsDetail, ...sku, productId: sku.skuId }, state.mchId)
state.showSkuDialog = false
}
</script>
+8 -1
View File
@@ -1,5 +1,5 @@
import { router } from "@/sheep"
import { orderApi, payApi } from "@/sheep/api"
import { orderApi } from "@/sheep/api"
import { useProsperityCartStore } from "@/sheep/stores/prosperity-cart"
import { isEmpty } from "radash"
@@ -13,6 +13,12 @@ export default function useCartBuy() {
// 购物车商品列表
const cartList = cartStore.cartList
// 选择sku确认加入到购物车
const skuAddToCart = (sku: any, merchantId: string) => {
cartStore.addGoodsItemToCart(sku)
cartStore.updateShopCart(merchantId)
}
// 获取购物车列表
const getShopCart = async (merchantId: string) => {
await cartStore.getShopCart(merchantId)
@@ -63,6 +69,7 @@ export default function useCartBuy() {
totalCount,
cartList,
getShopCart,
skuAddToCart,
addProductCount,
removeProductCount,
doBuy,
@@ -31,7 +31,7 @@ export default function useShopDetailScroll() {
const scrollY = scrollDetail.value.scrollTop
const scrollHeight = scrollDetail.value.scrollHeight
const scrollWidth = scrollDetail.value.scrollWidth
const calcWidth = Math.min((scrollY / scrollHeight) * scrollWidth, scrollWidth)
const calcWidth = Math.min(((scrollY / scrollHeight) * scrollWidth) / 2, scrollWidth)
if (isNaN(calcWidth)) return { width: `${minWidth}%` }
if (calcWidth < 2) return { width: `${calcWidth + minWidth}%` }
return {