继续完善购物逻辑闭环,consumer模块完成度80%
This commit is contained in:
@@ -1,17 +1,28 @@
|
||||
<!-- 支付页面 -->
|
||||
<template>
|
||||
<view class="payment-page">
|
||||
<!-- 顶部栏 -->
|
||||
<view class="payment-header">
|
||||
<text class="back-btn" @click="goBack">‹</text>
|
||||
<text class="header-title">收银台</text>
|
||||
</view>
|
||||
|
||||
<view class="payment-content">
|
||||
<!-- 支付金额 -->
|
||||
<view class="amount-section">
|
||||
<text class="amount-label">支付金额</text>
|
||||
<text class="amount-value">¥{{ amount.toFixed(2) }}</text>
|
||||
<!-- 价格明细 -->
|
||||
<view class="price-detail-section">
|
||||
<text class="section-title">价格明细</text>
|
||||
<view class="price-detail">
|
||||
<view class="price-row">
|
||||
<text class="price-label">商品总价</text>
|
||||
<text class="price-value">¥{{ productAmount.toFixed(2) }}</text>
|
||||
</view>
|
||||
<view class="price-row">
|
||||
<text class="price-label">运费</text>
|
||||
<text class="price-value">+¥{{ deliveryFee.toFixed(2) }}</text>
|
||||
</view>
|
||||
<view v-if="discountAmount > 0" class="price-row">
|
||||
<text class="price-label">优惠减免</text>
|
||||
<text class="price-value discount">-¥{{ discountAmount.toFixed(2) }}</text>
|
||||
</view>
|
||||
<view class="price-row total">
|
||||
<text class="price-label">应付金额</text>
|
||||
<text class="price-value total-price">¥{{ amount.toFixed(2) }}</text>
|
||||
</view>
|
||||
</view>
|
||||
<text class="order-no">订单号: {{ orderNo }}</text>
|
||||
</view>
|
||||
|
||||
@@ -98,7 +109,8 @@
|
||||
</template>
|
||||
|
||||
<script setup lang="uts">
|
||||
import { ref, onMounted, watch } from 'vue'
|
||||
import { ref, onMounted, watch, computed, onUnmounted } from 'vue'
|
||||
import { onLoad, onBackPress } from '@dcloudio/uni-app'
|
||||
// import { supabase as supa } from '@/components/supadb/aksupainstance.uts'
|
||||
|
||||
type PaymentMethodType = {
|
||||
@@ -119,6 +131,11 @@ const isPaying = ref<boolean>(false)
|
||||
const showPassword = ref<boolean>(false)
|
||||
const password = ref<string>('')
|
||||
|
||||
// 价格相关变量
|
||||
const productAmount = ref<number>(0) // 商品总价
|
||||
const deliveryFee = ref<number>(0) // 运费
|
||||
const discountAmount = ref<number>(0) // 优惠减免
|
||||
|
||||
// 生命周期
|
||||
onMounted(() => {
|
||||
const pages = getCurrentPages()
|
||||
@@ -133,11 +150,65 @@ onMounted(() => {
|
||||
if (options.amount) {
|
||||
amount.value = parseFloat(options.amount)
|
||||
}
|
||||
|
||||
// 获取传递的价格详情
|
||||
if (options.productAmount) {
|
||||
productAmount.value = parseFloat(options.productAmount)
|
||||
}
|
||||
if (options.deliveryFee) {
|
||||
deliveryFee.value = parseFloat(options.deliveryFee)
|
||||
}
|
||||
if (options.discountAmount) {
|
||||
discountAmount.value = parseFloat(options.discountAmount)
|
||||
}
|
||||
|
||||
// 如果没有传详情,尝试根据总价估算(兼容旧逻辑,但优先使用传参)
|
||||
if (!options.productAmount && amount.value > 0) {
|
||||
calculatePriceDetails(amount.value)
|
||||
}
|
||||
|
||||
loadPaymentMethods()
|
||||
loadUserBalance()
|
||||
})
|
||||
|
||||
// 监听返回操作(包含系统返回键和导航栏返回按钮)
|
||||
onBackPress((options) => {
|
||||
// 如果是通过代码主动调用 navigateBack 返回,则允许
|
||||
if (options.from === 'navigateBack') {
|
||||
return false
|
||||
}
|
||||
|
||||
// 否则拦截返回,显示确认弹窗
|
||||
goBack()
|
||||
return true
|
||||
})
|
||||
|
||||
// 更新本地存储中的订单状态
|
||||
const updateOrderInStorage = (status: number) => {
|
||||
try {
|
||||
// 尝试从 'orders' 读取 (checkout页面写入的key)
|
||||
const ordersStr = uni.getStorageSync('orders')
|
||||
let orders: any[] = []
|
||||
if (ordersStr) {
|
||||
orders = JSON.parse(ordersStr as string) as any[]
|
||||
}
|
||||
|
||||
const index = orders.findIndex((o: any) => o.id === orderId.value)
|
||||
if (index !== -1) {
|
||||
orders[index].status = status
|
||||
orders[index].payment_status = status === 2 ? 1 : 0 // 2=待发货(已支付), 1=待支付(未支付)
|
||||
orders[index].updated_at = new Date().toISOString()
|
||||
// 确保更新的是 'orders' key
|
||||
uni.setStorageSync('orders', JSON.stringify(orders))
|
||||
console.log('订单状态已更新到Storage (orders):', orderId.value, status)
|
||||
} else {
|
||||
console.warn('在Storage (orders)中未找到订单:', orderId.value)
|
||||
}
|
||||
} catch (e) {
|
||||
console.error('更新订单状态失败', e)
|
||||
}
|
||||
}
|
||||
|
||||
// 加载订单信息
|
||||
const loadOrderInfo = async () => {
|
||||
try {
|
||||
@@ -274,6 +345,46 @@ const getPayButtonText = (): string => {
|
||||
return texts[selectedMethod.value] || '确认支付'
|
||||
}
|
||||
|
||||
// 减少商品库存
|
||||
const reduceStock = (orderId: string) => {
|
||||
try {
|
||||
// 读取订单
|
||||
const ordersStr = uni.getStorageSync('orders')
|
||||
if (!ordersStr) return
|
||||
|
||||
const orders = JSON.parse(ordersStr as string) as any[]
|
||||
const order = orders.find((o: any) => o.id === orderId)
|
||||
|
||||
if (!order || !order.items) return
|
||||
|
||||
// 读取商品库(这里假设商品库也在本地,实际项目中通常在服务器端处理)
|
||||
// 模拟:如果有本地商品缓存,则更新
|
||||
/*
|
||||
const productsStr = uni.getStorageSync('products')
|
||||
if (productsStr) {
|
||||
const products = JSON.parse(productsStr as string) as any[]
|
||||
let hasChange = false
|
||||
|
||||
order.items.forEach((item: any) => {
|
||||
const product = products.find((p: any) => p.id === item.product_id)
|
||||
if (product && product.stock >= item.quantity) {
|
||||
product.stock -= item.quantity
|
||||
hasChange = true
|
||||
console.log(`商品 ${product.name} 库存减少 ${item.quantity}, 剩余 ${product.stock}`)
|
||||
}
|
||||
})
|
||||
|
||||
if (hasChange) {
|
||||
uni.setStorageSync('products', JSON.stringify(products))
|
||||
}
|
||||
}
|
||||
*/
|
||||
console.log('模拟扣减库存成功', order.items)
|
||||
} catch (e) {
|
||||
console.error('扣减库存失败', e)
|
||||
}
|
||||
}
|
||||
|
||||
// 确认支付
|
||||
const confirmPayment = async () => {
|
||||
if (isPaying.value) return
|
||||
@@ -309,6 +420,11 @@ const confirmPayment = async () => {
|
||||
await new Promise(resolve => setTimeout(resolve, 2000))
|
||||
|
||||
// 更新订单状态
|
||||
updateOrderInStorage(2) // 2: 待发货(已支付)
|
||||
|
||||
// 扣减库存
|
||||
reduceStock(orderId.value)
|
||||
|
||||
/* const { error } = await supa
|
||||
.from('orders')
|
||||
.update({
|
||||
@@ -335,6 +451,9 @@ const confirmPayment = async () => {
|
||||
duration: 2000
|
||||
})
|
||||
|
||||
// 发布订单更新事件,让profile页面可以刷新数据
|
||||
uni.$emit('orderUpdated', { orderId: orderId.value, status: 2 }) // 2: 待发货
|
||||
|
||||
// 跳转到支付成功页面
|
||||
setTimeout(() => {
|
||||
uni.redirectTo({
|
||||
@@ -471,9 +590,91 @@ const forgotPassword = () => {
|
||||
})
|
||||
}
|
||||
|
||||
// 计算价格明细
|
||||
const calculatePriceDetails = (totalAmount: number) => {
|
||||
// 模拟计算各项费用
|
||||
// 假设商品总价占总金额的80%,运费占10%,优惠减免占10%
|
||||
productAmount.value = totalAmount * 0.8
|
||||
deliveryFee.value = totalAmount * 0.1
|
||||
discountAmount.value = totalAmount * 0.1
|
||||
|
||||
// 确保总和等于应付金额
|
||||
const calculatedTotal = productAmount.value + deliveryFee.value - discountAmount.value
|
||||
if (Math.abs(calculatedTotal - totalAmount) > 0.01) {
|
||||
// 调整商品总价以匹配应付金额
|
||||
productAmount.value = totalAmount + discountAmount.value - deliveryFee.value
|
||||
}
|
||||
}
|
||||
|
||||
// 在组件卸载时移除返回键监听
|
||||
onUnmounted(() => {
|
||||
// uni.offBackPress() 在uni-app中不需要手动移除
|
||||
})
|
||||
|
||||
// 返回
|
||||
const goBack = () => {
|
||||
uni.navigateBack()
|
||||
uni.showModal({
|
||||
title: '取消支付',
|
||||
content: '确定要取消支付吗?取消后订单将保存到待支付订单中',
|
||||
confirmText: '取消支付',
|
||||
cancelText: '继续支付',
|
||||
success: async (res) => {
|
||||
if (res.confirm) {
|
||||
// 用户确认取消支付,更新订单状态为待支付
|
||||
await cancelPayment()
|
||||
} else {
|
||||
// 用户选择继续支付,留在当前页面
|
||||
return
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// 取消支付,更新订单状态
|
||||
const cancelPayment = async () => {
|
||||
try {
|
||||
// 这里应该调用API更新订单状态为待支付(status: 1)
|
||||
// 模拟更新订单状态
|
||||
/* const { error } = await supa
|
||||
.from('orders')
|
||||
.update({
|
||||
status: 1, // 待支付
|
||||
updated_at: new Date().toISOString()
|
||||
})
|
||||
.eq('id', orderId.value)
|
||||
|
||||
if (error !== null) {
|
||||
console.error('更新订单状态失败:', error)
|
||||
uni.showToast({
|
||||
title: '操作失败',
|
||||
icon: 'none'
|
||||
})
|
||||
return
|
||||
} */
|
||||
|
||||
// 更新本地存储
|
||||
updateOrderInStorage(orderId.value, 1) // 1: 待支付
|
||||
|
||||
// 发布订单更新事件,让profile页面可以刷新数据
|
||||
uni.$emit('orderUpdated', { orderId: orderId.value, status: 1 })
|
||||
|
||||
uni.showToast({
|
||||
title: '已保存到待支付订单',
|
||||
icon: 'success'
|
||||
})
|
||||
|
||||
// 延迟返回,让用户看到提示
|
||||
setTimeout(() => {
|
||||
uni.navigateBack()
|
||||
}, 1500)
|
||||
|
||||
} catch (err) {
|
||||
console.error('取消支付异常:', err)
|
||||
uni.showToast({
|
||||
title: '操作失败',
|
||||
icon: 'none'
|
||||
})
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
@@ -511,32 +712,58 @@ const goBack = () => {
|
||||
overflow-y: auto;
|
||||
}
|
||||
|
||||
.amount-section {
|
||||
/* 价格明细部分 */
|
||||
.price-detail-section {
|
||||
background-color: #ffffff;
|
||||
padding: 40px 20px;
|
||||
text-align: center;
|
||||
padding: 20px 15px;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
.amount-label {
|
||||
display: block;
|
||||
font-size: 14px;
|
||||
color: #666666;
|
||||
.price-detail {
|
||||
padding: 15px;
|
||||
background-color: #f8f9fa;
|
||||
border-radius: 8px;
|
||||
margin-bottom: 15px;
|
||||
}
|
||||
|
||||
.amount-value {
|
||||
display: block;
|
||||
font-size: 36px;
|
||||
font-weight: bold;
|
||||
.price-row {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
padding: 8px 0;
|
||||
}
|
||||
|
||||
.price-row.total {
|
||||
border-top: 1px solid #e5e5e5;
|
||||
margin-top: 8px;
|
||||
padding-top: 15px;
|
||||
}
|
||||
|
||||
.price-label {
|
||||
font-size: 14px;
|
||||
color: #666666;
|
||||
}
|
||||
|
||||
.price-value {
|
||||
font-size: 14px;
|
||||
color: #333333;
|
||||
}
|
||||
|
||||
.price-value.discount {
|
||||
color: #4caf50;
|
||||
}
|
||||
|
||||
.price-value.total-price {
|
||||
font-size: 18px;
|
||||
color: #ff4757;
|
||||
margin-bottom: 10px;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.order-no {
|
||||
display: block;
|
||||
font-size: 12px;
|
||||
color: #999999;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.methods-section {
|
||||
@@ -758,4 +985,4 @@ const goBack = () => {
|
||||
font-size: 24px;
|
||||
color: #333333;
|
||||
}
|
||||
</style>
|
||||
</style>
|
||||
|
||||
Reference in New Issue
Block a user