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

265 lines
6.2 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-list-container">
<!-- z-paging组件 -->
<z-paging
ref="paging"
v-model="dataList"
:refresher-enabled="true"
:refresher-threshold="45"
refresher-default-text="下拉刷新"
refresher-pulling-text="下拉刷新"
refresher-refreshing-text="正在刷新..."
refresher-complete-text="刷新完成"
:loading-more-enabled="true"
loading-more-default-text="点击加载更多"
loading-more-loading-text="正在加载..."
loading-more-no-more-text="没有更多了"
loading-more-fail-text="加载失败点击重试"
:empty-view-text="emptyText"
:empty-view-img="emptyIcon"
:auto="false"
:use-virtual-list="false"
:virtual-list-height="virtualListHeight"
:cell-height-mode="cellHeightMode"
:fixed-height="fixedHeight"
:safe-area-inset-top="true"
:use-page-scroll="true"
:top-offset="120"
@query="queryList"
@emptyViewReload="handleEmptyReload"
>
<!-- 非虚拟列表模式下的数据渲染 -->
<view class="order-list-content">
<OrderCard
v-for="(item, index) in currentDataList"
:key="item.id || index"
:orderData="item"
@click="handleOrderClick"
@call="handleOrderCall"
@complete="handleOrderComplete"
/>
</view>
<!-- 虚拟列表模式下的数据渲染 -->
<template #cell="{ item }" v-if="useVirtualList">
<OrderCard
:orderData="item"
@click="handleOrderClick"
@call="handleOrderCall"
@complete="handleOrderComplete"
/>
</template>
<!-- 自定义空状态 -->
<template #empty v-if="customEmptyView">
<view class="custom-empty">
<image :src="emptyIcon" class="empty-icon" />
<text class="empty-text">{{ emptyText }}</text>
<button
class="refresh-btn"
@click="handleEmptyReload"
v-if="showRefreshBtn"
>
刷新重试
</button>
</view>
</template>
</z-paging>
</view>
</template>
<script setup>
import { ref, defineProps, watch, onMounted, computed, nextTick } from "vue";
import OrderCard from "../OrderCard/index.vue";
// Props
const props = defineProps({
// 工单数据列表
orderList: {
type: Array,
default: () => [],
},
// 是否有更多数据
hasMore: {
type: Boolean,
default: true,
},
// 是否正在加载
isLoading: {
type: Boolean,
default: false,
},
// 空状态文案
emptyText: {
type: String,
default: "暂无工单数据",
},
// 空状态图标
emptyIcon: {
type: String,
default: "/static/images/empty.png",
},
// 是否显示刷新按钮
showRefreshBtn: {
type: Boolean,
default: true,
},
// 当前Tab类型
currentTab: {
type: String,
default: "all",
},
// 是否启用虚拟列表
useVirtualList: {
type: Boolean,
default: true,
},
// 虚拟列表高度
virtualListHeight: {
type: [String, Number],
default: "100%",
},
// 单元格高度模式
cellHeightMode: {
type: String,
default: "auto", // auto | fixed
},
// 固定高度当cellHeightMode为fixed时使用
fixedHeight: {
type: Number,
default: 120,
},
// 是否使用自定义空状态
customEmptyView: {
type: Boolean,
default: false,
},
});
// Emits
const emit = defineEmits([
"refresh",
"loadMore",
"orderClick",
"orderCall",
"orderComplete",
]);
// 响应式数据
const paging = ref(null);
const dataList = ref([]);
const pageNum = ref(1);
const pageSize = ref(10);
// 计算属性
const currentDataList = computed(() => {
return props.orderList || [];
});
// 查询列表数据
const queryList = async (pageNo, pageSize, from) => {
console.log("z-paging查询:", { pageNo, pageSize, from });
try {
// 触发父组件的数据加载事件
if (pageNo === 1) {
// 下拉刷新
emit("refresh");
} else {
// 上拉加载更多
emit("loadMore");
}
// 等待数据更新
await nextTick();
// 直接使用当前的orderList数据
const currentData = props.orderList || [];
// 在非虚拟列表模式下z-paging主要用于下拉刷新和上拉加载
// 数据渲染通过模板中的v-for完成
paging.value?.complete(currentData, !props.hasMore);
} catch (error) {
console.error("查询列表失败:", error);
paging.value?.complete(false);
}
};
// 处理空状态重新加载
const handleEmptyReload = () => {
console.log("空状态重新加载");
paging.value?.reload();
};
// 处理工单点击
const handleOrderClick = (orderData) => {
emit("orderClick", orderData);
};
// 处理工单呼叫
const handleOrderCall = (orderData) => {
emit("orderCall", orderData);
};
// 处理工单完成
const handleOrderComplete = (orderData) => {
emit("orderComplete", orderData);
};
// 监听orderList变化更新z-paging数据
watch(
() => props.orderList,
(newList) => {
if (newList && newList.length >= 0) {
dataList.value = [...newList];
// 在非虚拟列表模式下主要是通知z-paging数据已更新
if (paging.value) {
paging.value.complete(newList, !props.hasMore);
}
}
},
{ immediate: true, deep: true }
);
// 监听Tab切换重新加载数据
watch(
() => props.currentTab,
() => {
nextTick(() => {
paging.value?.reload();
});
}
);
// 组件挂载后初始化
onMounted(() => {
nextTick(() => {
// 初始化数据
if (currentDataList.value.length > 0) {
dataList.value = [...currentDataList.value];
// 手动触发z-paging的数据更新
if (paging.value) {
paging.value.complete(currentDataList.value, !props.hasMore);
}
} else {
// 如果没有初始数据,触发第一次查询
if (paging.value) {
paging.value.reload();
}
}
});
});
// 暴露方法
defineExpose({
reload: () => paging.value?.reload(),
refresh: () => paging.value?.reload(),
complete: (data, noMore) => paging.value?.complete(data, noMore),
getPaging: () => paging.value,
});
</script>
<style scoped lang="scss">
@import "./styles/index.scss";
</style>