HomeLease/pages/useList/useList.vue

362 lines
7.4 KiB
Vue
Raw Normal View History

2025-08-18 16:24:51 +08:00
<template>
<view class="page">
2025-08-19 12:01:17 +08:00
<!-- 加载状态 -->
<view v-if="loading" class="loading-overlay">
<view class="loading-content">
<view class="loading-spinner"></view>
<text class="loading-text">加载中...</text>
</view>
</view>
2025-08-18 16:24:51 +08:00
<!-- 搜索和筛选区域 -->
<view class="search-filter-section">
<view class="search-box">
2025-08-18 16:37:23 +08:00
<uni-icons color="#7F7F7F" size="20" type="search"></uni-icons>
2025-08-18 16:24:51 +08:00
<input v-model="searchKeyword" class="search-input" placeholder="搜索" @input="onSearch" />
</view>
<view class="filter-btn" @click="showFilter">
<text class="filter-text">筛选</text>
<text class="filter-arrow"></text>
</view>
</view>
<!-- 用户列表 -->
<view class="user-list">
<view v-for="(user, index) in filteredUsers" :key="user.id" class="user-card">
<!-- 用户基本信息 -->
<view class="user-info">
<view class="avatar-placeholder"></view>
<view class="user-details">
<text class="username">{{ user.username }}</text>
<view class="user-stats">
<text class="amount">¥ {{ user.totalAmount }}</text>
<text class="device-count">{{ user.deviceCount }}</text>
</view>
</view>
</view>
<!-- 设备信息表格 -->
<view class="device-table">
<view class="table-header">
<text class="header-cell">类型</text>
<text class="header-cell">金额</text>
<text class="header-cell">租赁</text>
<text class="header-cell">周期</text>
<text class="header-cell">到期</text>
</view>
<view
v-for="(device, deviceIndex) in user.devices.slice(
0,
user.isExpanded ? user.devices.length : 1
)"
:key="deviceIndex"
class="table-row"
>
<text class="table-cell">{{ device.type }}</text>
2025-08-18 16:42:01 +08:00
<text class="table-cell amount-cell">¥ {{ device.amount }}</text>
2025-08-18 16:24:51 +08:00
<text class="table-cell">{{ device.rentDate }}</text>
2025-08-18 16:42:01 +08:00
<text class="table-cell period-cell">{{ device.period }}</text>
<text class="table-cell expiry-cell">{{ device.expiryDate }}</text>
2025-08-18 16:24:51 +08:00
</view>
</view>
<!-- 展开/收起按钮 -->
<view class="expand-btn" @click="toggleExpand(index)">
<text class="expand-text">
{{ user.isExpanded ? '点击收起' : '点击展开' }}
</text>
<text class="expand-arrow">
{{ user.isExpanded ? '▲' : '▼' }}
</text>
</view>
</view>
</view>
</view>
</template>
<script>
import { commonEnum } from '@/enum/commonEnum.js'
2025-08-19 12:01:17 +08:00
import { getUserList } from '@/api/user/user.js'
2025-08-18 16:24:51 +08:00
import UniIcons from '../../uni_modules/uni-icons/components/uni-icons/uni-icons.vue'
export default {
components: { UniIcons },
data() {
return {
searchKeyword: '',
2025-08-19 12:01:17 +08:00
users: [],
loading: false,
2025-08-18 16:24:51 +08:00
}
},
2025-08-19 12:01:17 +08:00
onLoad() {
this.fetchUserList()
},
onShow() {
// 页面显示时刷新数据
this.fetchUserList()
},
2025-08-18 16:24:51 +08:00
computed: {
filteredUsers() {
if (!this.searchKeyword) {
return this.users
}
return this.users.filter(user =>
user.username.toLowerCase().includes(this.searchKeyword.toLowerCase())
)
},
},
methods: {
2025-08-19 12:01:17 +08:00
// 获取用户列表
async fetchUserList() {
this.loading = true
try {
const response = await getUserList()
if (response.code === 200 && response.data && Array.isArray(response.data)) {
// 为每个用户添加展开状态
this.users = response.data.map(user => ({
...user,
isExpanded: false // 默认收起
}))
console.log('用户列表获取成功:', this.users)
}
} catch (error) {
console.error('获取用户列表失败:', error)
uni.showToast({
title: '数据加载失败',
icon: 'none',
})
} finally {
this.loading = false
}
},
2025-08-18 16:24:51 +08:00
onSearch() {
// 搜索逻辑已在computed中处理
},
showFilter() {
// 显示筛选选项
uni.showToast({
title: '筛选功能开发中',
icon: 'none',
})
},
toggleExpand(index) {
this.users[index].isExpanded = !this.users[index].isExpanded
},
},
}
</script>
<style lang="scss" scoped>
.page {
min-height: 90vh;
background: #f7f7f7;
padding-bottom: 40rpx;
2025-08-19 12:01:17 +08:00
position: relative;
}
.loading-overlay {
position: fixed;
top: 0;
left: 0;
right: 0;
bottom: 0;
background: rgba(255, 255, 255, 0.8);
display: flex;
align-items: center;
justify-content: center;
z-index: 9999;
}
.loading-content {
display: flex;
flex-direction: column;
align-items: center;
gap: 20rpx;
}
.loading-spinner {
width: 60rpx;
height: 60rpx;
border: 4rpx solid #f3f3f3;
border-top: 4rpx solid #007aff;
border-radius: 50%;
animation: spin 1s linear infinite;
}
.loading-text {
font-size: 28rpx;
color: #666;
}
@keyframes spin {
0% { transform: rotate(0deg); }
100% { transform: rotate(360deg); }
2025-08-18 16:24:51 +08:00
}
.search-filter-section {
display: flex;
align-items: center;
2025-08-18 16:37:23 +08:00
padding: 20rpx 20rpx 20rpx 20rpx;
2025-08-18 16:24:51 +08:00
gap: 20rpx;
2025-08-18 16:37:23 +08:00
background: white;
margin-bottom: 20rpx;
2025-08-18 16:24:51 +08:00
}
.search-box {
flex: 1;
display: flex;
align-items: center;
2025-08-18 16:37:23 +08:00
background: #f3f5f6;
border-radius: 999px;
2025-08-18 16:42:01 +08:00
padding: 20rpx 50rpx;
2025-08-18 16:24:51 +08:00
.search-input {
2025-08-18 16:37:23 +08:00
padding: 0 20rpx;
2025-08-18 16:24:51 +08:00
flex: 1;
font-size: 28rpx;
}
}
.filter-btn {
display: flex;
align-items: center;
background: white;
border-radius: 10rpx;
padding: 20rpx;
.filter-text {
font-size: 28rpx;
margin-right: 10rpx;
}
.filter-arrow {
font-size: 24rpx;
}
}
.user-list {
padding: 0 20rpx;
}
.user-card {
background: white;
border-radius: 20rpx;
margin-bottom: 20rpx;
padding: 30rpx;
}
.user-info {
display: flex;
align-items: center;
margin-bottom: 30rpx;
}
.avatar-placeholder {
width: 80rpx;
height: 80rpx;
background: #e0e0e0;
border-radius: 50%;
margin-right: 20rpx;
}
.user-details {
2025-08-18 16:37:23 +08:00
display: flex;
justify-content: space-between;
2025-08-18 16:24:51 +08:00
flex: 1;
}
.username {
font-size: 32rpx;
font-weight: 500;
color: #333;
display: block;
margin-bottom: 10rpx;
}
.user-stats {
display: flex;
align-items: center;
gap: 20rpx;
}
.amount {
2025-08-18 16:42:01 +08:00
font-size: 32rpx;
2025-08-18 16:24:51 +08:00
font-weight: 500;
2025-08-18 16:37:23 +08:00
padding-right: 78rpx;
2025-08-18 16:24:51 +08:00
}
.device-count {
2025-08-18 16:42:01 +08:00
font-size: 32rpx;
font-weight: 500;
2025-08-18 16:24:51 +08:00
color: #666;
}
.device-table {
margin-bottom: 20rpx;
}
.table-header {
display: flex;
background: #f8f8f8;
border-radius: 10rpx;
padding: 20rpx 0;
margin-bottom: 10rpx;
}
.header-cell {
flex: 1;
text-align: center;
font-size: 24rpx;
color: #666;
font-weight: 500;
}
.table-row {
display: flex;
padding: 15rpx 0;
border-bottom: 1rpx solid #f0f0f0;
}
.table-cell {
flex: 1;
text-align: center;
font-size: 24rpx;
color: #333;
2025-08-18 16:42:01 +08:00
&.amount-cell {
color: #ff6b35;
}
&.period-cell {
color: #ff6b35;
}
&.expiry-cell {
color: #ff4757;
}
2025-08-18 16:24:51 +08:00
}
.expand-btn {
display: flex;
align-items: center;
justify-content: center;
padding: 20rpx 0;
2025-08-18 16:42:01 +08:00
//color: #007aff;
2025-08-18 16:24:51 +08:00
font-size: 28rpx;
.expand-text {
margin-right: 10rpx;
}
.expand-arrow {
font-size: 24rpx;
}
}
view {
2025-08-18 16:42:01 +08:00
//border: red solid 1px;
2025-08-18 16:24:51 +08:00
}
</style>