This commit is contained in:
wangxiaoxian 2026-03-10 19:56:49 +08:00
parent 4576eef238
commit f3b8433c23
3 changed files with 126 additions and 5 deletions

View File

@ -57,7 +57,10 @@ export const statisticsApi = {
getRegionHouseStats: () => get('/statistics/region-house'), getRegionHouseStats: () => get('/statistics/region-house'),
getRegionApartmentHouseStats: () => get('/statistics/region-apartment-house'), getRegionApartmentHouseStats: () => get('/statistics/region-apartment-house'),
getDashboardStats: () => get('/statistics/dashboard'), getDashboardStats: () => get('/statistics/dashboard'),
getApartmentRoomStatusStats: () => get('/statistics/apartment-room-status') getApartmentRoomStatusStats: () => get('/statistics/apartment-room-status'),
getEmptyRoomsByApartment: () => get('/statistics/empty-rooms-by-apartment'),
getRentedRoomsByApartment: () => get('/statistics/rented-rooms-by-apartment'),
getTenantRentalStats: () => get('/statistics/tenant-rental-stats')
}; };
// 水费管理API // 水费管理API

View File

@ -49,6 +49,9 @@
<!-- 房间卡片列表 --> <!-- 房间卡片列表 -->
<div class="room-cards" v-loading="isLoading"> <div class="room-cards" v-loading="isLoading">
<div v-if="rooms.length === 0 && !isLoading" class="no-data">
<el-empty description="暂无数据"></el-empty>
</div>
<div <div
v-for="room in rooms" v-for="room in rooms"
:key="room.id" :key="room.id"
@ -326,6 +329,14 @@ export default {
margin-top: 20px; margin-top: 20px;
} }
.no-data {
grid-column: 1 / -1;
display: flex;
justify-content: center;
align-items: center;
min-height: 300px;
}
.room-card-wrapper { .room-card-wrapper {
cursor: pointer; cursor: pointer;
} }

View File

@ -6,9 +6,6 @@
<span>房间状态统计</span> <span>房间状态统计</span>
</div> </div>
</template> </template>
<div class="chart-container">
<el-empty description="图表功能暂未实现" style="margin: 40px 0;"></el-empty>
</div>
<div class="table-wrapper"> <div class="table-wrapper">
<el-table :data="roomStatusData" style="width: 100%; margin-top: 20px;" class="stats-table"> <el-table :data="roomStatusData" style="width: 100%; margin-top: 20px;" class="stats-table">
<el-table-column prop="status" label="状态" min-width="100"></el-table-column> <el-table-column prop="status" label="状态" min-width="100"></el-table-column>
@ -27,6 +24,61 @@
<div class="total-count"> <div class="total-count">
<el-tag size="medium" type="primary">房间总数{{ totalCount }} </el-tag> <el-tag size="medium" type="primary">房间总数{{ totalCount }} </el-tag>
</div> </div>
<div class="table-wrapper" style="margin-top: 30px;">
<h3 style="margin-bottom: 15px;">空房分布</h3>
<el-table :data="emptyRoomsData" style="width: 100%;" class="stats-table">
<el-table-column type="index" label="序号" width="60"></el-table-column>
<el-table-column prop="apartmentName" label="公寓名称" min-width="150"></el-table-column>
<el-table-column label="空房信息" min-width="300">
<template slot-scope="scope">
<div v-if="scope.row.emptyRooms && scope.row.emptyRooms.length > 0">
{{ scope.row.emptyRooms.map(room => room.roomNumber).join('') }}
</div>
<div v-else class="no-empty-rooms">
无空房
</div>
</template>
</el-table-column>
</el-table>
</div>
<div class="table-wrapper" style="margin-top: 30px;">
<h3 style="margin-bottom: 15px;">在租分布</h3>
<el-table :data="rentedRoomsData" style="width: 100%;" class="stats-table">
<el-table-column type="index" label="序号" width="60"></el-table-column>
<el-table-column prop="apartmentName" label="公寓名称" min-width="150"></el-table-column>
<el-table-column label="在租信息" min-width="300">
<template slot-scope="scope">
<div v-if="scope.row.rentedRooms && scope.row.rentedRooms.length > 0">
{{ scope.row.rentedRooms.map(room => room.roomNumber).join('') }}
</div>
<div v-else class="no-empty-rooms">
无在租房
</div>
</template>
</el-table-column>
</el-table>
</div>
<div class="table-wrapper" style="margin-top: 30px;">
<h3 style="margin-bottom: 15px;">租客在租统计</h3>
<el-table :data="tenantRentalData" style="width: 100%;" class="stats-table">
<el-table-column type="expand">
<template slot-scope="scope">
<div class="expand-content">
<div v-for="apartment in scope.row.apartments" :key="apartment.apartmentId" class="apartment-item">
<strong>{{ apartment.apartmentName }}</strong>
<span v-if="apartment.rooms && apartment.rooms.length > 0">
{{ apartment.rooms.map(room => room.roomNumber).join('') }}
</span>
<span v-else class="no-rooms">无房间</span>
</div>
</div>
</template>
</el-table-column>
<el-table-column type="index" label="序号" width="60"></el-table-column>
<el-table-column prop="tenantName" label="租客名称" min-width="150"></el-table-column>
<el-table-column prop="count" label="数量" min-width="80"></el-table-column>
</el-table>
</div>
</el-card> </el-card>
</div> </div>
</template> </template>
@ -38,7 +90,10 @@ export default {
name: 'RoomStatistics', name: 'RoomStatistics',
data() { data() {
return { return {
roomStatusData: [] roomStatusData: [],
emptyRoomsData: [],
rentedRoomsData: [],
tenantRentalData: []
} }
}, },
computed: { computed: {
@ -50,6 +105,9 @@ export default {
}, },
mounted() { mounted() {
this.loadRoomStatusData() this.loadRoomStatusData()
this.loadEmptyRoomsData()
this.loadRentedRoomsData()
this.loadTenantRentalData()
}, },
methods: { methods: {
async loadRoomStatusData() { async loadRoomStatusData() {
@ -94,6 +152,30 @@ export default {
} }
this.$router.push(`/rental/list?${query}`) this.$router.push(`/rental/list?${query}`)
},
async loadEmptyRoomsData() {
try {
const response = await statisticsApi.getEmptyRoomsByApartment()
this.emptyRoomsData = response
} catch (error) {
this.$message.error('加载空房分布数据失败')
}
},
async loadRentedRoomsData() {
try {
const response = await statisticsApi.getRentedRoomsByApartment()
this.rentedRoomsData = response
} catch (error) {
this.$message.error('加载在租分布数据失败')
}
},
async loadTenantRentalData() {
try {
const response = await statisticsApi.getTenantRentalStats()
this.tenantRentalData = response
} catch (error) {
this.$message.error('加载租客在租统计数据失败')
}
} }
} }
} }
@ -129,6 +211,31 @@ export default {
color: #409EFF; color: #409EFF;
} }
.no-empty-rooms {
color: #909399;
font-style: italic;
padding: 8px 0;
}
.expand-content {
padding: 15px 20px;
background-color: #f9f9f9;
}
.apartment-item {
padding: 8px 0;
border-bottom: 1px dashed #e0e0e0;
}
.apartment-item:last-child {
border-bottom: none;
}
.no-rooms {
color: #909399;
font-style: italic;
}
.clickable-cell { .clickable-cell {
cursor: pointer; cursor: pointer;
transition: color 0.3s; transition: color 0.3s;