OMS_H5/src/views/List/index.vue

268 lines
5.7 KiB
Vue
Raw Normal View History

<template>
<div class="order-list-page">
<!-- 搜索栏 -->
<van-search
v-model="searchKeyword"
placeholder="搜索订单编号、客户名称"
@search="handleSearch"
@clear="handleClear"
/>
<!-- 下拉刷新 -->
<van-pull-refresh v-model="refreshing" @refresh="onRefresh">
<!-- 订单列表 -->
<van-list
v-model:loading="loading"
:finished="finished"
finished-text="没有更多了"
@load="onLoad"
>
<div v-for="order in orderList" :key="order.id" class="order-item" @click="goToDetail(order.id)">
<div class="order-header">
<div class="order-code">{{ order.orderCode }}</div>
<div class="status-tag pending">
待审批
</div>
</div>
<div class="order-info">
<div class="info-row">
<span class="label">项目名称</span>
<span class="value">{{ order.projectName }}</span>
</div>
<div class="info-row">
<span class="label">客户名称</span>
<span class="value">{{ order.customerName }}</span>
</div>
<div class="info-row">
<span class="label">订单金额</span>
<span class="value amount">{{ formatAmount(order.shipmentAmount) }}</span>
</div>
<div class="info-row">
<span class="label">创建时间</span>
<span class="value">{{ formatDate(order.createTime, 'YYYY-MM-DD HH:mm') }}</span>
</div>
</div>
</div>
<!-- 空状态 -->
<div v-if="!loading && orderList.length === 0" class="empty-state">
<van-empty description="暂无订单数据" />
</div>
</van-list>
</van-pull-refresh>
</div>
</template>
<script setup lang="ts">
import { ref, onMounted } from 'vue'
import { useRouter } from 'vue-router'
import { storeToRefs } from 'pinia'
import { useOrderStore } from '@/store/order'
import { formatOrderStatus, formatAmount, formatDate } from '@/utils'
import type { OrderStatus } from '@/types'
const router = useRouter()
const orderStore = useOrderStore()
const { orderList, loading, finished } = storeToRefs(orderStore)
// 搜索相关
const searchKeyword = ref('')
const refreshing = ref(false)
// 获取状态样式类
const getStatusClass = (status: OrderStatus) => {
const classMap = {
'0': 'pending',
'1': 'approved',
'2': 'rejected'
}
return classMap[status] || 'pending'
}
// 加载数据
const onLoad = async () => {
try {
await orderStore.loadOrderList()
} catch (error) {
console.error('加载订单列表失败:', error)
}
}
// 下拉刷新
const onRefresh = async () => {
try {
await orderStore.loadOrderList(true)
refreshing.value = false
} catch (error) {
refreshing.value = false
console.error('刷新失败:', error)
}
}
// 搜索处理
const handleSearch = async () => {
try {
await orderStore.searchOrders(searchKeyword.value.trim())
} catch (error) {
console.error('搜索失败:', error)
}
}
// 清空搜索
const handleClear = async () => {
searchKeyword.value = ''
try {
await orderStore.searchOrders('')
} catch (error) {
console.error('清空搜索失败:', error)
}
}
// 跳转到详情页
const goToDetail = (id: number) => {
router.push(`/detail/${id}`)
}
onMounted(() => {
// 重置状态并加载数据
orderStore.resetListState()
onLoad()
})
</script>
<style lang="scss" scoped>
.order-list-page {
min-height: 100vh;
background: linear-gradient(135deg, #f5f7fa 0%, #c3cfe2 100%);
padding: 20px;
box-sizing: border-box;
}
.order-item {
background: white;
margin-bottom: 16px;
padding: 20px;
cursor: pointer;
transition: all 0.2s;
border-radius: 12px;
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.05);
position: relative;
overflow: hidden;
&::before {
content: '';
position: absolute;
top: 0;
left: 0;
bottom: 0;
width: 4px;
background: linear-gradient(90deg, #1989fa, #07c160);
}
&:active {
transform: translateY(2px);
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
}
&:hover {
box-shadow: 0 6px 16px rgba(0, 0, 0, 0.1);
}
}
.order-header {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 16px;
padding-bottom: 12px;
border-bottom: 1px solid #f0f0f0;
}
.order-code {
font-size: 16px;
font-weight: 600;
color: #333;
}
.status-tag {
font-size: 12px;
padding: 4px 10px;
border-radius: 20px;
font-weight: 500;
&.pending {
background-color: #FFF7E6;
color: #FA8C16;
}
&.approved {
background-color: #F6FFED;
color: #52C41A;
}
&.rejected {
background-color: #FFF2F0;
color: #FF4D4F;
}
}
.order-info {
.info-row {
display: flex;
margin-bottom: 12px;
&:last-child {
margin-bottom: 0;
}
.label {
width: 80px;
color: #666;
font-size: 14px;
flex-shrink: 0;
}
.value {
flex: 1;
color: #333;
font-size: 14px;
word-break: break-all;
&.amount {
color: #FF6600;
font-weight: 600;
}
}
}
}
.empty-state {
padding: 60px 20px;
text-align: center;
:deep(.van-empty) {
.van-empty__image {
width: 120px;
height: 120px;
}
.van-empty__description {
font-size: 16px;
color: #666;
}
}
}
// 搜索栏样式优化
:deep(.van-search) {
margin-bottom: 16px;
border-radius: 12px;
overflow: hidden;
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.08);
.van-search__content {
background: white;
}
}
</style>