From a79bd2c500a142f4f64e081fcb337280d1df18e1 Mon Sep 17 00:00:00 2001 From: WindowBird <13870814+windows-bird@user.noreply.gitee.com> Date: Fri, 29 Aug 2025 15:33:14 +0800 Subject: [PATCH] =?UTF-8?q?vue2=E5=88=86=E9=A1=B5=E5=8A=A0=E8=BD=BD?= =?UTF-8?q?=E5=99=A8=E5=AE=9E=E7=8E=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../institutionalStructureDetail.js | 19 +- composables/winB_Pagination.js | 209 ++++++++++++++++++ pages/future/future.vue | 88 ++++++-- 3 files changed, 293 insertions(+), 23 deletions(-) create mode 100644 composables/winB_Pagination.js diff --git a/api/institutionalStructure/institutionalStructureDetail.js b/api/institutionalStructure/institutionalStructureDetail.js index 488f993..b2f13a1 100644 --- a/api/institutionalStructure/institutionalStructureDetail.js +++ b/api/institutionalStructure/institutionalStructureDetail.js @@ -10,6 +10,21 @@ export function getInstitutionalDetail(formedId) { return get("/app/formed/formedDetail", { formedId }); } -export function getProjectSchedule(formedId) { - return get("/app/article/listFormed", { formedId }); +// export function getProjectSchedule(formedId) { +// return get("/app/article/listFormed", { formedId }); +// } + +/** + * 获取建制数据列表 + * @param {Object} params - 查询参数 + * @param {number} params.pageNum - 页码 + * @param {number} params.pageSize - 每页数量 + * @returns {Promise} 返回项目进度数据 + */ +export function getProjectSchedule(params = {}) { + const defaultParams = { + pageNum: 1, + pageSize: 2, + }; + return get("/app/article/listFormed", { ...defaultParams, ...params }); } diff --git a/composables/winB_Pagination.js b/composables/winB_Pagination.js new file mode 100644 index 0000000..b9760ae --- /dev/null +++ b/composables/winB_Pagination.js @@ -0,0 +1,209 @@ +/** + * 分页管理工厂函数 (带winB_前缀) + * @param {Object} options - 配置选项 + * @param {Function} options.fetchData - 获取数据的API函数 + * @param {Object} options.defaultParams - 默认查询参数 + * @param {string} options.mode - 分页模式:'loadMore' 或 'pager' + * @param {number} options.pageSize - 每页数量 + * @returns {Object} Vue组件选项对象 + */ +export function createPagination(options = {}) { + const { + fetchData, + defaultParams = {}, + mode = "loadMore", + pageSize = 10, + } = options; + + return { + data() { + return { + // 基础状态 + winB_List: [], + winB_Loading: false, + winB_Error: null, + + // 分页参数 + winB_QueryParams: { + pageNum: 1, + pageSize, + ...defaultParams, + }, + + // 分页信息 + winB_Pagination: { + total: 0, + currentPage: 1, + pageSize, + totalPages: 0, + }, + + // 上拉加载相关 + winB_NoMore: false, + }; + }, + + computed: { + winB_HasData() { + return this.winB_List.length > 0; + }, + winB_IsEmpty() { + return !this.winB_Loading && this.winB_List.length === 0; + }, + winB_CanLoadMore() { + return mode === "loadMore" && !this.winB_NoMore && !this.winB_Loading; + }, + }, + + methods: { + /** + * 获取数据 + * @param {boolean} reset - 是否重置列表 + */ + async winB_GetList(reset = false) { + if (this.winB_Loading) return; + + if (reset) { + this.winB_List = []; + this.winB_QueryParams.pageNum = 1; + this.winB_NoMore = false; + } + + this.winB_Loading = true; + this.winB_Error = null; + + try { + const response = await fetchData(this.winB_QueryParams); + + if (!response || response.code !== 200) { + throw new Error(response?.message || "获取数据失败"); + } + + const { rows = [], total = 0 } = response; + + if (reset) { + this.winB_List = rows; + } else { + this.winB_List = [...this.winB_List, ...rows]; + } + + // 更新分页信息 + this.winB_Pagination = { + total, + + currentPage: this.winB_QueryParams.pageNum, + pageSize, + totalPages: Math.ceil(total / pageSize), + }; + + // 检查是否还有更多数据 + if (mode === "loadMore") { + this.winB_NoMore = + this.winB_QueryParams.pageNum * pageSize >= total; + console.log( + `noMore状态: ${this.winB_NoMore}, 当前页: ${this.winB_QueryParams.pageNum}, 每页: ${pageSize}, 总数: ${total}`, + ); + } + + console.log( + `获取数据成功: 第${this.winB_QueryParams.pageNum}页,共${rows.length}条`, + ); + } catch (err) { + console.error("获取数据失败:", err); + this.winB_Error = err; + + // 显示错误提示 + if (typeof uni !== "undefined") { + uni.showToast({ + title: "数据加载失败", + icon: "none", + }); + } + } finally { + this.winB_Loading = false; + } + }, + + /** + * 刷新数据 + */ + winB_Refresh() { + this.winB_GetList(true); + }, + + /** + * 加载下一页(上拉加载模式) + */ + winB_LoadMore() { + if (!this.winB_CanLoadMore) return 0; + + this.winB_QueryParams.pageNum++; + this.winB_GetList(); + }, + + /** + * 跳转到指定页(分页器模式) + * @param {number} page - 目标页码 + */ + winB_GoToPage(page) { + if ( + page < 1 || + page > this.winB_Pagination.totalPages || + page === this.winB_QueryParams.pageNum + ) { + return; + } + + this.winB_QueryParams.pageNum = page; + this.winB_GetList(true); + }, + + /** + * 重置分页状态 + */ + winB_Reset() { + this.winB_List = []; + this.winB_Loading = false; + this.winB_Error = null; + this.winB_NoMore = false; + this.winB_QueryParams.pageNum = 1; + this.winB_Pagination = { + total: 0, + currentPage: 1, + pageSize, + totalPages: 0, + }; + }, + + /** + * 更新查询参数 + * @param {Object} newParams - 新的查询参数 + */ + winB_UpdateParams(newParams) { + this.winB_QueryParams = { + ...this.winB_QueryParams, + ...newParams, + pageNum: 1, // 重置页码 + }; + this.winB_Reset(); + this.winB_GetList(); + }, + + /** + * 格式化日期 + * @param {string} dateString - 日期字符串 + * @returns {string} 格式化后的日期 + */ + winB_FormatDate(dateString) { + if (!dateString) return "未知"; + const date = new Date(dateString); + return `${date.getFullYear()}.${String(date.getMonth() + 1).padStart(2, "0")}.${String(date.getDate()).padStart(2, "0")}`; + }, + }, + + created() { + // 初始化时加载第一页数据 + this.winB_GetList(); + }, + }; +} diff --git a/pages/future/future.vue b/pages/future/future.vue index 431e260..21616a5 100644 --- a/pages/future/future.vue +++ b/pages/future/future.vue @@ -46,7 +46,7 @@ 最新进展 @@ -70,7 +70,10 @@ > - 查看更多{{ listData.length }}条数据 + 查看更多{{ remainingItems }}条进展 + + 到底了 @@ -84,8 +87,16 @@ import { getInstitutionalDetail, getProjectSchedule, } from "../../api/institutionalStructure/institutionalStructureDetail"; +import { createPagination } from "../../composables/winB_Pagination"; export default { + mixins: [ + createPagination({ + fetchData: getProjectSchedule, + mode: "loadMore", + pageSize: 2, + }), + ], components: {}, data() { return { @@ -120,7 +131,7 @@ export default { { id: "18", templeId: "12", - title: "施工情况02", + title: "施工情况01", content: "

施工情况02施工情况02...

", status: "1", templeName: "寒山寺", @@ -137,6 +148,46 @@ export default { createTime: "2025-07-09 13:50:57", coverUrl: "https://api.ccttiot.com/IMG01-1751968117197.jpg", }, + { + id: "19", + templeId: "12", + title: "施工情况01232", + content: "

施工情况02施工情况02...

", + status: "1", + templeName: "寒山寺", + createTime: "2025-07-09 13:50:57", + coverUrl: "https://api.ccttiot.com/IMG01-1751968117197.jpg", + }, + { + id: "19", + templeId: "12", + title: "施工情况01232", + content: "

施工情况02施工情况02...

", + status: "1", + templeName: "寒山寺", + createTime: "2025-07-09 13:50:57", + coverUrl: "https://api.ccttiot.com/IMG01-1751968117197.jpg", + }, + { + id: "19", + templeId: "12", + title: "施工情况01232", + content: "

施工情况02施工情况02...

", + status: "1", + templeName: "寒山寺", + createTime: "2025-07-09 13:50:57", + coverUrl: "https://api.ccttiot.com/IMG01-1751968117197.jpg", + }, + { + id: "19", + templeId: "12", + title: "施工情况01232", + content: "

施工情况02施工情况02...

", + status: "1", + templeName: "寒山寺", + createTime: "2025-07-09 13:50:57", + coverUrl: "https://api.ccttiot.com/IMG01-1751968117197.jpg", + }, ], }; }, @@ -148,15 +199,14 @@ export default { } // 页面加载时获取数据 this.loadPageData(); + this.winB_GetList(); }, methods: { // 加载页面数据 async loadPageData() { try { - // 并行请求优化(如果两个请求无依赖关系) - const [detailResponse, scheduleResponse] = await Promise.all([ + const [detailResponse] = await Promise.all([ getInstitutionalDetail(this.formedId), - getProjectSchedule(this.formedId), ]); // 处理机构详情数据 @@ -169,28 +219,13 @@ export default { icon: "none", }); } - // 处理项目进度数据 - if (scheduleResponse?.code === 200) { - console.log("123:", scheduleResponse.rows); - this.listData = scheduleResponse.rows; - } else { - console.warn("获取项目进度失败:", scheduleResponse?.message); - uni.showToast({ - title: "获取进度失败", - icon: "none", - }); - } } catch (error) { console.error("获取页面数据失败:", error); uni.showToast({ title: "数据加载失败", icon: "none", }); - - // 可选:重试逻辑 - // setTimeout(() => this.loadPageData(), 2000); } finally { - // 可以在这里关闭加载状态 this.loading = false; } }, @@ -205,6 +240,17 @@ export default { return formattedHtml; }, + loadMore() { + this.winB_LoadMore(); + }, + }, + computed: { + remainingItems() { + return ( + this.winB_Pagination.total - + this.winB_Pagination.currentPage * this.winB_Pagination.pageSize + ); + }, }, };