Files
YGChatCS/pages/order/components/OrderList/demo.vue
2025-07-27 18:08:06 +08:00

322 lines
7.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="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>