campus-errand/miniapp/pages/message/order-notify.vue
18631081161 681d2b5fe8
All checks were successful
continuous-integration/drone/push Build is passing
提现
2026-04-02 16:55:18 +08:00

292 lines
5.7 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<template>
<view class="order-notify-page">
<!-- 自定义导航栏 -->
<view class="custom-navbar" :style="{ paddingTop: statusBarHeight + 'px' }">
<view class="navbar-content">
<view class="nav-back" @click="goBack">
<image class="back-icon" src="/static/ic_back.png" mode="aspectFit"></image>
</view>
<text class="navbar-title">订单通知</text>
<view class="nav-placeholder"></view>
</view>
</view>
<view :style="{ height: (statusBarHeight + 44) + 'px' }"></view>
<!-- 分类标签 -->
<view class="tabs">
<view
class="tab-item"
:class="{ active: currentTab === tab.value }"
v-for="tab in tabs"
:key="tab.value"
@click="switchTab(tab.value)"
>
<text>{{ tab.label }}</text>
</view>
</view>
<!-- 订单通知列表 -->
<view
class="notify-item"
v-for="item in notifications"
:key="item.id"
>
<view class="notify-header">
<text class="notify-title">{{ item.title }}</text>
<text class="notify-type">{{ formatOrderType(item.orderType) }}</text>
</view>
<view class="notify-body">
<text class="notify-order-no">订单编号:{{ item.orderNo }}</text>
<text class="notify-item-name" v-if="item.itemName">
{{ getFirstFieldLabel(item.orderType) }}{{ item.itemName }}
</text>
</view>
<view class="notify-footer">
<text class="notify-time">{{ formatTime(item.createdAt) }}</text>
<view class="notify-btn" @click="goOrderDetail(item)">
<text class="btn-text">查看订单</text>
</view>
</view>
</view>
<!-- 空状态 -->
<view v-if="notifications.length === 0 && !loading" class="empty">
<text class="empty-text">暂无订单通知</text>
</view>
</view>
</template>
<script>
import { getOrderNotifications } from '../../utils/api'
export default {
data() {
return {
currentTab: '',
tabs: [
{ label: '全部', value: '' },
{ label: '被接单', value: 'accepted' },
{ label: '已完成', value: 'completed' },
{ label: '已取消', value: 'cancelled' }
],
notifications: [],
loading: false,
statusBarHeight: 0
}
},
onLoad() {
const sysInfo = uni.getSystemInfoSync()
this.statusBarHeight = sysInfo.statusBarHeight || 0
this.loadNotifications()
},
methods: {
goBack() { uni.navigateBack() },
/** 切换分类标签 */
switchTab(value) {
this.currentTab = value
this.loadNotifications()
},
/** 加载订单通知列表 */
async loadNotifications() {
this.loading = true
try {
const params = {}
if (this.currentTab) {
params.category = this.currentTab
}
const res = await getOrderNotifications(params)
this.notifications = res || []
} catch (e) {
uni.showToast({ title: '加载失败', icon: 'none' })
} finally {
this.loading = false
}
},
/** 跳转订单详情页 */
goOrderDetail(item) {
uni.navigateTo({
url: `/pages/order/order-detail?id=${item.id}`
})
},
/** 格式化订单类型 */
formatOrderType(type) {
const map = {
Pickup: '代取',
Delivery: '代送',
Help: '万能帮',
Purchase: '代购',
Food: '美食街'
}
return map[type] || type
},
/** 获取订单第1项字段标题 */
getFirstFieldLabel(type) {
const map = {
Pickup: '代取物品',
Delivery: '代送物品',
Help: '帮忙事项',
Purchase: '代购物品',
Food: '美食订单'
}
return map[type] || '物品'
},
/** 格式化时间(精确到年月日时分,) */
formatTime(dateStr) {
if (!dateStr) return ''
const d = new Date(typeof dateStr === 'string' && !dateStr.endsWith('Z') ? dateStr + 'Z' : dateStr)
const pad = (n) => String(n).padStart(2, '0')
return `${d.getFullYear()}-${pad(d.getMonth() + 1)}-${pad(d.getDate())} ${pad(d.getHours())}:${pad(d.getMinutes())}`
}
}
}
</script>
<style scoped>
/* 自定义导航栏 */
.custom-navbar {
position: fixed;
top: 0;
left: 0;
width: 100%;
z-index: 999;
background: #FFB700;
}
.navbar-content {
height: 44px;
display: flex;
align-items: center;
justify-content: space-between;
padding: 0 20rpx;
}
.nav-back {
width: 60rpx;
height: 60rpx;
display: flex;
align-items: center;
justify-content: center;
}
.back-icon {
width: 40rpx;
height: 40rpx;
}
.navbar-title {
font-size: 34rpx;
font-weight: bold;
color: #363636;
}
.nav-placeholder {
width: 60rpx;
}
.order-notify-page {
padding: 0 24rpx 20rpx;
}
.tabs {
display: flex;
background-color: #ffffff;
padding: 20rpx 0;
margin: 0 -24rpx 20rpx;
padding-left: 24rpx;
padding-right: 24rpx;
position: sticky;
top: 0;
z-index: 10;
}
.tab-item {
flex: 1;
text-align: center;
font-size: 28rpx;
color: #666666;
padding: 12rpx 0;
border-radius: 8rpx;
}
.tab-item.active {
color: #FFB700;
font-weight: 500;
background-color: #fff8e6;
}
.notify-item {
background-color: #ffffff;
border-radius: 16rpx;
padding: 24rpx 30rpx;
margin-bottom: 16rpx;
}
.notify-header {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 16rpx;
}
.notify-title {
font-size: 30rpx;
color: #333333;
font-weight: 500;
}
.notify-type {
font-size: 24rpx;
color: #FFB700;
background-color: #fff8e6;
padding: 4rpx 16rpx;
border-radius: 8rpx;
}
.notify-body {
margin-bottom: 16rpx;
}
.notify-order-no {
font-size: 24rpx;
color: #999999;
display: block;
}
.notify-item-name {
font-size: 26rpx;
color: #666666;
margin-top: 8rpx;
display: block;
}
.notify-footer {
display: flex;
justify-content: space-between;
align-items: center;
}
.notify-time {
font-size: 22rpx;
color: #cccccc;
}
.notify-btn {
background-color: #FFB700;
border-radius: 8rpx;
padding: 8rpx 24rpx;
}
.btn-text {
font-size: 24rpx;
color: #ffffff;
}
.empty {
text-align: center;
padding: 120rpx 0;
}
.empty-text {
font-size: 28rpx;
color: #cccccc;
}
</style>