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,265 @@
<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>