464 lines
9.2 KiB
Plaintext
464 lines
9.2 KiB
Plaintext
<template>
|
|
<view class="order-confirm-page">
|
|
<!-- 全新方案:纯 CSS 手动构建的骨架屏 -->
|
|
<view v-if="loading" class="skeleton-wrapper">
|
|
<view class="skeleton-card" style="height: 180rpx;"></view>
|
|
<view class="skeleton-card" style="height: 220rpx;"></view>
|
|
<view class="skeleton-card" style="height: 150rpx;"></view>
|
|
<view class="skeleton-card" style="height: 200rpx;"></view>
|
|
</view>
|
|
|
|
<!-- 页面实际内容 -->
|
|
<view v-else class="page-content">
|
|
|
|
<scroll-view class="page-scroll" scroll-y>
|
|
<view class="page-container">
|
|
<!-- 1. 收货地址 -->
|
|
<view class="card address-card" @click="selectAddress">
|
|
<view v-if="orderInfo.address==''" class="no-address">
|
|
<up-icon name="plus" color="#fa6400" size="20"></up-icon>
|
|
<text>请选择收货地址</text>
|
|
</view>
|
|
<view v-else class="has-address">
|
|
<view class="user-info">
|
|
<text class="name">{{ getAddInfo().name}}</text>
|
|
<text class="phone">{{ getAddInfo().phone }}</text>
|
|
</view>
|
|
<text class="address-text">{{ getAddInfo().province}}{{ getAddInfo().city}}{{ getAddInfo().region}}{{ getAddInfo().address}}</text>
|
|
</view>
|
|
<up-icon name="arrow-right" color="#999" size="16"></up-icon>
|
|
</view>
|
|
|
|
<!-- 2. 商品信息 -->
|
|
<view class="card product-card">
|
|
<view class="image-placeholder product-image">
|
|
<image :src="orderInfo.img" style="width: 100%; height: 100%; border-radius: 10rpx;" mode=""></image>
|
|
</view>
|
|
<view class="product-info">
|
|
<text class="name">{{ orderInfo.goodsName }}</text>
|
|
<text class="quantity" style="margin-top: 10rpx;">数量: x{{ orderInfo.count }}</text>
|
|
</view>
|
|
</view>
|
|
|
|
<!-- 3. 配送与备注 -->
|
|
<!-- <view class="card options-card" style="padding: 20rpx 0;">
|
|
<view class="" style="width: 100%; border: solid 1rpx black; height: 40rpx;">
|
|
|
|
</view>
|
|
</view> -->
|
|
|
|
<!-- 4. 费用明细 -->
|
|
<view class="card price-card">
|
|
<view class="price-row">
|
|
<text class="label">商品总计</text>
|
|
<text class="value">{{ orderInfo.amount }} 积分</text>
|
|
</view>
|
|
</view>
|
|
</view>
|
|
</scroll-view>
|
|
|
|
<!-- 底部操作栏 -->
|
|
<view class="bottom-bar">
|
|
<view class="total-summary">
|
|
<text class="total-points">{{ orderInfo.amount }} 积分</text>
|
|
</view>
|
|
<button class="submit-btn" @click="submitOrder">提交订单</button>
|
|
</view>
|
|
</view>
|
|
|
|
<u-popup :show="show" @close="show = false" closeable>
|
|
<view class="" style="width: 100%; height: 800rpx;">
|
|
<view class=""
|
|
style="width: 100; text-align: center; font-size: 28rpx; flex-wrap: 600; height: 80rpx; line-height: 80rpx;">
|
|
|
|
</view>
|
|
<view class="" style="width: 90%; margin: 0 auto; margin-top: 20rpx;">
|
|
<view style="width:100%; padding: 5rpx; border: solid 1rpx #e7e7e7; border-radius: 10rpx; margin-bottom: 20rpx; padding: 20rpx;"
|
|
v-for="(item, index) in addList" :key="index" :style="addressID==item.addressId?'border: solid 1rpx var(--nav-mian);':''" @click="GxorderAdd(item.addressId)">
|
|
<view class="has-address">
|
|
<view class="user-info">
|
|
<text class="name">{{item.name}}</text>
|
|
<text class="phone">{{ item.phone }}</text>
|
|
</view>
|
|
<text class="address-text">{{ item.province}}{{ item.city}}{{ item.region}}{{ item.address}}</text>
|
|
</view>
|
|
</view>
|
|
</view>
|
|
</view>
|
|
</u-popup>
|
|
|
|
|
|
|
|
|
|
</view>
|
|
</template>
|
|
|
|
<script setup lang="ts">
|
|
import { ref, reactive } from 'vue';
|
|
import { onLoad, onShow } from '@dcloudio/uni-app';
|
|
import { Service } from "@/Service/Service";
|
|
import { vpGoodsService } from '@/Service/vp/vpGoodsService'
|
|
import { vpAddressService } from '@/Service/vp/vpAddressService'
|
|
|
|
|
|
|
|
|
|
const loading = ref<boolean>(true);
|
|
|
|
let orderId = ref<string>('')
|
|
|
|
let orderInfo = ref<any>({
|
|
goodsName: '',
|
|
img: '',
|
|
count: 1,
|
|
amount: 0,
|
|
|
|
address: '',
|
|
way: '',
|
|
wayName: ''
|
|
})
|
|
|
|
let addList = ref<Array<any>>([])
|
|
|
|
let addressID = ref<string>('')
|
|
|
|
let show = ref<boolean>(false)
|
|
|
|
onLoad((options) => {
|
|
orderId.value = options.orderId
|
|
GetData()
|
|
|
|
});
|
|
onShow(() => {
|
|
|
|
getAddList()
|
|
|
|
});
|
|
|
|
// 获取收货地址
|
|
const getAddList = () => {
|
|
vpAddressService.GetUserAddressList().then(res => {
|
|
if (res.code == 0) {
|
|
addList.value = res.data.list
|
|
if(orderInfo.value.address== '' && addList.value.length>0){
|
|
|
|
GxorderAdd(addList.value[0].addressId)
|
|
}
|
|
} else {
|
|
Service.Msg(res.msg)
|
|
}
|
|
})
|
|
}
|
|
|
|
|
|
|
|
// 获取数据
|
|
const GetData = () => {
|
|
vpGoodsService.GetOrderInfo(orderId.value).then(res => {
|
|
if (res.code == 0) {
|
|
loading.value = false;
|
|
orderInfo.value = res.data.orderInfo
|
|
if(orderInfo.value.address != ''){
|
|
addressID.value = JSON.parse(orderInfo.value.address).addressId
|
|
}
|
|
getAddList()
|
|
} else {
|
|
Service.Msg(res.msg)
|
|
}
|
|
})
|
|
|
|
|
|
}
|
|
|
|
// 选择收货地址
|
|
const selectAddress = () => {
|
|
if(orderInfo.value.address==''){
|
|
|
|
Service.GoPage('/pages/userFunc/addAddress')
|
|
}else{
|
|
show.value = true
|
|
}
|
|
};
|
|
|
|
// 修改收货地址
|
|
const GxorderAdd = (addId:string) =>{
|
|
|
|
addressID.value = addId
|
|
vpGoodsService.UpdateOrderAddress(orderId.value,addId).then(res=>{
|
|
if(res.code==0){
|
|
orderInfo.value.address = JSON.stringify(addList.value.find(data => data.addressId == addressID.value))
|
|
}else{
|
|
Service.Msg(res.msg)
|
|
}
|
|
})
|
|
}
|
|
|
|
|
|
const getAddInfo = () =>{
|
|
let obj = {
|
|
address:'',
|
|
province:'',
|
|
city:'',
|
|
region:'',
|
|
name:'',
|
|
phone:'',
|
|
addressId:''
|
|
}
|
|
|
|
if(orderInfo.value.address != ''){
|
|
return JSON.parse(orderInfo.value.address)
|
|
}else if(addressID.value!=''){
|
|
obj = addList.value.find(data => data.addressId == addressID.value)
|
|
return obj
|
|
}else{
|
|
return obj
|
|
}
|
|
}
|
|
|
|
|
|
const submitOrder = () => {
|
|
|
|
vpGoodsService.PayOrder(orderId.value).then(res=>{
|
|
if(res.code==0){
|
|
Service.Msg('下单成功!')
|
|
}else{
|
|
Service.Msg(res.msg)
|
|
}
|
|
})
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
</script>
|
|
|
|
<style lang="scss" scoped>
|
|
@keyframes skeleton-blink {
|
|
0% {
|
|
background-position: 100% 50%;
|
|
}
|
|
|
|
100% {
|
|
background-position: 0 50%;
|
|
}
|
|
}
|
|
|
|
.skeleton-item {
|
|
background: linear-gradient(90deg, #f0f0f0 25%, #e0e0e0 50%, #f0f0f0 75%);
|
|
background-size: 200% 100%;
|
|
animation: skeleton-blink 1.5s infinite linear;
|
|
}
|
|
|
|
.skeleton-rect {
|
|
border-radius: 12rpx;
|
|
}
|
|
|
|
.skeleton-text {
|
|
border-radius: 4rpx;
|
|
}
|
|
|
|
.skeleton-wrapper {
|
|
padding: 24rpx;
|
|
background-color: #f7f7f7;
|
|
|
|
.skeleton-card {
|
|
background-color: #fff;
|
|
padding: 30rpx;
|
|
border-radius: 16rpx;
|
|
margin-bottom: 24rpx;
|
|
}
|
|
}
|
|
|
|
.order-confirm-page {
|
|
background-color: #f7f7f7;
|
|
height: 100vh;
|
|
display: flex;
|
|
flex-direction: column;
|
|
}
|
|
|
|
.page-scroll {
|
|
flex: 1;
|
|
padding-bottom: 140rpx;
|
|
}
|
|
|
|
.page-container {
|
|
padding: 24rpx;
|
|
}
|
|
|
|
.card {
|
|
background-color: #fff;
|
|
border-radius: 16rpx;
|
|
padding: 30rpx;
|
|
margin-bottom: 24rpx;
|
|
box-shadow: 0 8rpx 30rpx rgba(220, 220, 230, 0.3);
|
|
}
|
|
|
|
.address-card {
|
|
display: flex;
|
|
align-items: center;
|
|
gap: 20rpx;
|
|
position: relative;
|
|
|
|
&::before {
|
|
top: 0;
|
|
}
|
|
|
|
&::after {
|
|
bottom: 0;
|
|
}
|
|
|
|
.no-address {
|
|
flex: 1;
|
|
display: flex;
|
|
align-items: center;
|
|
gap: 16rpx;
|
|
font-size: 30rpx;
|
|
}
|
|
|
|
.has-address {
|
|
flex: 1;
|
|
|
|
.user-info {
|
|
display: flex;
|
|
gap: 24rpx;
|
|
|
|
.name {
|
|
font-size: 32rpx;
|
|
font-weight: bold;
|
|
}
|
|
|
|
.phone {
|
|
font-size: 28rpx;
|
|
color: #666;
|
|
}
|
|
}
|
|
|
|
.address-text {
|
|
font-size: 26rpx;
|
|
color: #333;
|
|
margin-top: 12rpx;
|
|
line-height: 1.5;
|
|
}
|
|
}
|
|
}
|
|
|
|
.product-card {
|
|
display: flex;
|
|
gap: 24rpx;
|
|
|
|
.product-image {
|
|
width: 160rpx;
|
|
height: 160rpx;
|
|
border-radius: 12rpx;
|
|
flex-shrink: 0;
|
|
}
|
|
|
|
.product-info {
|
|
display: flex;
|
|
flex-direction: column;
|
|
|
|
.name {
|
|
font-size: 28rpx;
|
|
color: #333;
|
|
font-weight: 500;
|
|
display: -webkit-box;
|
|
-webkit-line-clamp: 2;
|
|
-webkit-box-orient: vertical;
|
|
overflow: hidden;
|
|
}
|
|
|
|
.spec,
|
|
.quantity {
|
|
font-size: 24rpx;
|
|
color: #999;
|
|
margin-top: 8rpx;
|
|
}
|
|
}
|
|
}
|
|
|
|
.options-card,
|
|
.price-card {
|
|
padding: 10rpx 30rpx;
|
|
|
|
:deep(.up-cell) {
|
|
.up-cell__body {
|
|
padding: 28rpx 0;
|
|
}
|
|
|
|
.up-cell__title-text {
|
|
font-size: 28rpx;
|
|
}
|
|
}
|
|
}
|
|
|
|
.price-card {
|
|
.price-row {
|
|
display: flex;
|
|
justify-content: space-between;
|
|
align-items: center;
|
|
padding: 16rpx 0;
|
|
font-size: 28rpx;
|
|
|
|
.label {
|
|
color: #666;
|
|
}
|
|
|
|
.value {
|
|
color: #333;
|
|
font-weight: 500;
|
|
}
|
|
}
|
|
}
|
|
|
|
.bottom-bar {
|
|
position: fixed;
|
|
bottom: 0;
|
|
left: 0;
|
|
right: 0;
|
|
display: flex;
|
|
justify-content: space-between;
|
|
align-items: center;
|
|
background-color: #fff;
|
|
padding: 20rpx 30rpx;
|
|
padding-bottom: calc(20rpx + constant(safe-area-inset-bottom));
|
|
padding-bottom: calc(20rpx + env(safe-area-inset-bottom));
|
|
z-index: 100;
|
|
box-shadow: 0 -4rpx 20rpx rgba(0, 0, 0, 0.08);
|
|
|
|
.total-summary {
|
|
display: flex;
|
|
align-items: baseline;
|
|
gap: 8rpx;
|
|
|
|
.total-points {
|
|
font-size: 36rpx;
|
|
font-weight: bold;
|
|
color: #fa6400;
|
|
}
|
|
|
|
.total-price {
|
|
font-size: 28rpx;
|
|
color: #333;
|
|
}
|
|
}
|
|
|
|
.submit-btn {
|
|
background-color: #fa6400;
|
|
color: #fff;
|
|
font-weight: bold;
|
|
border-radius: 44rpx;
|
|
height: 88rpx;
|
|
line-height: 88rpx;
|
|
font-size: 30rpx;
|
|
margin: 0;
|
|
padding: 0 80rpx;
|
|
|
|
&::after {
|
|
border: none;
|
|
}
|
|
}
|
|
}
|
|
</style> |