|
|
- <template>
- <view class="logistics-page">
- <!-- 顶部导航 -->
- <view class="nav-bar">
- <view class="back" @tap="goBack">
- <uni-icons type="left" size="20" color="#222" />
- </view>
- <text class="nav-title">物流轨迹</text>
- </view>
-
- <!-- 物流信息卡片 -->
- <view class="logistics-card">
- <view class="express-info">
- <view class="express-company">{{ expressCompany }}</view>
- <view class="express-number">运单号:{{ wuliuNo }}</view>
- </view>
- </view>
-
- <!-- 物流轨迹列表 -->
- <view class="trace-list">
- <view
- v-for="(item, index) in traceList"
- :key="index"
- class="trace-item"
- :class="{ 'active': index === 0 }"
- >
- <view class="trace-dot">
- <view class="dot-inner"></view>
- </view>
- <view class="trace-line" v-if="index < traceList.length - 1"></view>
- <view class="trace-content">
- <view class="trace-desc">{{ item.description }}</view>
- <view class="trace-time">{{ item.time }}</view>
- <view class="trace-location">{{ item.site }}</view>
- </view>
- </view>
- </view>
-
- <!-- 加载状态 -->
- <view v-if="loading" class="loading">
- <uni-load-more status="loading" :content-text="loadingText"></uni-load-more>
- </view>
-
- <!-- 无数据状态 -->
- <view v-if="!loading && traceList.length === 0" class="empty-state">
- <image src="/static/empty-logistics.png" class="empty-icon" mode="aspectFit"></image>
- <text class="empty-text">暂无物流信息</text>
- </view>
- </view>
- </template>
-
- <script>
- export default {
- data() {
- return {
- wuliuNo: '',
- expressCompany: '',
- traceList: [],
- loading: false,
- loadingText: {
- contentdown: '上拉显示更多',
- contentrefresh: '正在加载...',
- contentnomore: '没有更多数据了'
- }
- }
- },
- onLoad(options) {
- if (options.wliuNo) {
- this.wuliuNo = options.wliuNo
- }
- if (options.expressCompany) {
- this.expressCompany = options.expressCompany
- }
- this.fetchLogisticsTrace()
- },
- methods: {
- goBack() {
- uni.navigateBack()
- },
- async fetchLogisticsTrace() {
- if (!this.wuliuNo) {
- uni.showToast({ title: '运单号不能为空', icon: 'none' })
- return
- }
-
- this.loading = true
-
- try {
- this.$api('queryTrace', {
- wuliuNo: this.wuliuNo
- }, res => {
- this.loading = false
-
- if (res && res.code === 200 && res.result && res.result.responseParam) {
- const traceData = res.result.responseParam
- this.traceList = traceData.trace_list || []
-
- if (this.traceList.length === 0) {
- uni.showToast({ title: '暂无物流信息', icon: 'none' })
- }
- } else {
- uni.showToast({ title: res?.message || '获取物流信息失败', icon: 'none' })
- }
- })
- } catch (error) {
- this.loading = false
- uni.showToast({ title: '网络错误,请重试', icon: 'none' })
- }
- }
- }
- }
- </script>
-
- <style lang="scss" scoped>
- .logistics-page {
- min-height: 100vh;
- background: #f8f8f8;
- padding-bottom: 40rpx;
- }
-
- .nav-bar {
- display: flex;
- align-items: center;
- height: calc(150rpx + var(--status-bar-height));
- padding: 0 32rpx;
- padding-top: var(--status-bar-height);
- background: #fff;
- position: fixed;
- top: 0;
- left: 0;
- right: 0;
- z-index: 999;
- box-sizing: border-box;
- box-shadow: 0 2rpx 8rpx rgba(0,0,0,0.03);
-
- .back {
- padding: 20rpx;
- margin-left: -20rpx;
- }
-
- .nav-title {
- flex: 1;
- text-align: center;
- font-size: 32rpx;
- font-weight: 500;
- color: #222;
- }
- }
-
- .logistics-card {
- margin: calc(150rpx + var(--status-bar-height) + 24rpx) 24rpx 24rpx 24rpx;
- background: #fff;
- border-radius: 24rpx;
- padding: 32rpx;
- box-shadow: 0 4rpx 16rpx rgba(0,0,0,0.04);
-
- .express-info {
- .express-company {
- font-size: 32rpx;
- font-weight: bold;
- color: #222;
- margin-bottom: 12rpx;
- }
-
- .express-number {
- font-size: 28rpx;
- color: #666;
- }
- }
- }
-
- .trace-list {
- margin: 0 24rpx;
- background: #fff;
- border-radius: 24rpx;
- padding: 32rpx;
- box-shadow: 0 4rpx 16rpx rgba(0,0,0,0.04);
- position: relative;
- }
-
- .trace-item {
- display: flex;
- align-items: flex-start;
- position: relative;
- padding-bottom: 32rpx;
-
- &:last-child {
- padding-bottom: 0;
- }
-
- &.active {
- .trace-dot {
- background: #ff9c00;
- border-color: #ff9c00;
- }
-
- .trace-content {
- .trace-desc {
- color: #222;
- font-weight: bold;
- }
-
- .trace-time {
- color: #ff9c00;
- }
- }
- }
-
- .trace-dot {
- width: 24rpx;
- height: 24rpx;
- border-radius: 50%;
- background: #ddd;
- border: 4rpx solid #f0f0f0;
- margin-right: 24rpx;
- margin-top: 8rpx;
- flex-shrink: 0;
- position: relative;
- z-index: 2;
-
- .dot-inner {
- width: 8rpx;
- height: 8rpx;
- border-radius: 50%;
- background: #fff;
- position: absolute;
- top: 50%;
- left: 50%;
- transform: translate(-50%, -50%);
- }
- }
-
- .trace-line {
- position: absolute;
- left: 12rpx;
- top: 32rpx;
- width: 2rpx;
- height: calc(100% - 32rpx);
- background: #f0f0f0;
- z-index: 1;
- }
-
- .trace-content {
- flex: 1;
- min-width: 0;
-
- .trace-desc {
- font-size: 28rpx;
- color: #666;
- line-height: 1.5;
- margin-bottom: 8rpx;
- word-break: break-all;
- }
-
- .trace-time {
- font-size: 24rpx;
- color: #999;
- margin-bottom: 4rpx;
- }
-
- .trace-location {
- font-size: 24rpx;
- color: #bbb;
- }
- }
- }
-
- .loading {
- margin: 40rpx 24rpx;
- text-align: center;
- }
-
- .empty-state {
- margin: 120rpx 24rpx;
- text-align: center;
-
- .empty-icon {
- width: 200rpx;
- height: 200rpx;
- margin-bottom: 24rpx;
- }
-
- .empty-text {
- font-size: 28rpx;
- color: #999;
- }
- }
- </style>
|