| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163 |
- <template>
- <u-popup :show="showPopup" mode="center" round="20" @close="closePopup" :closeable="true"
- :safeAreaInsetBottom="false" :closeOnClickOverlay="true">
- <view class="express-popup">
- <!-- 弹框头部 -->
- <view class="popup-header">
- <text class="title">物流轨迹</text>
- </view>
- <!-- 右上角关闭按钮 -->
- <view class="close-btn" @tap="closePopup">
- <u-icon name="close" size="22" color="#333"></u-icon>
- </view>
- <!-- 物流轨迹时间线 -->
- <scroll-view class="timeline-container" scroll-y="true">
- <TimelineItem
- v-for="(item, index) in deliverTraceList"
- :key="index"
- :title="item.title"
- :desc="item.context"
- :time="item.time"
- :is-active="item.isActive"
- :show-line="index < deliverTraceList.length - 1"
- :show-dot-bg="index === 0"
- />
- <view v-if="deliverTraceList.length === 0 && !loading" class="empty-trace">
- 暂无物流轨迹
- </view>
- </scroll-view>
- </view>
- </u-popup>
- </template>
- <script setup>
- import {
- ref,
- defineProps,
- defineEmits,
- watch
- } from 'vue'
- import TimelineItem from '@/components/TimelineItem.vue'
- import { queryDeliverTrace } from '@/api/order'
- const props = defineProps({
- showPopup: {
- type: Boolean,
- default: false
- },
- orderNo:{
- type: String,
- default: ""
- },
- expressData: {
- type: Object,
- default: () => ({
- company: '顺丰速运',
- number: 'SF1234567890123',
- status: '已签收'
- })
- }
- })
- const emit = defineEmits(['update:showPopup', 'close'])
- // 模拟物流轨迹数据,实际应用中应该通过API获取
- const trackList = ref([])
-
- watch( showPopup,(olddata,newData) => {
- if(showPopup){
- getDeliverTrace()
- }
- })
-
- // 获取真实物流轨迹
- const getDeliverTrace = () => {
- if (!props.orderNo) return
- loading.value = true
- const params = {
- number: props.orderNo,
- company: '' // 可传入快递公司编码
- }
- queryDeliverTrace(params).then(response => {
- if (response.code === 200 && response.data) {
- // 按时间倒序排列(最新的在前)
- const list = response.data.data.map((item, index) => ({
- ...item,
- isActive: index === 0
- }))
- deliverTraceList.value = list
- } else {
- uni.showToast({ title: '未查询到物流信息', icon: 'none' })
- deliverTraceList.value = []
- }
- }).catch(error => {
- console.error('查询物流轨迹失败:', error)
- uni.showToast({ title: '查询物流信息失败', icon: 'error' })
- deliverTraceList.value = []
- }).finally(() => {
- loading.value = false
- })
- }
-
-
- const closePopup = () => {
- emit('update:showPopup', false)
- emit('close')
- }
- </script>
- <style scoped lang="less">
- .express-popup {
- width: 670rpx;
- background-color: #ffffff;
- border-radius: 32rpx;
- padding: 32rpx;
- max-height: 88vh;
- display: flex;
- flex-direction: column;
- }
- /* 头部样式 */
- .popup-header {
- display: flex;
- justify-content: center;
- align-items: center;
- padding-bottom: 20rpx;
- .title {
- font-size: 32rpx;
- font-weight: bold;
- color: #333333;
- }
- }
- .close-btn {
- position: absolute;
- right: 32rpx;
- top: 40rpx;
- }
- /* 时间线容器 */
- .timeline-container {
- overflow-y: auto;
- max-height: calc(88vh - 120rpx);
- }
- /* 弹框样式调整 */
- :deep(.u-popup) {
- display: flex;
- justify-content: center;
- align-items: flex-end;
- }
- :deep(.u-popup__content) {
- width: 90% !important;
- max-width: 670rpx !important;
- /* 限制最大宽度,避免在宽屏上过宽 */
- margin: 0 auto;
- }
- </style>
|