feat: 基本实现拆单收货

This commit is contained in:
2026-07-29 15:53:23 +08:00
parent c443109869
commit 1b45f9dac6
92 changed files with 3223 additions and 22968 deletions
@@ -1,5 +1,7 @@
<template>
<main class="checkout-page">
<div>
<joyful-selection-checkout-skeleton v-if="loading" />
<main v-else class="checkout-page">
<van-nav-bar title="确认订单" left-arrow @click-left="$router.back()" />
<section class="address-card" @click="$router.push({ path: '/joyful-selection/address', query: { from: 'checkout' } })">
@@ -50,7 +52,8 @@
</section>
<van-submit-bar :price="goodsAmount" button-text="提交订单" @submit="onSubmit" />
</main>
</main>
</div>
</template>
<script>
@@ -60,12 +63,17 @@ import { useCartStore } from '@/store/cart'
import { useUserStore } from '@/store/user'
import { readAddresses, readChosenAddressId } from '../../address/address-data'
import { createOrderNo, savePaymentInfo } from '../payment/payment-data'
import JoyfulSelectionCheckoutSkeleton from '@/skeleton-view/joyful-selection/order/checkout/index.vue'
const CHECKOUT_ITEMS_KEY = 'joyful-selection-checkout-items'
export default {
name: 'JoyfulSelectionCheckout',
components: {
JoyfulSelectionCheckoutSkeleton
},
data: () => ({
loading: true,
remark: '',
goods: [],
showAllGoods: false,
@@ -74,7 +82,7 @@ export default {
}),
computed: {
...mapState(useCartStore, ['items']),
...mapState(useUserStore, ['supplierId', 'token', 'userId']),
...mapState(useUserStore, ['supplierId', 'userId']),
visibleGoods() {
return this.showAllGoods ? this.goods : this.goods.slice(0, 3)
},
@@ -89,12 +97,15 @@ export default {
this.loadCart()
this.goods = this.getCheckoutGoods()
this.loadAddress()
this.$nextTick(() => {
this.loading = false
})
},
activated() {
this.loadAddress()
},
methods: {
...mapActions(useCartStore, ['loadCart']),
...mapActions(useCartStore, ['loadCart', 'removeItems']),
...mapActions(useUserStore, ['fetchBridgeToken']),
getCheckoutGoods() {
const storedItems = this.readCheckoutItems()
@@ -136,7 +147,7 @@ export default {
try {
await this.fetchBridgeToken()
if (!this.supplierId || !this.token || !this.userId) {
if (!this.supplierId || !this.userId) {
throw new Error('供应商授权信息不完整,请重新进入商城')
}
@@ -144,7 +155,6 @@ export default {
const data = await postFunction('order-create', {
supplierId: this.supplierId,
userId: this.userId,
token: this.token,
orderNo,
amount: this.goodsAmount,
goods: this.goods
@@ -158,6 +168,8 @@ export default {
receiverTel: this.maskTel(this.chosenAddress.tel || ''),
goods: this.goods
})
this.clearSubmittedCartItems()
this.$router.push('/joyful-selection/payment')
} catch (error) {
console.warn('提交待支付订单失败', error)
@@ -165,6 +177,19 @@ export default {
} finally {
this.submitting = false
}
},
clearSubmittedCartItems() {
if (this.$route.query.source !== 'cart') {
return
}
const cartIds = this.goods.map(item => item.cartId).filter(Boolean)
if (cartIds.length) {
this.removeItems(cartIds)
}
sessionStorage.removeItem(CHECKOUT_ITEMS_KEY)
}
}
}
@@ -1,5 +1,7 @@
<template>
<main class="success-page">
<div>
<joyful-selection-payment-success-skeleton v-if="loading" />
<main v-else class="success-page">
<van-nav-bar title="支付成功" left-arrow @click-left="$router.back()" />
<section class="success-card">
@@ -20,15 +22,21 @@
<van-button round type="danger" @click="$router.push('/joyful-selection/home')">继续购物</van-button>
</footer>
</section>
</main>
</main>
</div>
</template>
<script>
import { readPaymentInfo, formatYuan } from '../payment/payment-data'
import JoyfulSelectionPaymentSuccessSkeleton from '@/skeleton-view/joyful-selection/order/payment-success/index.vue'
export default {
name: 'JoyfulSelectionPaymentSuccess',
components: {
JoyfulSelectionPaymentSuccessSkeleton
},
data: () => ({
loading: true,
paymentInfo: {},
paidAt: ''
}),
@@ -49,6 +57,9 @@ export default {
created() {
this.paymentInfo = readPaymentInfo()
this.paidAt = this.formatTime(new Date())
this.$nextTick(() => {
this.loading = false
})
},
methods: {
formatTime(date) {
@@ -1,5 +1,7 @@
<template>
<main class="payment-page">
<div>
<joyful-selection-payment-skeleton v-if="loading" />
<main v-else class="payment-page">
<van-nav-bar title="确认支付" left-arrow @click-left="$router.back()" />
<section class="amount-card">
@@ -61,7 +63,8 @@
</footer>
</article>
</van-popup>
</main>
</main>
</div>
</template>
<script>
@@ -69,17 +72,22 @@ import { mapActions, mapState } from 'pinia'
import { postFunction } from '@/api/supplied-service'
import { useUserStore } from '@/store/user'
import { readPaymentInfo, formatYuan } from './payment-data'
import JoyfulSelectionPaymentSkeleton from '@/skeleton-view/joyful-selection/order/payment/index.vue'
export default {
name: 'JoyfulSelectionPayment',
components: {
JoyfulSelectionPaymentSkeleton
},
data: () => ({
loading: true,
payType: 'points',
showConfirm: false,
submitting: false,
paymentInfo: {}
}),
computed: {
...mapState(useUserStore, ['pointsBalance', 'supplierId', 'token']),
...mapState(useUserStore, ['pointsBalance', 'supplierId']),
amountText() {
return formatYuan(this.paymentInfo.amount)
},
@@ -110,9 +118,12 @@ export default {
},
created() {
this.paymentInfo = readPaymentInfo()
this.loading = true
this.fetchUserPoints().catch(error => {
console.warn('查询用户积分失败', error)
this.$toast(error.message || '查询用户积分失败')
}).finally(() => {
this.loading = false
})
},
methods: {
@@ -129,13 +140,12 @@ export default {
try {
await this.fetchBridgeToken()
if (!this.supplierId || !this.token || !this.paymentInfo.orderNo) {
if (!this.supplierId || !this.paymentInfo.orderNo) {
throw new Error('订单支付信息不完整,请重新提交订单')
}
await postFunction('order-pay', {
supplierId: this.supplierId,
token: this.token,
orderId: this.paymentInfo.orderNo,
amount: this.paymentInfo.amount,
totalPrice: Number(this.amountText),