You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

419 lines
11 KiB

<template>
<el-container>
<!-- 导航栏 -->
<el-header>
<Header />
</el-header>
<el-main>
<div class="container">
<!-- 标题输入框和按钮 -->
<!-- <div class="bg"></div> -->
<div class="top-section">
<h1 class="title">运单查询</h1>
<div class="input-group">
<el-input
v-model="form.trackingNumber"
placeholder="请输入快递单号"
clearable
style="width: 300px; margin-right: 20px;"
@input="validateTrackingNumber"
@keyup.enter="searchPackage"
></el-input>
<el-button @click="searchPackage" type="primary" :loading="loading"></el-button>
</div>
</div>
<!-- 选项卡 -->
<el-tabs v-model="activeTab" type="card" style="margin-top: 20px;" @tab-click="handleTabClick">
<el-tab-pane label="我寄的" name="sent">
<el-table v-if="sentPackages.length" :data="sentPackages" style="margin-top: 20px;">
<el-table-column label="快递单号" prop="trackingNumber"></el-table-column>
<el-table-column label="包裹名称" prop="packageName"></el-table-column>
<el-table-column label="寄件人" prop="sender"></el-table-column>
<el-table-column label="寄件人地址" prop="senderaddress"></el-table-column>
<el-table-column label="收件人" prop="receiver"></el-table-column>
<el-table-column label="收件人地址" prop="receiveraddress"></el-table-column>
<el-table-column label="状态" prop="status">
<template #default="scope">
<span :class="getStatusClass(scope.row.status)">{{ scope.row.status }}</span>
</template>
</el-table-column>
<el-table-column label="最新位置" prop="latestLocation"></el-table-column>
</el-table>
<p v-else>暂无数据</p>
</el-tab-pane>
<el-tab-pane label="我收的" name="received">
<el-table v-if="receivedPackages.length" :data="receivedPackages" style="margin-top: 20px;">
<el-table-column label="快递单号" prop="trackingNumber"></el-table-column>
<el-table-column label="包裹名称" prop="packageName"></el-table-column>
<el-table-column label="寄件人地址" prop="senderaddress"></el-table-column>
<el-table-column label="寄件人" prop="sender"></el-table-column>
<el-table-column label="收件人地址" prop="receiveraddress"></el-table-column>
<el-table-column label="收件人" prop="receiver"></el-table-column>
<el-table-column label="状态" prop="status">
<template #default="scope">
<span :class="getStatusClass(scope.row.status)">{{ scope.row.status }}</span>
</template>
</el-table-column>
<el-table-column label="最新位置" prop="latestLocation"></el-table-column>
</el-table>
<p v-else></p>
</el-tab-pane>
</el-tabs>
</div>
</el-main>
<el-footer>
<Footer />
</el-footer>
</el-container>
</template>
<script lang="ts" setup>
import { ref, onMounted } from 'vue'
import { ElMessage, ElMessageBox, ElInput, ElButton, ElTable, ElTableColumn } from 'element-plus'
// 定义包裹数据的类型
interface Package {
trackingNumber: string;
packageName: string;
sender: string;
senderaddress: string;
receiver: string;
receiveraddress: string;
status: string;
latestLocation: string;
}
// 模拟数据
const mockData: Package[] = [
{
trackingNumber: '123',
packageName: '书籍',
sender: '张帅齐',
senderaddress: '北京市海淀区',
receiver: '李四',
receiveraddress: '上海市浦东新区',
status: '未签收',
latestLocation: '北京市海淀区',
},
{
trackingNumber: '456',
packageName: '衣物',
sender: '林涛',
senderaddress: '上海市浦东新区',
receiver: '李四',
receiveraddress: '北京市海淀区',
status: '正在运输',
latestLocation: '上海市浦东新区',
},
{
trackingNumber: '789',
packageName: '电子产品',
sender: '陈子润',
senderaddress: '北京市海淀区',
receiver: '李四',
receiveraddress: '北京市海淀区',
status: '已签收',
latestLocation: '北京市海淀区',
},
{
trackingNumber: '011',
packageName: '书籍',
sender: '张帅齐',
senderaddress: '北京市海淀区',
receiver: '李四',
receiveraddress: '北京市海淀区',
status: '已签收',
latestLocation: '北京市海淀区',
},
{
trackingNumber: '012',
packageName: '书籍',
sender: '孙贺贺',
senderaddress: '北京市海淀区',
receiver: '李四',
receiveraddress: '北京市海淀区',
status: '已签收',
latestLocation: '北京市海淀区',
},
{
trackingNumber: '013',
packageName: '书籍',
sender: '梁佳琪',
senderaddress: '北京市海淀区',
receiver: '李四',
receiveraddress: '北京市海淀区',
status: '未签收',
latestLocation: '北京市海淀区',
}
]
const form = ref({
trackingNumber: ''
})
const activeTab = ref('sent')
const sentPackages = ref<Package[]>([]) // 初始为空数组
const receivedPackages = ref<Package[]>([]) // 初始为空数组
const error = ref('')
const loading = ref(false)
// 验证快递单号
const validateTrackingNumber = () => {
if (form.value.trackingNumber && !/^\d+$/.test(form.value.trackingNumber)) {
error.value = '快递单号只能包含数字'
} else {
error.value = ''
}
}
// 处理选项卡点击事件
const handleTabClick = (tab: any) => {
// 清空当前的包裹数据
sentPackages.value = [];
receivedPackages.value = [];
if (tab.paneName === 'sent') {
sentPackages.value = mockData.filter(item => ['123', '456', '789'].includes(item.trackingNumber));
activeTab.value = 'sent'; // 确保 activeTab 更新
} else if (tab.paneName === 'received') {
receivedPackages.value = mockData.filter(item => ['011', '012', '013'].includes(item.trackingNumber));
activeTab.value = 'received'; // 确保 activeTab 更新
}
}
// 初始化加载“我寄的”运单数据
const initSentPackages = () => {
sentPackages.value = mockData.filter(item => ['123', '456', '789'].includes(item.trackingNumber));
}
// 在组件初始化时调用
onMounted(() => {
initSentPackages();
})
// 查询包裹的函数
const searchPackage = async () => {
if (!form.value.trackingNumber) {
ElMessage.error('请输入快递单号')
return
}
if (error.value) {
ElMessageBox.alert(error.value, '错误', {
confirmButtonText: '确定',
type: 'error',
})
return
}
loading.value = true
try {
const result = mockData.find(item => item.trackingNumber === form.value.trackingNumber)
if (result) {
ElMessage.success('查询成功')
// 自动跳转到对应的选项卡
if (['123', '456', '789'].includes(result.trackingNumber)) {
activeTab.value = 'sent'
sentPackages.value = [result] // 只显示查询到的包裹
receivedPackages.value = [] // 清空收到的包裹
} else if (['011', '012', '013'].includes(result.trackingNumber)) {
activeTab.value = 'received'
receivedPackages.value = [result] // 只显示查询到的包裹
sentPackages.value = [] // 清空寄出的包裹
}
} else {
ElMessageBox.alert('未找到该快递单号的信息,请确认单号是否正确。', '错误', {
confirmButtonText: '确定',
type: 'error',
})
}
} finally {
loading.value = false
}
}
// 获取状态的颜色类
const getStatusClass = (status: string) => {
switch (status) {
case '已签收':
return 'status-success';
case '正在运输':
return 'status-warning';
default:
return 'status-fail';
}
}
</script>
<style scoped>
/* 将容器设置为 flex 布局,居中对齐 */
.container {
display: flex;
flex-direction: column;
align-items: center;
justify-content: flex-start; /* 从顶部开始排列 */
padding: 20px;
/* background: #f5f5f5; */
}
/* 标题样式 */
.title {
font-size: 32px;
font-weight: bold;
color: #0093dd;
margin-bottom: 20px;
text-align: center;
margin-top: 0px; /* 为标题留出导航栏的空间 */
}
/* 顶部区域样式 */
.top-section {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
width: 100%;
max-width: 600px;
}
/* 输入框和按钮容器 */
.input-group {
display: flex;
align-items: center;
justify-content: center;
margin-bottom: 20px;
}
.input-group .el-input {
margin-right: 20px;
width: 300px;
}
.el-button {
padding: 10px 20px;
font-size: 16px;
}
/* 表格样式 */
.el-table {
width: 100%;
max-width: 1000px; /* 增加表格的最大宽度 */
margin-top: 20px;
box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
border-radius: 10px;
overflow: hidden;
}
.el-table th,
.el-table td {
text-align: center;
padding: 12px 0;
}
.el-table th {
background: #f0f0f0;
font-weight: bold;
}
.el-table tr:nth-child(even) {
background: #f9f9f9;
}
.el-table tr:hover {
background: #e0e0e0;
}
/* 状态颜色样式 */
.status-success {
color: green;
}
.status-fail {
color: rgb(255, 0, 0);
}
.status-warning {
color: orange;
}
/* 选项卡样式 */
.el-tabs {
width: 100%;
max-width: 1000px; /* 增加选项卡的最大宽度 */
margin-top: 20px;
box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
border-radius: 10px;
overflow: hidden;
}
.el-tabs__header {
margin: 0;
padding: 0 20px;
background: #f0f0f0;
border-bottom: 1px solid #ddd;
}
.el-tabs__nav-wrap::after {
display: none;
}
.el-tabs__item {
padding: 0 20px;
height: 40px;
line-height: 40px;
font-weight: bold;
color: #333;
transition: background 0.3s, color 0.3s, border-bottom 0.3s;
border-bottom: 2px solid transparent; /* 默认情况下没有下划线 */
}
.el-tabs__item.is-active {
background: #fff;
color: #409eff;
border-bottom: 2px solid red !important; /* 激活状态下有红色下划线 */
}
.el-tabs__item:hover {
background: #e0e0e0;
color: #409eff;
border-bottom: 2px solid #f60d0d !important; /* 悬停时有下划线 */
}
/* Element UI 容器样式 */
.el-header {
padding: 0;
height: 100;
}
.el-main {
margin-top: 80px;
padding: 20px 0;
overflow: hidden;
height: calc(100vh - 200px); /* 调整高度以适应屏幕 */
}
.el-footer {
margin-top: 0px;
padding: 20px 0;
/* background: #333; */
color: #fff;
text-align: center;
}
.bg{
background-image: url('./assets/check-bg.jpg'); /* 替换为你的图片路径 */
background-size: cover; /* 覆盖整个元素 */
background-position: center; /* 背景图居中 */
background-repeat: no-repeat; /* 不重复背景图 */
width: 100%; /* 宽度填满整个容器 */
height: 100%; /* 高度填满整个容器 */
position: absolute; /* 绝对定位 */
top: 0;
left: 0;
z-index: -1; /* 确保背景图在内容下方 */
}
</style>