From 07e7a65ae5929df910f52375efd7d50a31a643d1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=99=88=E6=81=92=E6=88=90?= <962704835@qq.com> Date: Mon, 27 Oct 2025 17:50:50 +0800 Subject: [PATCH] =?UTF-8?q?=E5=85=A5=E4=BD=8F=E5=88=97=E8=A1=A8=E6=90=9C?= =?UTF-8?q?=E7=B4=A2=E5=8C=BA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- pages/dormitory/studentDormInfo/index.vue | 475 +++++++++++++++++++--- 1 file changed, 429 insertions(+), 46 deletions(-) diff --git a/pages/dormitory/studentDormInfo/index.vue b/pages/dormitory/studentDormInfo/index.vue index 5168be0..327479e 100644 --- a/pages/dormitory/studentDormInfo/index.vue +++ b/pages/dormitory/studentDormInfo/index.vue @@ -1,7 +1,7 @@ @@ -116,6 +169,9 @@ import { listAllCampus, listParkByCampus, + listBuildingByPark, + listFloorByBuilding, + listAllRoomByFloor, listStudent } from "@/api/dms/studentDormInfo/index.js" import { @@ -140,23 +196,39 @@ stuName: null, gradeId: null, campusId: null, - parkId:null, + parkId: null, + buildingId: null, + floorId: null, + dormitoryId: null, dormArea: null, // 宿舍区筛选参数 parkName: null // 园区筛选参数 }, dormInfo: [], isLoading: false, hasMore: true, + total: 0, // 存储接口返回的总数据条数 // 筛选下拉选项数据 gradeList: [], dormAreaList: [], parkList: [], + // 楼栋选项(按园区联动) + buildingOptions: [], + // 楼层选项(下拉框) + floorOptions: [], + // 宿舍号选项(下拉框) + dormOptions: [], // 筛选选中索引 gradeIndex: 0, dormAreaIndex: 0, parkIndex: 0, + buildingIndex: 0, + floorIndex: 0, + dormIndex: 0, searchTimer: null, - roleGroup: null + roleGroup: null, + // 存储搜索区高度(非学生有搜索区,学生无) + searchAreaHeight: 0, + } }, onShow() { @@ -165,6 +237,21 @@ this.getUserProfile() this.listGrade() this.listAllCampus() + this.scrollToTop() + // 页面渲染完成后,计算搜索区高度并设置内边距 + this.$nextTick(() => { + this.calcSearchAreaHeight() + this.setScrollContentPadding() + }) + }, + watch: { + // 监听角色变化,重新设置内边距(防止角色切换导致适配问题) + roleGroup() { + this.$nextTick(() => { + this.calcSearchAreaHeight() + this.setScrollContentPadding() + }) + } }, methods: { // 重置分页数据(用于刷新或重新加载) @@ -172,8 +259,57 @@ this.queryParams.pageNum = 1 this.dormInfo = [] this.hasMore = true + this.total = 0 // 重置总条数 }, + // 计算搜索区高度 + calcSearchAreaHeight() { + if (this.roleGroup !== '学生') { + const query = uni.createSelectorQuery().in(this) + query.select('.fixed-search-wrap') + .boundingClientRect(rect => { + // 转换rpx为px(1rpx≈0.5px,根据实际设备像素比调整) + this.searchAreaHeight = rect ? Math.ceil(rect.height) : 145 // 145px≈290rpx + }) + .exec() + } else { + this.searchAreaHeight = 0 + } + console.log(this.searchAreaHeight); + }, + + // 动态设置滚动内容的顶部内边距 + setScrollContentPadding() { + const scrollContent = document.querySelector('.scroll-content') + if (scrollContent) { + if (this.roleGroup !== '学生') { + // 非学生:内边距=搜索区高度 - 60rpx(额外间距) + const paddingTop = this.searchAreaHeight - 30 // 10px≈20rpx + scrollContent.style.paddingTop = `${paddingTop}px` + } else { + // 学生:内边距=20rpx(仅基础间距) + scrollContent.style.paddingTop = '10px' // 10px≈20rpx + } + } + }, + + // 滚动条回到顶部的方法 + scrollToTop() { + // 1. scroll-view 自身回顶 + if (this.$refs.scrollRef) { + this.$refs.scrollRef.scrollTo({ + scrollTop: 0, + duration: 300 + }) + } + // 2. 页面级回顶(兜底) + uni.pageScrollTo({ + scrollTop: 0, + duration: 300 + }) + }, + + // 查询列表数据 async getList() { if (this.isLoading || !this.hasMore) { @@ -187,13 +323,17 @@ const res = await listStudent(this.queryParams) if (res.code === 200) { const newData = res.rows || [] + this.total = res.total || 0 // 从接口获取总数据条数(需确保接口返回 total) + // 第一页覆盖数据,后续页追加 this.dormInfo = this.queryParams.pageNum === 1 ? newData : [...this.dormInfo, ...newData] - this.hasMore = newData.length === this.queryParams.pageSize + // 关键判断:当前已加载条数 >= 总条数 → 无更多数据 + this.hasMore = this.dormInfo.length < this.total } else { uni.showToast({ title: '加载失败', icon: 'none' }) + this.hasMore = false // 加载失败时停止后续请求 } } catch (err) { console.error('加载数据出错:', err) @@ -201,6 +341,7 @@ title: '网络错误', icon: 'none' }) + this.hasMore = false // 异常时停止后续请求 } finally { this.isLoading = false // 最终兜底:无论如何都停止刷新 @@ -309,6 +450,8 @@ this.queryParams.gradeId = selectedGrade.gradeId || null this.resetData() this.getList() + this.scrollToTop() + this.$nextTick(() => this.setScrollContentPadding()) }, // 宿舍区筛选 @@ -318,7 +461,9 @@ this.queryParams.campusId = selectedArea.id || null this.resetData() this.getList() - + this.resetDorm() + this.scrollToTop() + this.$nextTick(() => this.setScrollContentPadding()) if (this.queryParams.campusId) { // 根据校区id获取园区 let res = await listParkByCampus(this.queryParams.campusId) @@ -330,13 +475,119 @@ } }, + // 宿舍区选择,重置园区等其他选择 + resetDorm() { + this.parkList = [] + this.parkIndex = 0 + this.buildingOptions = [] + this.buildingIndex = 0 + this.floorIndex = 0 + this.floorOptions = [] + this.dormIndex = 0 + this.dormOptions = [] + }, + + // 判断是否选择上一个选项 + isDorm(data) { + if (data == '楼层') { + if (this.queryParams.buildingId == null) { + uni.showToast({ + title: '请先选择楼栋', + icon: 'none' + }); + return + } + } else if (data == '宿舍号') { + if (this.queryParams.floorId == null) { + uni.showToast({ + title: '请先选择楼层', + icon: 'none' + }); + return + } + } else { + if (this.queryParams.campusId == null) { + uni.showToast({ + title: '请先选择宿舍区', + icon: 'none' + }); + return + } + } + }, + // 园区筛选 - handleParkChange(e) { + async handleParkChange(e) { + this.parkIndex = e.detail.value const selectedPark = this.parkList[this.parkIndex] this.queryParams.parkId = selectedPark.id || null this.resetData() this.getList() + this.scrollToTop() + this.$nextTick(() => this.setScrollContentPadding()) + this.buildingOptions = [] + this.buildingIndex = 0 + this.floorIndex = 0 + this.floorOptions = [] + this.dormIndex = 0 + this.dormOptions = [] + + if (this.queryParams.parkId) { + // 根据园区id获取楼栋 + let res = await listBuildingByPark(this.queryParams.parkId) + if (res.code == 200) { + this.buildingOptions = [{ + name: '全部' + }, ...res.data] + } + } + }, + + // 楼栋筛选 + async handleBuildingChange(e) { + this.buildingIndex = e.detail.value + const selectedBuilding = this.buildingOptions[this.buildingIndex] + this.queryParams.buildingId = selectedBuilding.id || null + this.floorIndex = 0 + this.floorOptions = [] + this.dormIndex = 0 + this.dormOptions = [] + if (this.queryParams.buildingId) { + // 根据楼栋id获取楼层 + let res = await listFloorByBuilding(this.queryParams.buildingId) + if (res.code == 200) { + this.floorOptions = [{ + floor: '全部' + }, ...res.data] + + } + } + }, + + // 楼层筛选 + async handleFloorChange(e) { + this.floorIndex = e.detail.value + const selectedFloor = this.floorOptions[this.floorIndex] + this.queryParams.floorId = selectedFloor.id || null + this.dormIndex = 0 + this.dormOptions = [] + if (this.queryParams.floorId) { + // 根据楼栋id获取楼层 + let res = await listAllRoomByFloor(this.queryParams.floorId) + if (res.code == 200) { + this.dormOptions = [{ + roomNo: '全部' + }, ...res.data] + } + } + }, + + // 宿舍号筛选 + handleDormChange(e) { + this.dormIndex = e.detail.value + const selectedDorm = this.dormOptions[this.dormIndex] + this.queryParams.dormitoryId = selectedDorm.id || null }, // 重置筛选 @@ -344,6 +595,9 @@ this.gradeIndex = 0 this.dormAreaIndex = 0 this.parkIndex = 0 + this.buildingIndex = 0 + this.floorIndex = 0 + this.dormIndex = 0 // 重置筛选参数,保留分页基础参数 this.queryParams = { ...this.queryParams, @@ -351,17 +605,48 @@ dormArea: null, parkName: null, roomNo: null, - stuName: null + stuName: null, + campusId: null, + parkId: null, + buildingId: null, + floorId: null, + dormitoryId: null, + dormArea: null, // 宿舍区筛选参数 + parkName: null // 园区筛选参数 } this.resetData() this.getList() + this.scrollToTop() + this.$nextTick(() => this.setScrollContentPadding()) }, // 手动搜索 handleSearch() { this.resetData() this.getList() + this.scrollToTop() + this.$nextTick(() => this.setScrollContentPadding()) }, + addRecordsPopup() { + if (this.queryParams.parkId == null) { + uni.showToast({ + title: '请先选择园区', + icon: 'none' + }); + return + } + this.$refs.popupTime.open('center'); + }, + onCancel() { + this.$refs.popupTime.close(); + }, + topersonalReporting() { + this.resetData() + this.getList() + this.scrollToTop() + this.$nextTick(() => this.setScrollContentPadding()) + this.$refs.popupTime.close(); + } }, destroyed() { clearTimeout(this.searchTimer) @@ -373,23 +658,24 @@ .page-container { position: relative; height: 100vh; - padding-top: 44px; - /* 预留原生title高度 */ background-color: #f5f7fa; box-sizing: border-box; + /* 禁止页面滚动 */ + overflow: hidden; } - /* 固定搜索区:收缩时无空白 */ + /* 固定搜索区*/ .fixed-search-wrap { position: fixed; top: 44px; + /* 原生title高度 */ left: 0; right: 0; z-index: 90; background-color: #fff; - /* 背景改为白色,与页面融合 */ border-bottom: 1px solid #eee; padding: 14px; + box-sizing: border-box; } /* 触发器:样式简洁,点击区域大 */ @@ -422,10 +708,25 @@ /* 滚动容器:调整顶部内边距,适应搜索区高度变化 */ .scroll-container { - height: 100%; + position: absolute; + top: 44px; + /* 与原生title对齐 */ + left: 0; + right: 0; + bottom: 60px; + /* 预留添加按钮高度 */ width: 100%; - padding-top: 290rpx; - padding-bottom: 120rpx; + overflow-y: auto; + overflow-x: hidden; + } + + /* 滚动内容容器:处理内边距,避免内容被遮挡 */ + .scroll-content { + /* 底部预留加载状态高度 */ + padding-bottom: 40rpx; + /* 左右内边距 */ + padding-left: 20rpx; + padding-right: 20rpx; box-sizing: border-box; } @@ -448,7 +749,8 @@ } .dorm-list { - padding: 20rpx; + // padding: 20rpx; + padding: 0; } .dorm-item { @@ -606,4 +908,85 @@ .btn-icon { margin-right: 6rpx; } + + .popup-time, + .popup-audit { + width: 80%; + + .popup-content { + width: 600rpx; + height: 750rpx; + padding: 40rpx 50rpx 40rpx; + + .title { + text-align: center; + padding-bottom: 20rpx; + font-weight: bold; + font-size: 32rpx; + color: #3D3D3D; + border-bottom: 1px solid #F5F5F7; + } + + .form-item { + width: 100%; + margin-top: 40rpx; + padding: 0 50rpx; + + label { + font-weight: bold; + color: #202020; + } + + picker { + margin-top: 20rpx; + border: 1px solid darkgray; + height: 72rpx; + line-height: 72rpx; + padding-left: 8px; + border-radius: 10rpx; + + .uni-input { + display: flex; + color: #202020; + + .val { + flex: 1; + } + + .uni-icons { + margin: 0 20rpx; + opacity: 0.5; + } + } + } + } + + .btns { + display: flex; + margin-top: 50rpx; + position: absolute; + bottom: 0; + left: 0; + right: 0; + + button { + flex: 1; + border-radius: 0; + height: 80rpx; + line-height: 80rpx; + + &:first-child { + background-color: #ffffff; + border-top: 1px solid #F5F5F7; + } + + &:last-child { + background-color: #258FE4; + border-top: 1px solid #258FE4; + } + } + } + + } + } \ No newline at end of file