feat:共富商城购物车

This commit is contained in:
weiwei committed 2025-10-28 14:20:14 +08:00
1 parent a2ecdbc187
commit 467dcc637d
20 files changed
+429 -122

No files matched your search

+4 -4
View File
@@ -20,15 +20,15 @@ VITE_OAUTH2_APP_CLIENT='mini:mini'
# VITE_APP_DEV_SERVICE = https://stgl.pj.gov.cn/api # 域名线上
#VITE_APP_DEV_SERVICE = http://59.202.170.152:81/api # 信创线上
# VITE_APP_DEV_SERVICE = http://192.168.101.174:9999 # 邓-本地
VITE_APP_DEV_SERVICE = http://127.0.0.1:9999 # 邓-本地
; VITE_APP_DEV_SERVICE = http://123.157.250.162:8089/api # 测试线上
# VITE_APP_DEV_SERVICE = http://127.0.0.1:9999 # 邓-本地
VITE_APP_DEV_SERVICE = http://123.157.250.162:8089/api # 测试线上
# --------------------------- 开发环境 图片访问基础地址 ---------------------------
# VITE_IMAGE_DEV_PATH = https://stgl.pj.gov.cn/api # 域名线上
#VITE_IMAGE_DEV_PATH = http://59.202.170.152:81/api # 信创线上
# VITE_IMAGE_DEV_PATH = http://192.168.101.174:9999 # 邓-本地
VITE_IMAGE_DEV_PATH = http://127.0.0.1:9999
; VITE_IMAGE_DEV_PATH = http://123.157.250.162:8089/api # 测试线上
# VITE_IMAGE_DEV_PATH = http://127.0.0.1:9999
VITE_IMAGE_DEV_PATH = http://123.157.250.162:8089/api # 测试线上
# --------------------------- 生产环境 api地址 ----------------------------------
VITE_APP_PROD_SERVICE = https://stgl.pj.gov.cn/api # 域名线上
+7
View File
@@ -198,6 +198,13 @@
"navigationBarTitleText": "商品分类管理",
"disableScroll": true
}
},
{
"path": "goods-cart",
"style": {
"navigationBarTitleText": "购物车",
"disableScroll": true
}
}
]
},
+2 -2
View File
@@ -55,7 +55,7 @@ const getDetail = async () => {
// 获取购物车信息
const getFoodCart = async () => {
const { data } = await foodApi.getShopCar({ merchantId: state.detailId, hardType: "CANTEEN" })
const { data } = await orderApi.getShopCar({ merchantId: state.detailId, hardType: "CANTEEN" })
state.cartList = data ?? []
if (isEmpty(state.cartList)) {
state.foodList.forEach((v: any) => {
@@ -154,7 +154,7 @@ const updateFoodCart = async () => {
})
if (isEmpty(list)) return
const _pa = { merchantId: state.detailId, list: list, hardType: "CANTEEN" }
const { data, code }: any = await foodApi.updateShopCar(_pa)
const { data, code }: any = await orderApi.updateShopCar(_pa)
if (code == 0) await getFoodCart()
}
@@ -4,15 +4,9 @@
<tm-sheet :margin="[0]">
<tm-alert :border="['2']" :borderColor="['#89c0ff']" :darkBorderColor="['#3b5066']">访客邀约请填写以下信息</tm-alert>
<tm-form @submit="onsubmit" v-model="form" :rules="rules" direction="vertical">
<!-- <tm-form-item name="name" label="访客姓名">
<tm-input color="transparent" v-model.trim="form.name" placeholder="请输入真实姓名" />
</tm-form-item> -->
<tm-form-item name="mobile" label="访客手机号">
<tm-input color="transparent" v-model.trim="form.mobile" placeholder="请输入访客手机号" />
</tm-form-item>
<!-- <tm-form-item name="companyName" label="来访公司名称">
<tm-input color="transparent" v-model.trim="form.companyName" placeholder="来访公司名称" />
</tm-form-item> -->
<tm-form-item name="vStartDate" label="拜访开始时间 >" @click="startDatePicker('vStartDate')">
<template #label>
<span>拜访开始时间 </span>
@@ -39,30 +33,6 @@
color="transparent"
/>
</tm-form-item>
<!-- <tm-form-item name="deptId" label="拜访部门">
<tm-drawer :show-close="true" :show-footer="true" size="auto" title="请选择拜访部门">
<template #trigger>
<tm-input :modelValue="form.deptId" placeholder="请选择拜访部门" style="pointer-events: none" disabled color="transparent">
<template v-slot:rightIcon>
<tm-icon name="arrow-right-s-line"></tm-icon>
</template>
</tm-input>
</template>
<tm-text color="#999999"></tm-text>
</tm-drawer>
</tm-form-item> -->
<!-- <tm-form-item name="reasonValue" label="拜访原因">
<tm-picker @confirm="reasonPickerConfirm" :list="visitorReasonList">
<tm-input :modelValue="form.reasonText" placeholder="请选择拜访原因" style="pointer-events: none" disabled color="transparent">
<template #rightIcon>
<tm-icon name="arrow-right-s-line"></tm-icon>
</template>
</tm-input>
</tm-picker>
</tm-form-item> -->
<tm-form-item name="isOtherPeople" label="是否可随行人员" direction="horizontal" labelWidth="500">
<tm-switch v-model="form.isOtherPeople" />
</tm-form-item>
@@ -133,49 +103,20 @@ interface FormData {
}
const form = reactive<FormData>({
// name: "",
mobile: "",
// companyName: "",
vStartDate: "",
vEndDate: "",
// reasonValue: "",
// reasonText: "",
isOtherPeople: true,
isDrive: true,
})
const showDatePicker = ref(false)
const curDateType = ref("")
const confirmModalShow = ref(false)
// const visitorReasonList = ref<{ title: string; id: string }[]>([])
// onLoad(() => {
// getVisitorReasonList()
// })
// 获取拜访原因列表
// const getVisitorReasonList = async () => {
// const { code, data } = await invitationApi.getDictListByType("1")
// if (code == 0 && data) {
// visitorReasonList.value = data.map((item: any) => ({ title: item.label, id: item.value }))
// return
// }
// visitorReasonList.value = []
// }
// 来访原因选择器确认
// const reasonPickerConfirm = (ids: string) => {
// const reason = visitorReasonList.value.find((item) => item.id === ids[0])
// form.reasonText = reason?.title || ""
// form.reasonValue = reason?.id || ""
// }
const rules: Record<string, TM.FORM_RULE[]> = {
// name: [{ required: true, message: "姓名2到5个字符", rule: /^.{2,5}$/ }],
mobile: [{ required: true, message: "请输入正确的手机号", rule: /^(?:(?:\+|00)86)?1\d{10}$/ }],
// companyName: [{ required: true, message: "请输入来访公司名称" }],
vStartDate: [{ required: true, message: "请选择拜访开始时间" }],
vEndDate: [{ required: true, message: "请选择拜访离开时间" }],
// reasonValue: [{ required: true, message: "请选择拜访原因" }],
}
// 开始日期选择
@@ -237,13 +178,9 @@ const confirmSubmit = async () => {
// 重置表单
const resetForm = () => {
Object.assign(form, {
// name: "",
mobile: "",
// companyName: "",
vstartDate: "",
vendDate: "",
// reasonValue: "",
// reasonText: "",
isOtherPeople: true,
isDrive: true,
})
+3 -3
View File
@@ -138,7 +138,7 @@ import { reactive, nextTick } from "vue"
import { onLoad, onShow } from "@dcloudio/uni-app"
import { isEmpty } from "radash"
import { hooks, router } from "@@/index"
import { foodApi, merchantApi, payApi, shopApi } from "@@/api"
import { foodApi, merchantApi, orderApi, payApi, shopApi } from "@@/api"
import { filePath } from "@@/utils/file"
// import ProductRow from "./components/product-row.vue"
// import ProductCart from "./components/product-cart.vue"
@@ -196,7 +196,7 @@ const getDetail = async () => {
}
const getShopCart = async () => {
const { data } = await foodApi.getShopCar({ merchantId: state.merchantId, hardType: "SUPERMARKET" })
const { data } = await orderApi.getShopCar({ merchantId: state.merchantId, hardType: "SUPERMARKET" })
state.cartList = data ?? []
state.totPrice = state.cartList.map((v) => Number(v.totalPrice)).reduce((pre, next) => pre + next, 0)
state.totCount = state.cartList.map((v) => v.productCount).reduce((pre, next) => pre + next, 0)
@@ -293,7 +293,7 @@ const updateShopCart = async () => {
productId: v.productId,
}
})
const { code }: any = await foodApi.updateShopCar({ merchantId: state.merchantId, list, hardType: "SUPERMARKET" })
const { code }: any = await orderApi.updateShopCar({ merchantId: state.merchantId, list, hardType: "SUPERMARKET" })
if (code == 0) await getShopCart()
}
+4 -4
View File
@@ -44,15 +44,17 @@
<script setup lang="ts">
import ProductTotal from "./components/product-total.vue"
import { isEmpty } from "radash"
import { useCartStore } from "@/sheep/stores/cart"
import { useOnlineCartStore } from "@/sheep/stores/online-cart"
import { payApi } from "@/sheep/api"
import { hooks, router } from "@/sheep"
import { filePath } from "@/sheep/utils/file"
const cartStore = useCartStore()
const cartStore = useOnlineCartStore()
// 点击提交订单
const doBuy = async () => {
if (isEmpty(cartStore.cart)) return uni.showToast({ title: "请至少购买一件商品", icon: "none" })
uni.showModal({
title: "提示",
content: "是否确定购买",
@@ -67,8 +69,6 @@ const doBuy = async () => {
// 提交订单
const submitPay = async () => {
try {
if (isEmpty(cartStore.cart)) return uni.showToast({ title: "请至少购买一件商品", icon: "none" })
uni.showLoading({ title: "支付中...", mask: false })
const { code, msg }: any = await payApi.createSupermarketOrder({ carParentId: cartStore.cart[0].parentCarId, hardType: "SUPERMARKET" })
if (code != 0) throw new Error(msg)
+2 -2
View File
@@ -4,11 +4,11 @@ import { onLoad } from "@dcloudio/uni-app"
import { onlineShopApi } from "@@/api"
import { filePath } from "@/sheep/utils/file"
import ProductSku from "./components/product-sku.vue"
import { useCartStore } from "@/sheep/stores/cart"
import { useOnlineCartStore } from "@/sheep/stores/online-cart"
import { hooks, router } from "@/sheep"
import { displayPrice } from "@/sheep/utils/formatMoney"
const cartStore = useCartStore()
const cartStore = useOnlineCartStore()
const state = reactive<any>({
detailId: null,
@@ -0,0 +1,152 @@
<template>
<tm-drawer z-index="800" v-model:show="modelValue" showFooter showClose title="加入购物车" size="70%" bgColor="#ECF4F9" @close="doClose">
<view class="flex-col card py-20rpx px-30rpx mb-20rpx">
<view class="prefix_title mb-15rpx">商品信息</view>
<view class="flex items-center">
<image
class="size-160rpx bg-#eeeeee rounded-1 mr-2"
:src="filePath(goodsInfo.coverImage)"
mode="aspectFill"
@tap.stop="goodsInfo.coverImage && usePreviewImage(filePath(goodsInfo.coverImage))"
/>
<view class="flex-1 overflow-hidden">
<view class="sub-text-32 truncate">{{ goodsInfo.title }}</view>
<view class="second-text-32 c-red!">
<text>¥{{ displayPrice(state.selectedSku.price, "") || 0 }}</text>
<!-- <text class="m-l-20rpx second-text-28 line-through">¥{{ displayPrice(state.selectedSku.retailPrice, "") || 0 }}</text> -->
</view>
<view class="second-text-26">库存 {{ state.selectedSku.stock || 0 }}</view>
<view class="second-text-26">
已选择 {{ `${state.selectedSku.skuName || "未选择"} / ${state.selectedSku.weightG + "克"},数量 ${state.goodsCount}` }}
</view>
</view>
</view>
</view>
<!-- 包装单位 -->
<view class="flex-col card p-y-20rpx p-x-30rpx mb-20rpx">
<view class="prefix_title mb-15rpx">包装单位</view>
<view class="flex flex-wrap">
<view
class="text-center rounded-2 mr-4 mb-2 py-2 px-3 text-28 bg-#F2F2F2 c-black border border-solid border-#E5E5E5"
:class="{ 'bg-#0094ff! c-white!': state.selectedSku.id === v.id }"
v-for="v in goodsInfo.skuList"
:key="v.id"
@click="onSelectSku(v)"
>
{{ v.skuName + " / " + v.weightG + "克" }}
</view>
</view>
</view>
<!-- 购买数量 -->
<view class="flex-col card p-y-20rpx p-x-30rpx mb-20rpx">
<view class="prefix_title mb-15rpx">购买数量</view>
<view class="flex items-center justify-between">
<view class="second-text-28">库存 {{ state.selectedSku.stock }}</view>
<view class="flex">
<view class="flex-row-center size-40rpx rounded-full border-1px border-solid border-color-#0094ff" @tap.stop="handleNumRemove">
<view class="iconfont icon-a--" />
</view>
<view class="sub-text-28 m-x-20rpx">{{ String(state.goodsCount).padStart(2, "0") }}</view>
<view class="flex-row-center size-40rpx rounded-full bg-#0094ff" @tap.stop="handleNumAdd">
<view class="font-size-40rpx color-white iconfont icon-a-" />
</view>
</view>
</view>
</view>
<template #footer>
<button
class="mx-12 rounded-3 bg-#0094ff sub-text-30 py-2 c-white! active:bg-#0094ff99"
:class="{ 'bg-#0094ff77!': Object.keys(state.selectedSku).length === 0 }"
@tap="handleSkuAddToCart"
>
加入购物车
</button>
</template>
</tm-drawer>
</template>
<script setup lang="ts">
import { reactive, watch } from "vue"
import { filePath } from "@/sheep/utils/file"
import { usePreviewImage } from "@/sheep/hooks/use-img"
import { isEmpty } from "radash"
import { displayPrice } from "@/sheep/utils/formatMoney"
const modelValue = defineModel("modelValue", { default: false })
const emit = defineEmits<{ (e: "onSkuAddToCart", val: object): void }>()
const props = defineProps({
goodsInfo: {
type: Object,
default: () => ({}),
},
})
const state = reactive<any>({
selectedSku: {},
goodsCount: 1,
})
watch(modelValue, (newValue) => {
if (newValue && !isEmpty(props.goodsInfo)) {
state.selectedSku = props.goodsInfo.skuList[0]
}
})
// 选择规格/取消选择规格
const onSelectSku = (skuItem: any) => {
if (state.selectedSku.id == skuItem.id) {
state.selectedSku = {}
return
}
state.selectedSku = skuItem
}
// 加数量
const handleNumAdd = () => {
if (state.goodsCount >= state.selectedSku.stock) return uni.showToast({ title: "库存不足", icon: "none" })
state.goodsCount += 1
}
// 减数量
const handleNumRemove = () => {
if (state.goodsCount <= 1) return
state.goodsCount -= 1
}
// 点击sku加入到购物车
const handleSkuAddToCart = async () => {
if (!state.selectedSku.id) return uni.showToast({ title: "请选择包装单位", icon: "none" })
// 检查库存
// try {
// uni.showLoading({ title: "加载中", mask: true })
// const { code }: any = await shopApi.checkSpuStock({ spuId: props.goodsInfo.id, incrCount: state.goodsCount })
// if (code != 0) return uni.showToast({ title: "库存不足", icon: "none" })
// } catch (e) {
// console.error(e)
// } finally {
// uni.hideLoading()
// }
// 检查库存
if (props.goodsInfo.stock === 0 || Number(state.goodsCount) > Number(state.selectedSku.stock))
return uni.showToast({ title: "库存不足", icon: "none" })
emit("onSkuAddToCart", {
spuId: props.goodsInfo.id,
skuId: state.selectedSku.id,
productCount: state.goodsCount,
...state.selectedSku,
})
}
// 关闭
const doClose = () => {
modelValue.value = false
state.selectedSku = {}
state.goodsCount = 1
}
</script>
@@ -0,0 +1,33 @@
<template>
<view class="flex-row items-center justify-between" @tap="doContainer">
<view class="flex-row-center">
<view class="flex-row-center size-80rpx rounded-full bg-#0094ff">
<view class="color-white! iconfont icon-biaoqianlanicon_gouwuche-xuanzhong" />
</view>
<view class="flex-col m-l-30rpx">
<view class="second-text-36 color-#f63a36!">¥ {{ hooks.useMoney(props.totPrice) }}</view>
<view class="sub-text-28">共{{ props.totCount }}件</view>
</view>
</view>
<view class="bg-#0094ff p-x-30rpx p-y-20rpx text-center rounded-40rpx sub-text-30 color-white!" @tap.stop="doBuy">提交订单</view>
</view>
</template>
<script setup lang="ts">
import { hooks } from "@@/index"
const emit = defineEmits(["submit", "doContainer"])
export type Props = {
totPrice: number
totCount: number
}
const props = withDefaults(defineProps<Props>(), {
totPrice: 0,
totCount: 0,
})
const doBuy = () => emit("submit")
const doContainer = () => emit("doContainer")
</script>
+90
View File
@@ -0,0 +1,90 @@
<template>
<crud-layout title="购物车" mainIsScroll bg="/static/page/blue-bg.png">
<view class="h-20rpx"></view>
<view v-if="cartStore.totalCount > 0" class="flex-row card px-15rpx py-25rpx mb-20rpx" v-for="(v, i) in cartStore.cart" :key="i">
<image class="size-160rpx rounded-12rpx mr-20rpx bg-#eeeeee" :src="filePath(v.productPic)" mode="aspectFill" />
<view class="flex-1 overflow-hidden">
<view class="sub-text-30 truncate">{{ 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 v-else class="flex-col justify-center items-center pt-300rpx">
<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.totalCount" @doContainer="" @submit="doBuy" />
</view>
</template>
</crud-layout>
</template>
<script setup lang="ts">
import ProductTotal from "./components/product-total.vue"
import { isEmpty } from "radash"
import { useOnlineCartStore } from "@/sheep/stores/online-cart"
import { payApi } from "@/sheep/api"
import { hooks, router } from "@/sheep"
import { filePath } from "@/sheep/utils/file"
const cartStore = useOnlineCartStore()
// 点击提交订单
const doBuy = async () => {
if (isEmpty(cartStore.cart)) return uni.showToast({ title: "请至少购买一件商品", icon: "none" })
uni.showModal({
title: "提示",
content: "是否确定购买",
confirmColor: "#0094ff",
success: async (res) => {
if (!res.confirm) return
submitPay()
},
})
}
// 提交订单
const submitPay = async () => {
try {
uni.showLoading({ title: "支付中...", mask: false })
const { code, msg }: any = await payApi.createSupermarketOrder({ carParentId: cartStore.cart[0].parentCarId, hardType: "SUPERMARKET" })
if (code != 0) throw new Error(msg)
uni.showToast({ title: "支付成功", icon: "none" })
router.jump("/pages/tabbar/order")
} catch (error: any) {
uni.showToast({ title: error.message, icon: "none" })
} finally {
uni.hideLoading()
}
}
const add = async (productId: string) => {
await cartStore.addProductCount(productId)
}
const remove = async (productId: string) => {
await cartStore.removeProductCount(productId)
}
</script>
@@ -49,7 +49,20 @@
<view class="mt-20rpx overflow-auto text-26rpx!" v-html="state.detail.description"></view>
</view>
<view class="h-30rpx" />
<template #main-bottom>
<view class="flex-row justify-between items-center my-4 mx-12">
<tm-badge bg-color="red" :label="2">
<view class="flex-col-center" @tap="goCart">
<image class="w-60rpx h-60rpx" src="/static/icon/cart.png" />
<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="state.showSkuDialog = true">加入购物车</view>
</view>
</template>
</crud-layout>
<product-sku v-model="state.showSkuDialog" :goodsInfo="state.detail" @onSkuAddToCart="onSkuAddToCart" />
</template>
<script setup lang="ts">
@@ -58,10 +71,13 @@ import { reactive } from "vue"
import { prosperityShopApi } from "@/sheep/api"
import { filePath } from "@/sheep/utils/file"
import { displayPrice } from "@/sheep/utils/formatMoney"
import ProductSku from "./components/product-sku.vue"
import { hooks, router } from "@/sheep"
const state = reactive<any>({
id: "",
detail: {},
showSkuDialog: false,
})
onLoad(async (option: any) => {
if (!option.id) return uni.showToast({ title: "参数错误", icon: "error" })
@@ -76,6 +92,20 @@ const getGoodsDetail = async (id: string) => {
if (code != 0) return uni.showToast({ title: msg || "商品详情获取失败", icon: "none" })
state.detail = data
}
// 选择sku确认加入到购物车
const onSkuAddToCart = (sku: any) => {
console.log(sku)
// cartStore.addGoodsItemToCart({ ...state.detail, ...sku, productId: sku.skuId })
// cartStore.updateShopCart()
state.showSkuDialog = false
}
const goCart = async () => {
const isLogin = await hooks.useCheckLogin()
if (isLogin) router.jump("/pages/prosperity-shop/goods-cart")
}
</script>
<style scoped lang="scss">
+2 -8
View File
@@ -14,14 +14,8 @@
</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 class="sub-text-24 mt-1">
<text class="c-#0094ff! mr-20rpx px-2 bg-#0094ff22 rounded-2">{{ state.detail.status == "0" ? "开业中" : "未开业" }}</text>
<text class="rounded-2 c-#0094ff px-2 bg-#0094ff22 rounded-2">{{ state.detail.businessHours }}</text>
</view>
<view class="second-text-24 truncate mt-1">
<text class="mr-20rpx">营业人 {{ state.detail.contactName }}·{{ state.detail.contactPhone }}</text>
<text class="mr-20rpx">许可 {{ state.detail.licenseNo }}</text>
</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>
<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>
+1 -1
View File
@@ -44,7 +44,7 @@
<view class="second-text-26 text-center mb-2 mt-10">
<text>联系热线:</text>
<text @click="doPhone('18837698126')">18837698126</text>
<text @click="doPhone('18367908152')">18367908152</text>
&nbsp;
<text @click="doPhone('15657370065')">15657370065</text>
</view>
+2 -2
View File
@@ -143,10 +143,10 @@ import { isEmpty } from "radash"
import { filePath } from "@@/utils/file"
import { merchantApi, onlineShopApi } from "@@/api"
import { hooks, router } from "@@/index"
import { useCartStore } from "@/sheep/stores/cart"
import { useOnlineCartStore } from "@/sheep/stores/online-cart"
import treeToList from "@/sheep/utils/tree-to-list"
const cartStore = useCartStore()
const cartStore = useOnlineCartStore()
const state = reactive<any>({
params: {
+11 -16
View File
@@ -57,20 +57,15 @@
<view class="card p-20rpx mb-20rpx" v-for="(v, i) in pageHook.list" :key="i" @tap="toDetail(v)">
<view class="flex">
<image class="w-150rpx h-150rpx bg-#eeeeee rounded-12rpx" :src="filePath(v.images)" mode="aspectFill" />
<image class="w-160rpx h-160rpx bg-#eeeeee rounded-12rpx" :src="filePath(v.images)" mode="aspectFill" />
<view class="ml-20rpx flex-1 overflow-hidden">
<view class="sub-text-30 truncate">{{ v.name }}</view>
<view class="second-text-26 truncate">
<text class="mr-20rpx">{{ v.contactName }}</text>
<text class="mr-20rpx">
<view class="sub-text-32 truncate">{{ v.name }}222222222222222222222222 </view>
<view class="second-text-26 flex justify-between my-6rpx">
<view>
<image class="w-24rpx h-24rpx mr-1" src="@/static/page/phone.svg" />
<text @tap.stop="doPhone(v.contactPhone)">{{ v.contactPhone }}</text>
</text>
<text>{{ v.email }}</text>
</view>
<view>
<text class="c-#0094ff! sub-text-26 px-2 bg-#0094ff22 rounded-2 mr-2">营业</text>
<text class="c-#0094ff! sub-text-26 px-2 bg-#0094ff22 rounded-2">{{ v.businessHours }}</text>
</view>
<text class="c-#0094ff! sub-text-26 px-2 bg-#0094ff22 rounded-2">营业</text>
</view>
<view class="second-text-26">
<image class="w-24rpx h-24rpx mr-1" src="@/static/page/address.svg" />
@@ -83,21 +78,21 @@
<view class="w-160rpx flex-col items-center mr-20rpx" v-for="(pV, pI) in v.featuredProducts" :key="pI">
<image class="w-160rpx h-160rpx rounded-12rpx bg-#eeeeee" :src="filePath(pV.coverImage)" mode="aspectFill" />
<view class="w-full mt-4rpx sub-text-24 truncate">{{ pV.title }}</view>
<view class="w-full flex justify-between pr-1">
<view class="w-full flex justify-between">
<text class="main-text-26 color-red!">
<text class="text-22rpx">¥</text>
<text>{{ pV.priceType == "1" ? displayPrice(pV.minPrice, "") : displayPrice(pV.spuPrice, "") }}</text>
</text>
<text class="sub-text-24">{{ pV.unit || "" }}</text>
</view>
<view class="w-full flex justify-between pr-1">
<text class="second-text-24 line-through">
<template v-if="pV.priceType == '2'">
<text class="text-22rpx">¥</text>
<text>{{ displayPrice(pV.originalPrice, "") }}</text>
</template>
</text>
<text class="second-text-24">库存{{ pV.totalStock }}</text>
</view>
<view class="w-full flex justify-between second-text-24">
<text>{{ pV.unit || "" }}</text>
<text>库存{{ pV.totalStock }}</text>
</view>
</view>
</view>
-12
View File
@@ -23,18 +23,6 @@ export default {
method: "GET",
params,
}),
getShopCar: (params: any) =>
request({
url: `/hard/hard-car/app/mch-detail`,
method: "GET",
params,
}),
updateShopCar: (data: any) =>
request({
url: `/hard/hard-car/app/save-or-upload`,
method: "POST",
data,
}),
checkSpuStock: (params) => {
return request({
url: "/canteen/canteenOnlineSpu/app/checkSpuStock",
+12
View File
@@ -25,6 +25,18 @@ export default {
method: "GET",
params,
}),
getShopCar: (params: any) =>
request({
url: `/hard/hard-car/app/mch-detail`,
method: "GET",
params,
}),
updateShopCar: (data: any) =>
request({
url: `/hard/hard-car/app/save-or-upload`,
method: "POST",
data,
}),
/**
* 预约时间列表
*/
@@ -1,14 +1,14 @@
import { defineStore } from "pinia"
import { foodApi } from "../api"
import { orderApi } from "../api"
export const useCartStore = defineStore("cartStore", {
export const useOnlineCartStore = defineStore("onlineCartStore", {
state: () => ({
cart: JSON.parse(uni.getStorageSync("onlineShopCart") || "[]"),
shopMerchantId: uni.getStorageSync("onlineShopMerchantId") || "",
}),
getters: {
totalCount(state) {
return state.cart.reduce((prev: string, cur: any) => {
return state.cart.reduce((prev: number, cur: { productCount: number }) => {
return prev + cur.productCount
}, 0)
},
@@ -58,7 +58,7 @@ export const useCartStore = defineStore("cartStore", {
await this.getShopCart()
},
async getShopCart() {
const { data } = await foodApi.getShopCar({ merchantId: this.shopMerchantId, hardType: "SUPERMARKET" })
const { data } = await orderApi.getShopCar({ merchantId: this.shopMerchantId, hardType: "SUPERMARKET" })
this.saveShopCart(data ?? [])
},
async updateShopCart() {
@@ -70,7 +70,7 @@ export const useCartStore = defineStore("cartStore", {
productId: v.productId,
}
})
const { code }: any = await foodApi.updateShopCar({ merchantId: this.shopMerchantId, list, hardType: "SUPERMARKET" })
const { code }: any = await orderApi.updateShopCar({ merchantId: this.shopMerchantId, list, hardType: "SUPERMARKET" })
if (code == 0) return await this.getShopCart()
uni.showToast({ title: "更新购物车失败", icon: "none" })
},
+69
View File
@@ -0,0 +1,69 @@
import { defineStore } from "pinia"
import { orderApi } from "../api"
export const useProsperityCartStore = defineStore("prosperityCartStore", {
state: () => ({
cartList: [],
}),
getters: {
totalCount(state) {
return state.cartList.reduce((prev: number, cur: { productCount: number }) => {
return prev + cur.productCount
}, 0)
},
totPrice(state) {
return state.cartList
.map((item: any) => Number(item.totalPrice))
.reduce((prev: number, cur: number) => prev + cur, 0)
.toFixed(2)
},
},
actions: {
addGoodsItemToCart(goodsItem: any) {
const findResult = this.cartList.find((item: any) => {
return item.productId === goodsItem.productId
})
if (!findResult) {
this.cartList.unshift(goodsItem)
} else {
findResult.productCount++
}
uni.setStorageSync("onlineShopCart", JSON.stringify(this.cartList))
},
async addProductCount(productId: string) {
this.cartList.forEach((item: any) => {
if (item.productId === productId) {
item.productCount++
}
})
await this.updateShopCart()
await this.getShopCart()
},
async removeProductCount(productId: string) {
this.cartList.forEach((item: any) => {
if (item.productId === productId) {
item.productCount--
}
})
await this.updateShopCart()
await this.getShopCart()
},
async getShopCart(merchantId: string) {
const { data } = await orderApi.getShopCar({ merchantId, hardType: "SUPERMARKET" })
this.cartList = data
},
async updateShopCart() {
const list = this.cartList
.filter((v) => v.productCount && v.productCount > 0)
.map((v) => {
return {
productCount: v.productCount,
productId: v.productId,
}
})
const { code }: any = await orderApi.updateShopCar({ merchantId: this.shopMerchantId, list, hardType: "SUPERMARKET" })
if (code == 0) return await this.getShopCart()
uni.showToast({ title: "更新购物车失败", icon: "none" })
},
},
})
Binary file not shown.

After

Width:  |  Height:  |  Size: 3.4 KiB