451 lines
10 KiB
Plaintext
451 lines
10 KiB
Plaintext
<template>
|
||
<!-- 骨架屏 -->
|
||
<view v-if="loading" class="order-detail skeleton-loading">
|
||
<!-- 订单基本信息骨架屏 -->
|
||
<view class="order-basic-info skeleton-section">
|
||
<view class="" style="display: flex; justify-content: space-between;align-items: center; ">
|
||
<view class="skeleton-block skeleton-short"></view>
|
||
<view class="skeleton-block skeleton-short"></view>
|
||
</view>
|
||
<view class="skeleton-block skeleton-long"></view>
|
||
<view class="" style="display: flex; align-items: center; justify-content: space-between;">
|
||
<view class="skeleton-block skeleton-medium"></view>
|
||
<view class="skeleton-block skeleton-medium"></view>
|
||
</view>
|
||
<view class="skeleton-block skeleton-medium"></view>
|
||
<view class="skeleton-block skeleton-long"></view>
|
||
</view>
|
||
|
||
<!-- 物品清单骨架屏 -->
|
||
<view class="order-basic-info skeleton-section">
|
||
<view v-for="item in 4" class="skeleton-block" style="width: 100%; height: 40rpx; "></view>
|
||
|
||
<view class="" style="display: flex; justify-content: center;">
|
||
<view class="skeleton-block skeleton-short"></view>
|
||
</view>
|
||
</view>
|
||
|
||
<!-- 地图区域骨架屏 -->
|
||
<view class="map-section skeleton-section">
|
||
<view class="map-placeholder skeleton-map"></view>
|
||
</view>
|
||
|
||
<!-- 地址区域骨架屏 -->
|
||
<view class="address-section skeleton-section">
|
||
<view class="skeleton-block skeleton-medium"></view>
|
||
<view class="skeleton-block skeleton-long"></view>
|
||
<view class="skeleton-block skeleton-long"></view>
|
||
<view class="skeleton-block skeleton-medium"></view>
|
||
<view class="skeleton-block skeleton-long"></view>
|
||
<view class="skeleton-block skeleton-long"></view>
|
||
<view class="skeleton-block skeleton-long"></view>
|
||
</view>
|
||
|
||
<view class="bottom-padding"></view>
|
||
|
||
<!-- 底部按钮骨架屏 -->
|
||
<view class="bottom-action">
|
||
<view class="skeleton-button"></view>
|
||
</view>
|
||
</view>
|
||
<!-- 实际内容 -->
|
||
<view v-else class="order-detail">
|
||
<!-- 订单基本信息 -->
|
||
<view class="order-basic-info">
|
||
<view class="info-item">
|
||
<view class="label" style="font-weight: 700; font-size: 30rpx;"> {{ orderInfo.distribution=='预约订单'?'预计'+orderInfo.makeTime.split(' ')[1]+'送达':orderInfo.makeTime }} </view>
|
||
</view>
|
||
<view class="info-item">
|
||
<text class="label">订单编号 : </text>
|
||
<text class="value">{{ orderId }}</text>
|
||
</view>
|
||
|
||
<view class="info-item">
|
||
<view class="label" style="display: flex; align-items: baseline;">
|
||
<u-icon name="clock" size="16" class="clock-icon"></u-icon>
|
||
{{ Service.formatDate(orderInfo.addTime,1) }} 下单
|
||
</view>
|
||
</view>
|
||
|
||
</view>
|
||
|
||
<!-- 物品清单 -->
|
||
<view class="order-basic-info">
|
||
<view class="" style="display: flex; align-items: center; ">
|
||
<view class="" style="flex: 1; font-size: 34rpx; font-weight: 600; ">
|
||
物品清单
|
||
</view>
|
||
<view class="" style="width: 100rpx; text-align: right; font-size: 30rpx; ">
|
||
数量
|
||
</view>
|
||
<view class="" style="width: 120rpx; text-align: right; font-size: 30rpx; ">
|
||
金额
|
||
</view>
|
||
</view>
|
||
<!-- 商品列表 -->
|
||
<view class="" :style="{'height':isShow?'110rpx':'fit-content' }" style="overflow: hidden;">
|
||
<view class="" v-for="(goodsItem,goodsIndex) in JSON.parse(orderInfo.detail) " :key="goodsIndex"
|
||
style="display: flex; align-items: center; margin-top: 15rpx; ">
|
||
<view class="" style="flex: 1; ">
|
||
{{goodsItem.goodsName}}
|
||
</view>
|
||
<view class="" style="width: 100rpx; text-align: right; ">
|
||
×{{ goodsItem.count }}
|
||
</view>
|
||
<view class="" style="width: 120rpx; text-align: right; ">
|
||
¥{{ goodsItem.count*goodsItem.price }}
|
||
</view>
|
||
</view>
|
||
</view>
|
||
<view class="" style="display: flex; align-items: center; justify-content: space-between;" >
|
||
<view class="">
|
||
|
||
</view>
|
||
<view class="info-item">
|
||
<text class="label" style="font-weight: 700;">配送费</text>
|
||
<text class="value price">¥{{ Number(orderInfo.postage).toFixed(2) }}</text>
|
||
</view>
|
||
</view>
|
||
<view class="" v-if="JSON.parse(orderInfo.detail).length>2" @click="isShow=!isShow"
|
||
style=" margin-top: 20rpx; display: flex; align-items: center; justify-content: center; color: #666; ">
|
||
<up-icon :name="isShow?'arrow-down':'arrow-up'" color="#666" size="18"></up-icon>
|
||
{{isShow?'展开':'收入'}}
|
||
</view>
|
||
|
||
</view>
|
||
|
||
<!-- 地图区域 -->
|
||
<view class="map-section">
|
||
<view class="map-placeholder">
|
||
<text @click="Service.GoPage('/pages/order/navigation')" class="map-hint">点击查看完整导航</text>
|
||
</view>
|
||
</view>
|
||
|
||
<!-- 取餐地址 -->
|
||
<view class="address-section">
|
||
<view class="" style=" border-bottom: 4rpx solid #e2e2e2; ">
|
||
<view class="section-title">取餐地址 : </view>
|
||
<view class="address-content">
|
||
<text class="store-name">{{ storeInfo.name }}</text>
|
||
<text class="address"> {{ storeInfo.city }}{{storeInfo.region }}{{ storeInfo.address }}</text>
|
||
</view>
|
||
</view>
|
||
<view style="margin: 10rpx 0; font-size: 30rpx;font-weight: 800;color: #333;">送餐地址 : </view>
|
||
<view class="address-content">
|
||
<text class="user-name">{{ JSON.parse(orderInfo.address).realName }}</text>
|
||
<text class="address">{{ JSON.parse(orderInfo.address).address }}</text>
|
||
<view v-if="orderInfo.remark" class="remark">
|
||
<text class="remark-label">备注:</text>
|
||
<text class="remark-content">请放门口,勿按门铃</text>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
|
||
|
||
|
||
<view class="" style="width: 100vw; height: 140rpx; ">
|
||
|
||
</view>
|
||
|
||
<!-- 底部按钮 -->
|
||
<view class="bottom-action">
|
||
<up-button @click="placeOrder()" color="var(--nav-mian)" class="confirm-btn">立即接单</up-button>
|
||
</view>
|
||
</view>
|
||
</template>
|
||
|
||
<script setup lang="ts">
|
||
import { onLoad } from '@dcloudio/uni-app';
|
||
import { ref, onMounted } from 'vue';
|
||
import { Service } from '@/Service/Service';
|
||
import { CNRiderOrderService } from '@/Service/CN/CNRiderOrderService'
|
||
|
||
// 加载状态
|
||
const loading = ref(true);
|
||
|
||
let orderStatus = ref(0)
|
||
|
||
let isShow = ref(true)
|
||
|
||
let deliveryTime = ref('')
|
||
|
||
let orderInfo = ref<any>({})
|
||
let storeInfo = ref<any>({})
|
||
let storeLocation = ref<any>({})
|
||
|
||
let orderId = ref('')
|
||
onLoad((data : any) => {
|
||
orderId.value = data.orderId
|
||
getData()
|
||
})
|
||
|
||
const getData = () => {
|
||
CNRiderOrderService.GetUnitOrderInfo(orderId.value).then(res => {
|
||
loading.value = false
|
||
|
||
if (res.data) {
|
||
deliveryTime.value = res.data.deliveryTime
|
||
orderInfo.value = res.data.orderInfo
|
||
storeInfo.value = res.data.storeInfo
|
||
storeLocation.value = res.data.storeLocation
|
||
}
|
||
|
||
})
|
||
}
|
||
|
||
const placeOrder = () => {
|
||
CNRiderOrderService.RiderTakeOrder(orderId.value).then(res => {
|
||
if (res.data) {
|
||
Service.Msg('接单成功!')
|
||
setTimeout(() => {
|
||
Service.GoPageBack()
|
||
},1000)
|
||
} else {
|
||
Service.Msg(res.msg)
|
||
}
|
||
})
|
||
}
|
||
</script>
|
||
|
||
<style scoped>
|
||
.order-detail {
|
||
min-height: 100vh;
|
||
background-color: #f5f5f5;
|
||
}
|
||
|
||
/* 订单状态样式 */
|
||
.order-status {
|
||
background-color: #fff;
|
||
padding: 30rpx;
|
||
text-align: center;
|
||
}
|
||
|
||
|
||
/* 订单基本信息样式 */
|
||
.order-basic-info {
|
||
background-color: #fff;
|
||
margin: 20rpx 20rpx;
|
||
padding: 30rpx;
|
||
border-radius: 20rpx;
|
||
}
|
||
|
||
.info-item {
|
||
display: flex;
|
||
align-items: center;
|
||
margin-bottom: 20rpx;
|
||
font-size: 28rpx;
|
||
}
|
||
|
||
.info-item:last-child {
|
||
margin-bottom: 0;
|
||
}
|
||
|
||
.label {
|
||
color: #666;
|
||
margin-right: 10rpx;
|
||
}
|
||
|
||
.value {
|
||
color: #333;
|
||
}
|
||
|
||
.value.highlight {
|
||
color: var(--nav-diluted);
|
||
font-weight: 500;
|
||
}
|
||
|
||
.value.price {
|
||
color: var(--nav-diluted);
|
||
font-weight: 700;
|
||
}
|
||
|
||
.clock-icon {
|
||
color: #666;
|
||
margin-right: 8rpx;
|
||
}
|
||
|
||
/* 地图区域样式 */
|
||
.map-section {
|
||
margin: 20rpx;
|
||
border-radius: 20rpx;
|
||
overflow: hidden;
|
||
}
|
||
|
||
.map-placeholder {
|
||
width: 100%;
|
||
height: 400rpx;
|
||
background-color: #f0f0f0;
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
position: relative;
|
||
border: 1rpx solid #e8e8e8;
|
||
}
|
||
|
||
.map-placeholder::before {
|
||
content: '';
|
||
position: absolute;
|
||
top: 0;
|
||
left: 0;
|
||
right: 0;
|
||
bottom: 0;
|
||
background: linear-gradient(135deg, #f5f5f5 25%, #e6e6e6 25%, #e6e6e6 50%, #f5f5f5 50%, #f5f5f5 75%, #e6e6e6 75%, #e6e6e6 100%);
|
||
background-size: 20rpx 20rpx;
|
||
opacity: 0.3;
|
||
}
|
||
|
||
.map-hint {
|
||
font-size: 28rpx;
|
||
color: #666;
|
||
position: relative;
|
||
z-index: 1;
|
||
}
|
||
|
||
/* 地址区域样式 */
|
||
.address-section {
|
||
background-color: #fff;
|
||
margin: 20rpx;
|
||
padding: 30rpx;
|
||
border-radius: 20rpx;
|
||
}
|
||
|
||
.section-title {
|
||
font-size: 30rpx;
|
||
font-weight: 800;
|
||
color: #333;
|
||
margin: 10rpx 0;
|
||
}
|
||
|
||
.address-content {
|
||
position: relative;
|
||
}
|
||
|
||
.store-name,
|
||
.user-name {
|
||
font-size: 34rpx;
|
||
font-weight: 600;
|
||
margin-bottom: 15rpx;
|
||
display: block;
|
||
}
|
||
|
||
.address {
|
||
font-size: 26rpx;
|
||
color: #666;
|
||
line-height: 1.5;
|
||
margin-bottom: 25rpx;
|
||
display: block;
|
||
}
|
||
|
||
|
||
|
||
.pickup-code,
|
||
.remark {
|
||
font-size: 26rpx;
|
||
}
|
||
|
||
.code-label,
|
||
.code-value {
|
||
color: var(--nav-mian);
|
||
font-weight: 600;
|
||
}
|
||
|
||
.remark-label,
|
||
.remark-content {
|
||
color: #FAAD14;
|
||
font-weight: 600;
|
||
}
|
||
|
||
/* 底部按钮样式 */
|
||
.bottom-action {
|
||
background-color: #fff;
|
||
width: 100vw;
|
||
position: fixed;
|
||
bottom: 0;
|
||
left: 0;
|
||
padding: 20rpx 30rpx;
|
||
}
|
||
|
||
.confirm-btn {
|
||
width: 100%;
|
||
height: 90rpx;
|
||
font-size: 32rpx;
|
||
line-height: 90rpx;
|
||
border-radius: 45rpx;
|
||
}
|
||
|
||
/* 骨架屏样式 */
|
||
.skeleton-loading .skeleton-section {
|
||
margin: 20rpx 20rpx;
|
||
padding: 30rpx;
|
||
border-radius: 20rpx;
|
||
background-color: #fff;
|
||
}
|
||
|
||
|
||
|
||
.skeleton-block {
|
||
background-color: #f0f0f0;
|
||
margin-bottom: 20rpx;
|
||
border-radius: 4rpx;
|
||
position: relative;
|
||
overflow: hidden;
|
||
}
|
||
|
||
|
||
|
||
.skeleton-short {
|
||
height: 40rpx;
|
||
width: 30%;
|
||
}
|
||
|
||
.skeleton-medium {
|
||
height: 30rpx;
|
||
width: 30%;
|
||
}
|
||
|
||
.skeleton-long {
|
||
height: 30rpx;
|
||
width: 90%;
|
||
}
|
||
|
||
.skeleton-map {
|
||
height: 400rpx;
|
||
background-color: #f0f0f0;
|
||
border-radius: 20rpx;
|
||
margin: 0;
|
||
}
|
||
|
||
.skeleton-button {
|
||
height: 90rpx;
|
||
background-color: #f0f0f0;
|
||
border-radius: 45rpx;
|
||
}
|
||
|
||
.bottom-padding {
|
||
height: 140rpx;
|
||
}
|
||
|
||
/* 骨架屏动画 */
|
||
.skeleton-block::after,
|
||
.skeleton-map::after,
|
||
.skeleton-button::after {
|
||
content: '';
|
||
position: absolute;
|
||
top: 0;
|
||
left: 0;
|
||
width: 100%;
|
||
height: 100%;
|
||
background: linear-gradient(90deg, transparent, rgba(255, 255, 255, 0.2), transparent);
|
||
animation: shimmer 1.5s infinite;
|
||
}
|
||
|
||
@keyframes shimmer {
|
||
0% {
|
||
transform: translateX(-100%);
|
||
}
|
||
|
||
100% {
|
||
transform: translateX(100%);
|
||
}
|
||
}
|
||
</style> |