任务列表分页器的实现

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 {number[]} params.statusList 任务状态列表4对应已完成
* @param {string} params.expireTimeStart 过期时间开始范围格式yyyy-MM-dd HH:mm:ss * @param {string} params.expireTimeStart 过期时间开始范围格式yyyy-MM-dd HH:mm:ss
* @param {string} params.expireTimeEnd 过期时间结束范围格式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} 返回任务列表 * @returns {Promise} 返回任务列表
*/ */
export const getTaskList = ({ownerId, overdue, statusList, expireTimeStart, expireTimeEnd }) => { export const getTaskList = ({ownerId, overdue, statusList, expireTimeStart, expireTimeEnd, pageNum, pageSize }) => {
const queryParams = []; const queryParams = [];
if (overdue !== undefined) { if (overdue !== undefined) {
queryParams.push(`overdue=${overdue}`); queryParams.push(`overdue=${overdue}`);
} }
if (ownerId !== undefined) { if (ownerId !== undefined && ownerId !== '') {
queryParams.push(`ownerId=${ownerId}`); queryParams.push(`ownerId=${ownerId}`);
} }
if (statusList !== undefined && Array.isArray(statusList) && statusList.length > 0) { 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 !== '') { if (expireTimeEnd !== undefined && expireTimeEnd !== null && expireTimeEnd !== '') {
queryParams.push(`expireTimeEnd=${encodeURIComponent(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('&')}` : ''; const queryString = queryParams.length > 0 ? `?${queryParams.join('&')}` : '';
return uni.$uv.http.get(`bst/task/list${queryString}`, { return uni.$uv.http.get(`bst/task/list${queryString}`, {

View File

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

View File

@ -1,16 +1,19 @@
<template> <template>
<view class="task-list-page"> <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"> <view class="task-container">
<!-- 任务卡片列表 --> <!-- 任务卡片列表 -->
<template v-if="!loading"> <view
<view class="task-card"
class="task-card" v-for="task in tasks"
v-for="task in tasks" :key="task.id"
:key="task.id" :class="getTaskCardClass(task.status)"
:class="getTaskCardClass(task.status)" @click="goToTaskDetail(task)"
@click="goToTaskDetail(task)" >
>
<!-- 状态标签和日期 --> <!-- 状态标签和日期 -->
<view class="task-header"> <view class="task-header">
<view style="display: flex;align-items: center;gap: 12px"> <view style="display: flex;align-items: center;gap: 12px">
@ -54,15 +57,11 @@
<text class="countdown-text" :class="getCountdownClass(task.status)"> <text class="countdown-text" :class="getCountdownClass(task.status)">
{{ task.remainingDays < 0 ? `已逾期${Math.abs(task.remainingDays)}` : `剩余${task.remainingDays}` }} {{ task.remainingDays < 0 ? `已逾期${Math.abs(task.remainingDays)}` : `剩余${task.remainingDays}` }}
</text> </text>
</view> </view>
</view> </view>
</view> </view>
</view> </view>
</view>
</view>
</template>
<!-- 加载状态 --> <!-- 加载状态 -->
<view class="empty-state" v-if="loading"> <view class="empty-state" v-if="loading">
@ -70,28 +69,54 @@
</view> </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> <text class="empty-text">暂无{{ getStatusText(statusFilter) || '' }}任务</text>
</view> </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> </view>
</scroll-view> </scroll-view>
</view> </view>
</template> </template>
<script setup> <script setup>
import { ref } from 'vue'; import { ref, computed, watch } from 'vue';
import { onLoad } from '@dcloudio/uni-app'; import { onLoad } from '@dcloudio/uni-app';
import { getStatusText, getTaskStatusType, getTaskStatusStyle } from '@/utils/taskConfig.js'; import { getStatusText, getTaskStatusType, getTaskStatusStyle } from '@/utils/taskConfig.js';
import { getTaskList } from '@/api'; import {getTaskList} from '@/api';
import { useTaskStore } from '@/store/task'; import { useTaskStore } from '@/store/task';
import {truncateText} from "@/utils/textSolve/truncateText"; import {truncateText} from "@/utils/textSolve/truncateText";
import {useUserStore} from "@/store/user"; 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 statusFilter = ref('');
const loading = ref(false);
// //
const statusMap = { const statusMap = {
@ -109,8 +134,17 @@ const statusReverseMap = {
'逾期任务': 'overdue' '逾期任务': 'overdue'
}; };
// // list
const tasks = ref([]); 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) => { const getTagCustomStyle = (status) => {
@ -318,69 +352,62 @@ const transformTaskData = (item) => {
}; };
}; };
// //
const loadTaskList = async () => { const getQueryParams = () => {
try { const userId = userStore.getUserInfo?.user?.userId || userStore.getUserInfo?.userId;
loading.value = true; const privateView = userStore.privateView;
let res; const ownerId = userId && privateView ? userId : '';
let userId= useUserStore().getUserInfo.user.userId //
let privateView= useUserStore().privateView if (statusFilter.value === 'completed') {
let ownerId = userId && privateView ? userId:'' return { statusList: [4], ownerId: ownerId };
// } else if (statusFilter.value === 'overdue') {
if (statusFilter.value === 'completed') { return { statusList: [2], overdue: true, ownerId: ownerId };
res = await getTaskList({ statusList: [4], ownerId: ownerId }); } else if (statusFilter.value === 'pending') {
} else if (statusFilter.value === 'overdue') { return { statusList: [2], ownerId: ownerId };
res = await getTaskList({ statusList: [2],overdue: true, ownerId: ownerId }); } else if (statusFilter.value === 'imminent') {
} else if (statusFilter.value === 'pending') { const dateRange = getImminentDateRange();
res = await getTaskList({ statusList: [2], ownerId: ownerId }); return {
} else if (statusFilter.value === 'imminent') { ownerId: ownerId,
const dateRange = getImminentDateRange(); statusList: [2],
res = await getTaskList({ expireTimeStart: dateRange.expireTimeStart,
ownerId: ownerId, expireTimeEnd: dateRange.expireTimeEnd
statusList: [2], };
expireTimeStart: dateRange.expireTimeStart, } else {
expireTimeEnd: dateRange.expireTimeEnd return { ownerId: ownerId };
});
} 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 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) => { onLoad((options) => {
// //
@ -398,7 +425,8 @@ onLoad((options) => {
}); });
} }
// //
isInitialized.value = true;
loadTaskList(); loadTaskList();
}); });
</script> </script>
@ -571,5 +599,15 @@ onLoad((options) => {
font-size: 14px; font-size: 14px;
color: #999; color: #999;
} }
.load-more-tip {
padding: 20px;
text-align: center;
}
.load-more-text {
font-size: 12px;
color: #999;
}
</style> </style>