摸大红支持购物车多选一起结账

下单支持多商品行快照与一次支付;支付后整单复制文案,前台提供购物车加购与结账。
This commit is contained in:
yml2213
2026-07-16 20:58:39 +08:00
parent e241607535
commit 183351a297
17 changed files with 1159 additions and 117 deletions
@@ -13,6 +13,8 @@ import {
startMohongPayment,
type MohongProduct,
} from '@/features/mohong/api/mohong'
import MohongCartPanel from '@/features/mohong/components/MohongCartPanel.vue'
import { useMohongCart } from '@/features/mohong/composables/useMohongCart'
import { useSessionStore } from '@/stores/session'
import { formatCent } from '@/shared/utils/money'
import { readError } from '@/shared/utils/error'
@@ -20,6 +22,7 @@ import { readError } from '@/shared/utils/error'
const route = useRoute()
const router = useRouter()
const session = useSessionStore()
const { addProduct, openCart, totalCount: cartCount } = useMohongCart()
const product = ref<MohongProduct | null>(null)
const loading = ref(true)
const quantity = ref(1)
@@ -91,6 +94,19 @@ async function ensureAuthReady() {
return true
}
function handleAddCart() {
if (!product.value) return
if (!canBuy.value) {
showToast({ message: '库存不足', icon: 'cross' })
return
}
const result = addProduct(product.value, quantity.value)
showToast({
message: result.message,
icon: result.ok ? 'passed' : 'cross',
})
}
async function handleBuy() {
if (!product.value || submitting.value) return
if (!(await ensureAuthReady())) return
@@ -107,11 +123,11 @@ async function handleBuy() {
const payment = await startMohongPayment(order.id, payWay)
if (payment.paid || payment.status === 'paid') {
showToast({ message: '支付成功', icon: 'passed' })
await router.push(`/mohong/orders/${order.id}`)
await router.push(`/m/mohong/orders/${order.id}`)
return
}
await openMobilePaymentCashier(payment, async () => {
await router.push(`/mohong/orders/${order.id}`)
await router.push(`/m/mohong/orders/${order.id}`)
})
} catch (error) {
showToast({ message: readError(error, '下单失败'), icon: 'cross' })
@@ -164,9 +180,16 @@ async function handleBuy() {
</section>
<div class="buy-bar">
<button type="button" class="cart-entry" @click="openCart">
<van-icon name="shopping-cart-o" :size="20" />
<em v-if="cartCount > 0">{{ cartCount }}</em>
</button>
<div class="sum">
合计 <strong>¥{{ totalPrice }}</strong>
</div>
<van-button plain round color="#ff6a00" :disabled="!canBuy" @click="handleAddCart">
加购
</van-button>
<van-button
type="primary"
color="#ff6a00"
@@ -175,12 +198,17 @@ async function handleBuy() {
:disabled="!canBuy"
@click="handleBuy"
>
{{ canBuy ? '立即购买' : '暂时缺货' }}
{{ canBuy ? '购买' : '缺货' }}
</van-button>
</div>
</template>
<van-empty v-else description="商品不存在" />
<MohongCartPanel
mobile
:select-pay-way="() => payWaySelect.select()"
:start-cashier="(payment, onPaid) => openMobilePaymentCashier(payment, onPaid)"
/>
<MobilePayWaySelectPopup
v-model:show="payWaySelect.visible.value"
@choose="payWaySelect.choose"
@@ -297,22 +325,51 @@ async function handleBuy() {
bottom: 0;
display: flex;
align-items: center;
justify-content: space-between;
gap: 12px;
padding: 10px 16px calc(10px + env(safe-area-inset-bottom));
gap: 8px;
padding: 10px 12px calc(10px + env(safe-area-inset-bottom));
background: #fff;
border-top: 1px solid #eef1f5;
}
.cart-entry {
position: relative;
width: 40px;
height: 40px;
border: 0;
border-radius: 50%;
background: #fff7ed;
color: #ff6a00;
display: grid;
place-items: center;
flex-shrink: 0;
}
.cart-entry em {
position: absolute;
top: -2px;
right: -2px;
min-width: 16px;
height: 16px;
padding: 0 4px;
border-radius: 999px;
background: #ef4444;
color: #fff;
font-size: 10px;
font-style: normal;
line-height: 16px;
text-align: center;
}
.sum {
flex: 1;
color: #6b7a90;
font-size: 13px;
min-width: 0;
}
.sum strong {
color: #ff6a00;
font-size: 20px;
font-size: 18px;
margin-left: 4px;
}
.buy-bar :deep(.van-button) {
min-width: 128px;
min-width: 72px;
flex-shrink: 0;
}
</style>