任务列表分页器的实现

This commit is contained in:
WindowBird 2025-11-13 09:48:26 +08:00
parent 423034bf8b
commit c7ba580670
3 changed files with 131 additions and 84 deletions

View File

@ -10,14 +10,16 @@
* @param {number[]} params.statusList 任务状态列表4对应已完成
* @param {string} params.expireTimeStart 过期时间开始范围格式yyyy-MM-dd HH:mm:ss
* @param {string} params.expireTimeEnd 过期时间结束范围格式yyyy-MM-dd HH:mm:ss
* @param {number} params.pageNum 页码
* @param {number} params.pageSize 每页数量
* @returns {Promise} 返回任务列表
*/
export const getTaskList = ({ownerId, overdue, statusList, expireTimeStart, expireTimeEnd }) => {
export const getTaskList = ({ownerId, overdue, statusList, expireTimeStart, expireTimeEnd, pageNum, pageSize }) => {
const queryParams = [];
if (overdue !== undefined) {
queryParams.push(`overdue=${overdue}`);
}
if (ownerId !== undefined) {
if (ownerId !== undefined && ownerId !== '') {
queryParams.push(`ownerId=${ownerId}`);
}
if (statusList !== undefined && Array.isArray(statusList) && statusList.length > 0) {
@ -30,6 +32,13 @@ export const getTaskList = ({ownerId, overdue, statusList, expireTimeStart, expi
if (expireTimeEnd !== undefined && expireTimeEnd !== null && expireTimeEnd !== '') {
queryParams.push(`expireTimeEnd=${encodeURIComponent(expireTimeEnd)}`);
}
// 添加分页参数
if (pageNum !== undefined) {
queryParams.push(`pageNum=${pageNum}`);
}
if (pageSize !== undefined) {
queryParams.push(`pageSize=${pageSize}`);
}
const queryString = queryParams.length > 0 ? `?${queryParams.join('&')}` : '';
return uni.$uv.http.get(`bst/task/list${queryString}`, {

View File

@ -430,7 +430,7 @@ onUnmounted(() => {
});
// onReachBottom
const winB_LoadMore = () => {
const winB_LoadMore= () => {
if (!loading.value && !noMore.value) {
loadMore();
}

View File

@ -1,16 +1,19 @@
<template>
<view class="task-list-page">
<scroll-view class="task-scroll" scroll-y>
<scroll-view
class="task-scroll"
scroll-y
@scrolltolower="handleScrollToLower"
>
<view class="task-container">
<!-- 任务卡片列表 -->
<template v-if="!loading">
<view
class="task-card"
v-for="task in tasks"
:key="task.id"
:class="getTaskCardClass(task.status)"
@click="goToTaskDetail(task)"
>
<view
class="task-card"
v-for="task in tasks"
:key="task.id"
:class="getTaskCardClass(task.status)"
@click="goToTaskDetail(task)"
>
<!-- 状态标签和日期 -->
<view class="task-header">
<view style="display: flex;align-items: center;gap: 12px">
@ -54,15 +57,11 @@
<text class="countdown-text" :class="getCountdownClass(task.status)">
{{ task.remainingDays < 0 ? `已逾期${Math.abs(task.remainingDays)}` : `剩余${task.remainingDays}` }}
</text>
</view>
</view>
</view>
</view>
</view>
</template>
</view>
<!-- 加载状态 -->
<view class="empty-state" v-if="loading">
@ -70,28 +69,54 @@
</view>
<!-- 空状态 -->
<view class="empty-state" v-else-if="tasks.length === 0">
<view class="empty-state" v-else-if="isEmpty">
<text class="empty-text">暂无{{ getStatusText(statusFilter) || '' }}任务</text>
</view>
<!-- 加载更多提示 -->
<view class="load-more-tip" v-if="!isEmpty && !loading && !noMore">
<text class="load-more-text">上拉加载更多</text>
</view>
<view class="load-more-tip" v-if="!isEmpty && noMore">
<text class="load-more-text">没有更多数据了</text>
</view>
</view>
</scroll-view>
</view>
</template>
<script setup>
import { ref } from 'vue';
import { ref, computed, watch } from 'vue';
import { onLoad } from '@dcloudio/uni-app';
import { getStatusText, getTaskStatusType, getTaskStatusStyle } from '@/utils/taskConfig.js';
import { getTaskList } from '@/api';
import {getTaskList} from '@/api';
import { useTaskStore } from '@/store/task';
import {truncateText} from "@/utils/textSolve/truncateText";
import {useUserStore} from "@/store/user";
import {usePagination} from "@/composables";
const userStore = useUserStore();
const {
list,
noMore,
isEmpty,
loading,
getList,
loadMore,
updateParams,
refresh,
queryParams,
reset
} = usePagination({
fetchData: getTaskList,
mode: 'loadMore',
pageSize: 10,
defaultParams: {}
});
//
const statusFilter = ref('');
const loading = ref(false);
//
const statusMap = {
@ -109,8 +134,17 @@ const statusReverseMap = {
'逾期任务': 'overdue'
};
//
const tasks = ref([]);
// list
const tasks = computed(() => {
let transformedTasks = list.value.map(item => transformTaskData(item));
// status === 4
if (statusFilter.value === 'overdue') {
transformedTasks = transformedTasks.filter(task => task.status !== 'completed');
}
return transformedTasks;
});
// 使
const getTagCustomStyle = (status) => {
@ -318,69 +352,62 @@ const transformTaskData = (item) => {
};
};
//
const loadTaskList = async () => {
try {
loading.value = true;
let res;
let userId= useUserStore().getUserInfo.user.userId
let privateView= useUserStore().privateView
let ownerId = userId && privateView ? userId:''
//
if (statusFilter.value === 'completed') {
res = await getTaskList({ statusList: [4], ownerId: ownerId });
} else if (statusFilter.value === 'overdue') {
res = await getTaskList({ statusList: [2],overdue: true, ownerId: ownerId });
} else if (statusFilter.value === 'pending') {
res = await getTaskList({ statusList: [2], ownerId: ownerId });
} else if (statusFilter.value === 'imminent') {
const dateRange = getImminentDateRange();
res = await getTaskList({
ownerId: ownerId,
statusList: [2],
expireTimeStart: dateRange.expireTimeStart,
expireTimeEnd: dateRange.expireTimeEnd
});
} else {
res = await getTaskList({});
}
console.log('任务列表加载成功:', res);
//
let taskList = [];
if (res && res.rows && Array.isArray(res.rows)) {
taskList = res.rows;
} else if (res && res.data && Array.isArray(res.data)) {
taskList = res.data;
} else if (res && Array.isArray(res)) {
taskList = res;
}
//
let transformedTasks = taskList.map(item => transformTaskData(item));
// status === 4
// transformTaskData status === 4 status === 'completed'
if (statusFilter.value === 'overdue') {
transformedTasks = transformedTasks.filter(task => task.status !== 'completed');
}
tasks.value = transformedTasks;
} catch (err) {
console.error('加载任务列表失败:', err);
uni.showToast({
title: '加载数据失败',
icon: 'none'
});
tasks.value = [];
} finally {
loading.value = false;
//
const getQueryParams = () => {
const userId = userStore.getUserInfo?.user?.userId || userStore.getUserInfo?.userId;
const privateView = userStore.privateView;
const ownerId = userId && privateView ? userId : '';
//
if (statusFilter.value === 'completed') {
return { statusList: [4], ownerId: ownerId };
} else if (statusFilter.value === 'overdue') {
return { statusList: [2], overdue: true, ownerId: ownerId };
} else if (statusFilter.value === 'pending') {
return { statusList: [2], ownerId: ownerId };
} else if (statusFilter.value === 'imminent') {
const dateRange = getImminentDateRange();
return {
ownerId: ownerId,
statusList: [2],
expireTimeStart: dateRange.expireTimeStart,
expireTimeEnd: dateRange.expireTimeEnd
};
} else {
return { ownerId: ownerId };
}
};
//
const loadTaskList = async () => {
const params = getQueryParams();
updateParams(params);
};
//
const handleScrollToLower = () => {
if (!noMore.value && !loading.value) {
loadMore();
}
};
// watch onLoad
const isInitialized = ref(false);
// statusFilter
watch(statusFilter, () => {
if (isInitialized.value) {
loadTaskList();
}
});
//
watch(() => userStore.privateView, () => {
if (isInitialized.value) {
loadTaskList();
}
});
//
onLoad((options) => {
//
@ -398,7 +425,8 @@ onLoad((options) => {
});
}
//
//
isInitialized.value = true;
loadTaskList();
});
</script>
@ -571,5 +599,15 @@ onLoad((options) => {
font-size: 14px;
color: #999;
}
.load-more-tip {
padding: 20px;
text-align: center;
}
.load-more-text {
font-size: 12px;
color: #999;
}
</style>