feat: 新增订单列表交互

This commit is contained in:
duanshuwen
2025-07-27 18:08:06 +08:00
parent 87bdac8c57
commit 4cd0f59966
31 changed files with 3535 additions and 2559 deletions

View File

@@ -0,0 +1,322 @@
<template>
<view class="demo-container">
<view class="demo-header">
<text class="demo-title">OrderList组件演示</text>
<text class="demo-subtitle">集成z-paging组件支持虚拟列表下拉刷新上拉加载更多</text>
</view>
<!-- 功能控制区 -->
<view class="control-section">
<view class="control-row">
<button class="control-btn" @click="toggleVirtualList">
{{ useVirtualList ? '关闭' : '开启' }}虚拟列表
</button>
<button class="control-btn" @click="toggleEmptyState">
{{ showEmpty ? '显示数据' : '显示空状态' }}
</button>
</view>
<view class="control-row">
<button class="control-btn" @click="addMoreData">
添加更多数据
</button>
<button class="control-btn" @click="clearData">
清空数据
</button>
</view>
</view>
<!-- OrderList组件演示 -->
<view class="demo-list">
<OrderList
:orderList="orderList"
:hasMore="hasMore"
:isLoading="isLoading"
:currentTab="currentTab"
:emptyText="emptyText"
:useVirtualList="useVirtualList"
:virtualListHeight="'500px'"
:cellHeightMode="cellHeightMode"
:fixedHeight="120"
@refresh="handleRefresh"
@loadMore="handleLoadMore"
@orderClick="handleOrderClick"
@orderCall="handleOrderCall"
@orderComplete="handleOrderComplete"
/>
</view>
<!-- 功能说明 -->
<view class="feature-section">
<text class="feature-title">新功能特性</text>
<view class="feature-list">
<text class="feature-item"> 集成z-paging组件</text>
<text class="feature-item"> 支持虚拟列表提升大数据渲染性能</text>
<text class="feature-item"> 自定义下拉刷新样式和文案</text>
<text class="feature-item"> 自定义上拉加载更多样式和文案</text>
<text class="feature-item"> 自动管理空数据状态</text>
<text class="feature-item"> 支持固定高度和自适应高度模式</text>
<text class="feature-item"> 完整的事件回调机制</text>
<text class="feature-item"> 响应式设计适配各种屏幕</text>
</view>
</view>
</view>
</template>
<script setup>
import { ref, computed } from 'vue'
import OrderList from './index.vue'
// 响应式数据
const orderList = ref([])
const hasMore = ref(true)
const isLoading = ref(false)
const currentTab = ref('all')
const useVirtualList = ref(true)
const cellHeightMode = ref('auto')
const showEmpty = ref(false)
// 计算属性
const emptyText = computed(() => {
return showEmpty.value ? '暂无数据,点击刷新重试' : '暂无工单数据'
})
// 模拟数据
const generateMockData = (count = 10, startId = 1) => {
const data = []
for (let i = 0; i < count; i++) {
data.push({
id: `${startId + i}`,
title: `工单标题 ${startId + i} - ${['空调维修', '水管漏水', '电路故障', '网络异常', '设备更换'][i % 5]}`,
createTime: new Date(Date.now() - Math.random() * 7 * 24 * 60 * 60 * 1000).toLocaleString(),
contactName: ['张先生', '李女士', '王先生', '赵女士', '刘先生'][i % 5],
contactPhone: `138****${String(Math.floor(Math.random() * 10000)).padStart(4, '0')}`,
status: ['pending', 'processing', 'completed'][i % 3],
type: 'service'
})
}
return data
}
// 初始化数据
const initData = () => {
orderList.value = generateMockData(20)
}
// 切换虚拟列表
const toggleVirtualList = () => {
useVirtualList.value = !useVirtualList.value
uni.showToast({
title: `虚拟列表已${useVirtualList.value ? '开启' : '关闭'}`,
icon: 'none'
})
}
// 切换空状态
const toggleEmptyState = () => {
showEmpty.value = !showEmpty.value
if (showEmpty.value) {
orderList.value = []
hasMore.value = false
} else {
initData()
hasMore.value = true
}
}
// 添加更多数据
const addMoreData = () => {
const newData = generateMockData(10, orderList.value.length + 1)
orderList.value.push(...newData)
uni.showToast({
title: '已添加10条数据',
icon: 'success'
})
}
// 清空数据
const clearData = () => {
orderList.value = []
hasMore.value = false
uni.showToast({
title: '数据已清空',
icon: 'none'
})
}
// 下拉刷新
const handleRefresh = async () => {
console.log('下拉刷新')
isLoading.value = true
// 模拟网络请求
await new Promise(resolve => setTimeout(resolve, 1500))
// 重新加载数据
orderList.value = generateMockData(15)
hasMore.value = true
isLoading.value = false
uni.showToast({
title: '刷新成功',
icon: 'success'
})
}
// 上拉加载更多
const handleLoadMore = async () => {
console.log('上拉加载更多')
if (!hasMore.value) return
// 模拟网络请求
await new Promise(resolve => setTimeout(resolve, 1000))
// 添加新数据
const newData = generateMockData(10, orderList.value.length + 1)
orderList.value.push(...newData)
// 模拟没有更多数据
if (orderList.value.length >= 50) {
hasMore.value = false
}
uni.showToast({
title: `加载了${newData.length}条数据`,
icon: 'none'
})
}
// 工单点击
const handleOrderClick = (orderData) => {
console.log('点击工单:', orderData)
uni.showToast({
title: `点击了工单: ${orderData.title}`,
icon: 'none'
})
}
// 工单呼叫
const handleOrderCall = (orderData) => {
console.log('呼叫工单:', orderData)
uni.showToast({
title: `呼叫: ${orderData.contactName}`,
icon: 'none'
})
}
// 工单完成
const handleOrderComplete = (orderData) => {
console.log('完成工单:', orderData)
// 更新状态
const index = orderList.value.findIndex(item => item.id === orderData.id)
if (index !== -1) {
orderList.value[index].status = 'completed'
}
uni.showToast({
title: '工单已标记为完成',
icon: 'success'
})
}
// 初始化
initData()
</script>
<style scoped lang="scss">
.demo-container {
padding: 20rpx;
background-color: #f5f5f5;
min-height: 100vh;
}
.demo-header {
text-align: center;
margin-bottom: 40rpx;
.demo-title {
display: block;
font-size: 36rpx;
font-weight: bold;
color: #333;
margin-bottom: 10rpx;
}
.demo-subtitle {
display: block;
font-size: 26rpx;
color: #666;
line-height: 1.5;
}
}
.control-section {
background: white;
border-radius: 16rpx;
padding: 30rpx;
margin-bottom: 30rpx;
box-shadow: 0 4rpx 20rpx rgba(0, 0, 0, 0.1);
.control-row {
display: flex;
gap: 20rpx;
margin-bottom: 20rpx;
&:last-child {
margin-bottom: 0;
}
}
.control-btn {
flex: 1;
padding: 20rpx;
background: linear-gradient(135deg, #007aff 0%, #0056cc 100%);
color: white;
border: none;
border-radius: 12rpx;
font-size: 26rpx;
transition: all 0.3s ease;
&:active {
transform: scale(0.95);
background: linear-gradient(135deg, #0056cc 0%, #003d99 100%);
}
}
}
.demo-list {
height: 500px;
background: white;
border-radius: 16rpx;
overflow: hidden;
margin-bottom: 30rpx;
box-shadow: 0 4rpx 20rpx rgba(0, 0, 0, 0.1);
}
.feature-section {
background: white;
border-radius: 16rpx;
padding: 30rpx;
box-shadow: 0 4rpx 20rpx rgba(0, 0, 0, 0.1);
.feature-title {
display: block;
font-size: 32rpx;
font-weight: bold;
color: #333;
margin-bottom: 20rpx;
}
.feature-list {
display: flex;
flex-direction: column;
gap: 12rpx;
}
.feature-item {
font-size: 28rpx;
color: #666;
line-height: 1.5;
padding-left: 10rpx;
}
}
</style>