Files
zhxg_app/pages/dormitory/studentDormInfo/index.vue

992 lines
24 KiB
Vue
Raw Normal View History

2025-10-24 17:45:57 +08:00
<template>
<view class="page-container">
2025-10-25 03:20:44 +08:00
<!-- 搜索区 -->
2025-10-27 17:50:50 +08:00
<view class="fixed-search-wrap" v-if="roleGroup != '学生'">
2025-10-25 03:20:44 +08:00
<!-- 搜索区内容 -->
<view class="search-content">
<view class="search-card">
<!-- 搜索输入框 -->
<view class="search-row">
<uni-icons type="search" size="28rpx" color="#1890FF" class="search-icon"></uni-icons>
<input v-model="queryParams.stuName" placeholder="输入学生姓名搜索" @input="handleSearchInput"
class="search-input" />
</view>
<!-- 筛选行 -->
<view class="filter-row">
<!-- 年级筛选 -->
<view class="filter-item">
<text class="filter-label">年级</text>
<picker mode="selector" :range="gradeList" :range-key="'gradeName'" :value="gradeIndex"
@change="handleGradeChange" class="filter-picker">
<view class="picker-content">
<!-- 添加空值判断 -->
<text
class="picker-text">{{ gradeList[gradeIndex] ? gradeList[gradeIndex].gradeName : '全部' }}</text>
<uni-icons type="bottom" size="20rpx" color="#999"></uni-icons>
</view>
</picker>
</view>
<!-- 宿舍区筛选 -->
<view class="filter-item">
<text class="filter-label">宿舍区</text>
<picker mode="selector" :range="dormAreaList" :range-key="'name'" :value="dormAreaIndex"
@change="handleDormAreaChange" class="filter-picker">
<view class="picker-content">
<text
class="picker-text">{{ dormAreaList[dormAreaIndex] ? dormAreaList[dormAreaIndex].name : '全部' }}</text>
<uni-icons type="bottom" size="20rpx" color="#999"></uni-icons>
</view>
</picker>
</view>
<!-- 园区筛选 -->
2025-10-27 17:50:50 +08:00
<view class="filter-item" @click="isDorm('')">
2025-10-25 03:20:44 +08:00
<text class="filter-label">园区</text>
2025-10-27 17:50:50 +08:00
<picker mode="selector" :range="parkList" :range-key="'name'" :value="parkIndex"
:disabled="!queryParams.campusId" @change="handleParkChange" class="filter-picker"
id="park">
2025-10-25 03:20:44 +08:00
<view class="picker-content">
2025-10-27 17:50:50 +08:00
<text
class="picker-text">{{ parkList[parkIndex] ? parkList[parkIndex].name : '全部' }}</text>
2025-10-25 03:20:44 +08:00
<uni-icons type="bottom" size="20rpx" color="#999"></uni-icons>
</view>
</picker>
</view>
<!-- 宿舍号筛选 -->
2025-10-27 17:50:50 +08:00
<view class="filter-item">
2025-10-25 03:20:44 +08:00
<text class="filter-label">宿舍号</text>
2025-10-27 17:50:50 +08:00
<view @click="addRecordsPopup" class="filter-input">
{{ dormOptions[dormIndex] ? dormOptions[dormIndex].roomNo : '请输入'}}
</view>
</view>
<uni-popup ref="popupTime" class="popup-time" background-color="#ffffff">
<view class="popup-content">
<view class="title">
宿舍号
</view>
<form @submit="topersonalReporting">
<view class="form-item">
<label>楼栋</label>
<picker range-key="name" :value="buildingIndex" :range="buildingOptions"
@change="handleBuildingChange">
<view class="uni-input">
<text
class="val">{{buildingOptions[buildingIndex] ? buildingOptions[buildingIndex].name : '全部'}}</text>
<uni-icons type="calendar" size="25" color="#202020"></uni-icons>
</view>
</picker>
</view>
<view class="form-item" @click="isDorm('楼层')">
<label>楼层</label>
<picker @change="handleFloorChange" :range="floorOptions" :range-key="'floor'"
:disabled="!queryParams.buildingId">
<view class="uni-input">
<text
class="val">{{floorOptions[floorIndex] ? floorOptions[floorIndex].floor : '全部'}}</text>
<uni-icons type="calendar" size="25" color="#202020"></uni-icons>
</view>
</picker>
</view>
<view class="form-item" @click="isDorm('宿舍号')">
<label>宿舍号</label>
<picker @change="handleDormChange" :range="dormOptions" :range-key="'roomNo'"
:disabled="!queryParams.floorId">
<view class="uni-input">
<text
class="val">{{dormOptions[dormIndex] ? dormOptions[dormIndex].roomNo : '全部'}}</text>
<uni-icons type="calendar" size="25" color="#202020"></uni-icons>
</view>
</picker>
</view>
<view class="btns">
<button type="default" @tap="onCancel">取消</button>
<button form-type="submit" type="primary">确定</button>
</view>
</form>
</view>
</uni-popup>
2025-10-25 03:20:44 +08:00
</view>
<!-- 操作按钮 -->
<view class="action-row">
<button class="reset-btn" @click="resetFilter">
<uni-icons type="clear" size="24rpx" color="#1890FF" class="btn-icon"></uni-icons>
重置
</button>
<button class="search-btn" @click="handleSearch">
<uni-icons type="search" size="24rpx" color="#fff" class="btn-icon"></uni-icons>
搜索
</button>
</view>
</view>
</view>
</view>
2025-10-24 17:45:57 +08:00
<!-- 添加信息收集按钮 -->
<view class="add" @click="addDormInfo">+</view>
2025-10-25 03:20:44 +08:00
<!-- 滚动容器 -->
2025-10-27 17:50:50 +08:00
<scroll-view ref="scrollRef" class="scroll-container" scroll-y @scrolltolower="loadNextPage"
@refresherrefresh="handleRefresh">
<view class="scroll-content">
<!-- 入住收集列表 -->
<view class="dorm-list">
<view class="dorm-item" v-for="(item, index) in dormInfo"
:key="`${item.id}_${Math.ceil((index + 1) / queryParams.pageSize)}`"
@click="handleItemClick(item)">
<view class="item-header">
<view class="name">姓名: {{ item.stuName }}</view>
<view class="tag" :class="item.isDormitoryHead === 1 ? 'head-tag' : ''">
{{ item.isDormitoryHead === 1 ? '宿舍长' : '' }}
</view>
2025-10-24 17:45:57 +08:00
</view>
2025-10-27 17:50:50 +08:00
<view class="item-content">
<view>学号: {{ item.stuNo }}</view>
<view>班级: {{ item.className }}</view>
<view>院系: {{ item.deptName }}</view>
<view>宿舍: {{ item.parkName }} {{ item.buildingName }}
{{ item.floorName }}{{ item.roomNo }}
</view>
<view>入住时间: {{ item.checkinTime }}</view>
<view>状态: {{ item.inStatus === '1' ? '已入住' : '未入住' }}</view>
2025-10-24 17:45:57 +08:00
</view>
</view>
</view>
2025-10-27 17:50:50 +08:00
<!-- 加载状态 -->
<view v-if="isLoading" class="loading">加载中...</view>
<view v-if="!hasMore && dormInfo.length > 0" class="no-more">已加载全部数据</view>
<view v-if="dormInfo.length === 0 && !isLoading" class="no-data">暂无数据</view>
</view>
2025-10-24 17:45:57 +08:00
</scroll-view>
</view>
</template>
<script>
import {
2025-10-25 03:20:44 +08:00
listAllCampus,
listParkByCampus,
2025-10-27 17:50:50 +08:00
listBuildingByPark,
listFloorByBuilding,
listAllRoomByFloor,
2025-10-24 17:45:57 +08:00
listStudent
} from "@/api/dms/studentDormInfo/index.js"
import {
getUserProfile
} from '@/api/system/user'
2025-10-25 03:20:44 +08:00
import {
listGrade
} from "@/api/dms/studentDormInfo/index.js"
2025-10-24 17:45:57 +08:00
export default {
data() {
return {
queryParams: {
pageNum: 1,
pageSize: 5, // 每页5条便于测试分页
dormitoryId: null,
bedId: null,
stuNo: null,
isDormitoryHead: null,
status: null,
checkinTime: null,
inStatus: null,
stuName: null,
2025-10-25 03:20:44 +08:00
gradeId: null,
campusId: null,
2025-10-27 17:50:50 +08:00
parkId: null,
buildingId: null,
floorId: null,
dormitoryId: null,
2025-10-25 03:20:44 +08:00
dormArea: null, // 宿舍区筛选参数
parkName: null // 园区筛选参数
2025-10-24 17:45:57 +08:00
},
dormInfo: [],
isLoading: false,
2025-10-25 03:20:44 +08:00
hasMore: true,
2025-10-27 17:50:50 +08:00
total: 0, // 存储接口返回的总数据条数
2025-10-25 03:20:44 +08:00
// 筛选下拉选项数据
gradeList: [],
dormAreaList: [],
parkList: [],
2025-10-27 17:50:50 +08:00
// 楼栋选项(按园区联动)
buildingOptions: [],
// 楼层选项(下拉框)
floorOptions: [],
// 宿舍号选项(下拉框)
dormOptions: [],
2025-10-25 03:20:44 +08:00
// 筛选选中索引
gradeIndex: 0,
dormAreaIndex: 0,
parkIndex: 0,
2025-10-27 17:50:50 +08:00
buildingIndex: 0,
floorIndex: 0,
dormIndex: 0,
2025-10-25 03:20:44 +08:00
searchTimer: null,
2025-10-27 17:50:50 +08:00
roleGroup: null,
// 存储搜索区高度(非学生有搜索区,学生无)
searchAreaHeight: 0,
2025-10-24 17:45:57 +08:00
}
},
onShow() {
// 每次显示页面时重置数据并重新加载
this.resetData()
this.getUserProfile()
2025-10-25 03:20:44 +08:00
this.listGrade()
this.listAllCampus()
2025-10-27 17:50:50 +08:00
this.scrollToTop()
// 页面渲染完成后,计算搜索区高度并设置内边距
this.$nextTick(() => {
this.calcSearchAreaHeight()
this.setScrollContentPadding()
})
},
watch: {
// 监听角色变化,重新设置内边距(防止角色切换导致适配问题)
roleGroup() {
this.$nextTick(() => {
this.calcSearchAreaHeight()
this.setScrollContentPadding()
})
}
2025-10-24 17:45:57 +08:00
},
methods: {
// 重置分页数据(用于刷新或重新加载)
resetData() {
this.queryParams.pageNum = 1
this.dormInfo = []
this.hasMore = true
2025-10-27 17:50:50 +08:00
this.total = 0 // 重置总条数
},
// 计算搜索区高度
calcSearchAreaHeight() {
if (this.roleGroup !== '学生') {
const query = uni.createSelectorQuery().in(this)
query.select('.fixed-search-wrap')
.boundingClientRect(rect => {
// 转换rpx为px1rpx≈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
}
}
2025-10-24 17:45:57 +08:00
},
2025-10-27 17:50:50 +08:00
// 滚动条回到顶部的方法
scrollToTop() {
// 1. scroll-view 自身回顶
if (this.$refs.scrollRef) {
this.$refs.scrollRef.scrollTo({
scrollTop: 0,
duration: 300
})
}
// 2. 页面级回顶(兜底)
uni.pageScrollTo({
scrollTop: 0,
duration: 300
})
},
2025-10-24 17:45:57 +08:00
// 查询列表数据
async getList() {
2025-10-25 03:20:44 +08:00
if (this.isLoading || !this.hasMore) {
// 若无需加载,直接停止刷新
uni.stopPullDownRefresh()
return
}
2025-10-24 17:45:57 +08:00
this.isLoading = true
try {
const res = await listStudent(this.queryParams)
if (res.code === 200) {
const newData = res.rows || []
2025-10-27 17:50:50 +08:00
this.total = res.total || 0 // 从接口获取总数据条数(需确保接口返回 total
// 第一页覆盖数据,后续页追加
2025-10-25 03:20:44 +08:00
this.dormInfo = this.queryParams.pageNum === 1 ? newData : [...this.dormInfo, ...newData]
2025-10-27 17:50:50 +08:00
// 关键判断:当前已加载条数 >= 总条数 → 无更多数据
this.hasMore = this.dormInfo.length < this.total
2025-10-24 17:45:57 +08:00
} else {
uni.showToast({
title: '加载失败',
icon: 'none'
})
2025-10-27 17:50:50 +08:00
this.hasMore = false // 加载失败时停止后续请求
2025-10-24 17:45:57 +08:00
}
} catch (err) {
console.error('加载数据出错:', err)
uni.showToast({
title: '网络错误',
icon: 'none'
})
2025-10-27 17:50:50 +08:00
this.hasMore = false // 异常时停止后续请求
2025-10-24 17:45:57 +08:00
} finally {
this.isLoading = false
2025-10-25 03:20:44 +08:00
// 最终兜底:无论如何都停止刷新
2025-10-24 17:45:57 +08:00
uni.stopPullDownRefresh()
}
},
// 加载下一页
loadNextPage() {
console.log('触发加载下一页')
if (this.hasMore) {
this.queryParams.pageNum++
this.getList()
}
},
// 下拉刷新
handleRefresh() {
console.log('触发下拉刷新')
this.resetData()
2025-10-25 03:20:44 +08:00
// 直接先停止一次(防止初始动画卡住)
uni.stopPullDownRefresh()
// 执行数据加载,加载完成后再次停止
this.getList().then(() => {
// 延迟300ms确保动画正常结束兼容快速加载场景
setTimeout(() => {
uni.stopPullDownRefresh()
}, 300)
}).catch(() => {
setTimeout(() => {
uni.stopPullDownRefresh()
}, 300)
})
2025-10-24 17:45:57 +08:00
},
// 获取用户信息
async getUserProfile() {
try {
const res = await getUserProfile()
console.log('当前用户信息:', res)
2025-10-25 03:20:44 +08:00
this.roleGroup = res.roleGroup
if (res.roleGroup === "学生") {
2025-10-24 17:45:57 +08:00
this.queryParams.stuName = res.data.nickName
}
this.getList()
} catch (err) {
console.error('获取用户信息失败:', err)
}
},
// 跳转添加页面
2025-10-25 03:20:44 +08:00
addDormInfo() {
if (this.roleGroup === "学生") {
if (this.dormInfo.length > 0) {
uni.showToast({
title: '请勿重复提交',
icon: 'none'
});
return
}
2025-10-24 17:45:57 +08:00
}
uni.navigateTo({
url: `/pages/dormitory/studentDormInfo/informationCollection`
})
},
// 点击列表项
handleItemClick(item) {
console.log('点击学生信息:', item)
// 可添加跳转详情页逻辑
// uni.navigateTo({ url: `/pages/detail?id=${item.id}` })
2025-10-25 03:20:44 +08:00
},
// 获取年级
async listGrade() {
let res = await listGrade()
this.gradeList = [{
gradeName: '全部'
}, ...res.rows]
},
// 获取校区数据
async listAllCampus() {
let res = await listAllCampus()
if (res.code == 200) {
this.dormAreaList = [{
name: '全部'
}, ...res.data]
}
},
// 搜索输入防抖
handleSearchInput() {
clearTimeout(this.searchTimer)
this.searchTimer = setTimeout(() => {
this.resetData()
this.getList()
}, 1000)
},
// 年级筛选
handleGradeChange(e) {
this.gradeIndex = e.detail.value
const selectedGrade = this.gradeList[this.gradeIndex]
// 修复“全部”选项无gradeId设为null
this.queryParams.gradeId = selectedGrade.gradeId || null
this.resetData()
this.getList()
2025-10-27 17:50:50 +08:00
this.scrollToTop()
this.$nextTick(() => this.setScrollContentPadding())
2025-10-25 03:20:44 +08:00
},
// 宿舍区筛选
async handleDormAreaChange(e) {
this.dormAreaIndex = e.detail.value
const selectedArea = this.dormAreaList[this.dormAreaIndex]
this.queryParams.campusId = selectedArea.id || null
this.resetData()
this.getList()
2025-10-27 17:50:50 +08:00
this.resetDorm()
this.scrollToTop()
this.$nextTick(() => this.setScrollContentPadding())
2025-10-25 03:20:44 +08:00
if (this.queryParams.campusId) {
// 根据校区id获取园区
let res = await listParkByCampus(this.queryParams.campusId)
if (res.code == 200) {
this.parkList = [{
name: '全部'
}, ...res.data]
}
}
},
2025-10-27 17:50:50 +08:00
// 宿舍区选择,重置园区等其他选择
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
}
}
},
2025-10-25 03:20:44 +08:00
// 园区筛选
2025-10-27 17:50:50 +08:00
async handleParkChange(e) {
2025-10-25 03:20:44 +08:00
this.parkIndex = e.detail.value
const selectedPark = this.parkList[this.parkIndex]
this.queryParams.parkId = selectedPark.id || null
this.resetData()
this.getList()
2025-10-27 17:50:50 +08:00
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
2025-10-25 03:20:44 +08:00
},
// 重置筛选
resetFilter() {
this.gradeIndex = 0
this.dormAreaIndex = 0
this.parkIndex = 0
2025-10-27 17:50:50 +08:00
this.buildingIndex = 0
this.floorIndex = 0
this.dormIndex = 0
2025-10-25 03:20:44 +08:00
// 重置筛选参数,保留分页基础参数
this.queryParams = {
...this.queryParams,
gradeId: null,
dormArea: null,
parkName: null,
roomNo: null,
2025-10-27 17:50:50 +08:00
stuName: null,
campusId: null,
parkId: null,
buildingId: null,
floorId: null,
dormitoryId: null,
dormArea: null, // 宿舍区筛选参数
parkName: null // 园区筛选参数
2025-10-25 03:20:44 +08:00
}
this.resetData()
this.getList()
2025-10-27 17:50:50 +08:00
this.scrollToTop()
this.$nextTick(() => this.setScrollContentPadding())
2025-10-25 03:20:44 +08:00
},
// 手动搜索
handleSearch() {
this.resetData()
this.getList()
2025-10-27 17:50:50 +08:00
this.scrollToTop()
this.$nextTick(() => this.setScrollContentPadding())
},
addRecordsPopup() {
if (this.queryParams.parkId == null) {
uni.showToast({
title: '请先选择园区',
icon: 'none'
});
return
}
this.$refs.popupTime.open('center');
2025-10-25 03:20:44 +08:00
},
2025-10-27 17:50:50 +08:00
onCancel() {
this.$refs.popupTime.close();
},
topersonalReporting() {
this.resetData()
this.getList()
this.scrollToTop()
this.$nextTick(() => this.setScrollContentPadding())
this.$refs.popupTime.close();
}
2025-10-25 03:20:44 +08:00
},
destroyed() {
clearTimeout(this.searchTimer)
2025-10-24 17:45:57 +08:00
}
}
</script>
<style scoped lang="scss">
.page-container {
position: relative;
height: 100vh;
background-color: #f5f7fa;
2025-10-25 03:20:44 +08:00
box-sizing: border-box;
2025-10-27 17:50:50 +08:00
/* 禁止页面滚动 */
overflow: hidden;
2025-10-25 03:20:44 +08:00
}
2025-10-27 17:50:50 +08:00
/* 固定搜索区*/
2025-10-25 03:20:44 +08:00
.fixed-search-wrap {
position: fixed;
top: 44px;
2025-10-27 17:50:50 +08:00
/* 原生title高度 */
2025-10-25 03:20:44 +08:00
left: 0;
right: 0;
z-index: 90;
background-color: #fff;
border-bottom: 1px solid #eee;
padding: 14px;
2025-10-27 17:50:50 +08:00
box-sizing: border-box;
2025-10-25 03:20:44 +08:00
}
/* 触发器:样式简洁,点击区域大 */
.search-header {
display: flex;
justify-content: space-between;
align-items: center;
padding: 20rpx;
cursor: pointer;
border-bottom: 1px solid #f5f5f5;
}
.search-header-title {
font-size: 28rpx;
font-weight: 500;
color: #333;
}
/* 搜索内容*/
.search-content {
transition: all 0.3s ease;
/* 动画过渡更自然 */
}
.search-card {
padding: 20rpx;
box-shadow: none;
/* 收缩时去掉阴影,更简洁 */
2025-10-24 17:45:57 +08:00
}
2025-10-25 03:20:44 +08:00
/* 滚动容器:调整顶部内边距,适应搜索区高度变化 */
2025-10-24 17:45:57 +08:00
.scroll-container {
2025-10-27 17:50:50 +08:00
position: absolute;
top: 44px;
/* 与原生title对齐 */
left: 0;
right: 0;
bottom: 60px;
/* 预留添加按钮高度 */
2025-10-24 17:45:57 +08:00
width: 100%;
2025-10-27 17:50:50 +08:00
overflow-y: auto;
overflow-x: hidden;
}
/* 滚动内容容器:处理内边距,避免内容被遮挡 */
.scroll-content {
/* 底部预留加载状态高度 */
padding-bottom: 40rpx;
/* 左右内边距 */
padding-left: 20rpx;
padding-right: 20rpx;
2025-10-24 17:45:57 +08:00
box-sizing: border-box;
}
2025-10-25 03:20:44 +08:00
/* 以下为原有样式,无需修改 */
2025-10-24 17:45:57 +08:00
.add {
position: fixed;
bottom: 50rpx;
right: 50rpx;
width: 90rpx;
height: 90rpx;
border-radius: 50%;
background-color: #1890FF;
color: white;
display: flex;
justify-content: center;
align-items: center;
font-size: 60rpx;
box-shadow: 0 4rpx 12rpx rgba(24, 144, 255, 0.3);
z-index: 99;
}
.dorm-list {
2025-10-27 17:50:50 +08:00
// padding: 20rpx;
padding: 0;
2025-10-24 17:45:57 +08:00
}
.dorm-item {
background-color: #fff;
border-radius: 16rpx;
padding: 28rpx;
margin-bottom: 20rpx;
box-shadow: 0 2rpx 8rpx rgba(0, 0, 0, 0.05);
transition: transform 0.2s;
}
.dorm-item:active {
transform: scale(0.99);
}
.item-header {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 20rpx;
padding-bottom: 16rpx;
border-bottom: 1px solid #f0f0f0;
}
.name {
font-size: 34rpx;
font-weight: 600;
color: #333;
}
.tag {
font-size: 24rpx;
padding: 4rpx 16rpx;
border-radius: 20rpx;
color: #fff;
}
.head-tag {
background-color: #28a745;
}
.item-content {
font-size: 28rpx;
color: #666;
line-height: 1.8;
}
.item-content view {
margin-bottom: 14rpx;
}
.item-content view:last-child {
margin-bottom: 0;
}
.loading,
.no-more,
.no-data {
text-align: center;
padding: 30rpx 0;
color: #999;
font-size: 28rpx;
}
.no-data {
padding: 100rpx 0;
}
2025-10-25 03:20:44 +08:00
.search-row {
display: flex;
align-items: center;
background-color: #f5f7fa;
border-radius: 60rpx;
padding: 14rpx 20rpx;
margin-bottom: 24rpx;
}
.search-icon {
margin-right: 12rpx;
}
.search-input {
flex: 1;
font-size: 28rpx;
color: #333;
}
.filter-row {
display: flex;
flex-wrap: wrap;
gap: 16rpx;
margin-bottom: 24rpx;
}
.filter-item {
flex: 1;
min-width: 120rpx;
display: flex;
flex-direction: column;
gap: 8rpx;
}
.filter-label {
font-size: 24rpx;
color: #666;
padding-left: 4rpx;
}
.picker-content,
.filter-input {
display: flex;
align-items: center;
font-size: 26rpx;
color: #333;
padding: 14rpx 16rpx;
background-color: #f5f7fa;
border-radius: 12rpx;
height: 60rpx;
box-sizing: border-box;
}
.filter-input::placeholder {
color: #999;
}
.action-row {
display: flex;
gap: 16rpx;
}
.reset-btn,
.search-btn {
flex: 1;
height: 72rpx;
line-height: 72rpx;
border-radius: 36rpx;
font-size: 28rpx;
display: flex;
justify-content: center;
align-items: center;
}
.reset-btn {
background-color: #fff;
color: #1890FF;
border: 1px solid #1890FF;
}
.search-btn {
background-color: #1890FF;
color: #fff;
border: none;
}
.btn-icon {
margin-right: 6rpx;
}
2025-10-27 17:50:50 +08:00
.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;
}
}
}
}
}
2025-10-24 17:45:57 +08:00
</style>