This commit is contained in:
wangxiaoxian 2026-03-04 00:34:53 +08:00
parent c63230239d
commit eb163089a1
3 changed files with 79 additions and 164 deletions

View File

@ -60,7 +60,8 @@ export const statisticsApi = {
getRentData: () => get('/statistics/rent'), getRentData: () => get('/statistics/rent'),
getRoomStatus: () => get('/statistics/room-status'), getRoomStatus: () => get('/statistics/room-status'),
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')
}; };
// 水费管理API // 水费管理API

View File

@ -83,6 +83,28 @@
</div> </div>
</el-card> </el-card>
</el-col> </el-col>
<el-col :xs="24" :sm="12" :md="8">
<el-card class="stat-card">
<div class="stat-item">
<el-icon class="el-icon-s-finance"></el-icon>
<div class="stat-info">
<div class="stat-value">¥{{ collectedRentAmount }}</div>
<div class="stat-label">已收租金</div>
</div>
</div>
</el-card>
</el-col>
<el-col :xs="24" :sm="12" :md="8">
<el-card class="stat-card">
<div class="stat-item">
<el-icon class="el-icon-s-finance"></el-icon>
<div class="stat-info">
<div class="stat-value">¥{{ collectedWaterAmount }}</div>
<div class="stat-label">已收水费</div>
</div>
</div>
</el-card>
</el-col>
</el-row> </el-row>
<el-card style="margin-top: 20px;"> <el-card style="margin-top: 20px;">
@ -120,6 +142,8 @@ export default {
contractCount: 0, contractCount: 0,
emptyRoomCount: 0, emptyRoomCount: 0,
rentedRoomCount: 0, rentedRoomCount: 0,
collectedRentAmount: 0,
collectedWaterAmount: 0,
regionApartmentHouseStats: [] regionApartmentHouseStats: []
} }
}, },
@ -130,29 +154,24 @@ export default {
async loadData() { async loadData() {
try { try {
// //
const [regionsResponse, apartmentsResponse, roomsResponse, tenantsResponse, contractsResponse, regionApartmentHouseStatsResponse] = await Promise.all([ const [dashboardStatsResponse, regionApartmentHouseStatsResponse] = await Promise.all([
regionApi.getAll(), statisticsApi.getDashboardStats(),
apartmentApi.getAll(),
roomApi.getAll(),
tenantApi.getAll(),
contractApi.getAll(),
statisticsApi.getRegionApartmentHouseStats() statisticsApi.getRegionApartmentHouseStats()
]) ])
// //
const regions = regionsResponse.data || regionsResponse const dashboardStats = dashboardStatsResponse.data || dashboardStatsResponse
const apartments = apartmentsResponse.data || apartmentsResponse
const rooms = roomsResponse.data || roomsResponse
const tenants = tenantsResponse.data || tenantsResponse
const contracts = contractsResponse.data || contractsResponse
this.regionCount = regions.length //
this.apartmentCount = apartments.length this.regionCount = dashboardStats.regionCount
this.roomCount = rooms.length this.apartmentCount = dashboardStats.apartmentCount
this.tenantCount = tenants.length this.roomCount = dashboardStats.roomCount
this.contractCount = contracts.length this.tenantCount = dashboardStats.tenantCount
this.emptyRoomCount = rooms.filter(room => room.status === 'empty').length this.contractCount = dashboardStats.contractCount
this.rentedRoomCount = rooms.filter(room => room.status === 'rented').length this.emptyRoomCount = dashboardStats.emptyRoomCount
this.rentedRoomCount = dashboardStats.rentedRoomCount
this.collectedRentAmount = dashboardStats.collectedRentAmount
this.collectedWaterAmount = dashboardStats.collectedWaterAmount
this.regionApartmentHouseStats = regionApartmentHouseStatsResponse this.regionApartmentHouseStats = regionApartmentHouseStatsResponse
} catch (error) { } catch (error) {
this.$message.error('加载数据失败') this.$message.error('加载数据失败')

View File

@ -61,9 +61,10 @@
</template> </template>
</el-table-column> </el-table-column>
<el-table-column prop="createTime" label="创建时间" width="180"></el-table-column> <el-table-column prop="createTime" label="创建时间" width="180"></el-table-column>
<el-table-column label="操作" width="150"> <el-table-column label="操作" width="220">
<template slot-scope="scope"> <template slot-scope="scope">
<el-button type="primary" size="small" @click="handleEditRental(scope.row)">编辑</el-button> <el-button type="primary" size="small" @click="handleEditRental(scope.row)">编辑</el-button>
<el-button type="success" size="small" @click="handleRenewRental(scope.row)">续租</el-button>
<el-button type="danger" size="small" @click="handleDeleteRental(scope.row.id)">删除</el-button> <el-button type="danger" size="small" @click="handleDeleteRental(scope.row.id)">删除</el-button>
</template> </template>
</el-table-column> </el-table-column>
@ -96,33 +97,7 @@
</el-table-column> </el-table-column>
</el-table> </el-table>
</el-tab-pane> </el-tab-pane>
<el-tab-pane label="电费记录" name="electricity">
<div class="section-header">
<el-button type="primary" size="small" @click="handleAddElectricityBill">添加电费</el-button>
</div>
<el-table :data="electricityBills" style="width: 100%">
<el-table-column prop="startDate" label="开始日期" width="150"></el-table-column>
<el-table-column prop="endDate" label="结束日期" width="150"></el-table-column>
<el-table-column prop="startReading" label="起始度数" width="120"></el-table-column>
<el-table-column prop="endReading" label="结束度数" width="120"></el-table-column>
<el-table-column prop="usage" label="用电量(度)" width="120"></el-table-column>
<el-table-column prop="unitPrice" label="单价(元/度)" width="120"></el-table-column>
<el-table-column prop="amount" label="费用(元)" width="100"></el-table-column>
<el-table-column prop="status" label="状态" width="100">
<template slot-scope="scope">
<el-tag :type="scope.row.status === 'paid' ? 'success' : 'warning'">
{{ scope.row.status === 'paid' ? '已支付' : '未支付' }}
</el-tag>
</template>
</el-table-column>
<el-table-column label="操作" width="150">
<template slot-scope="scope">
<el-button type="primary" size="small" @click="handleEditElectricityBill(scope.row)">编辑</el-button>
<el-button type="danger" size="small" @click="handleDeleteElectricityBill(scope.row.id)">删除</el-button>
</template>
</el-table-column>
</el-table>
</el-tab-pane>
</el-tabs> </el-tabs>
<!-- 水费编辑对话框 --> <!-- 水费编辑对话框 -->
@ -156,39 +131,10 @@
</span> </span>
</el-dialog> </el-dialog>
<!-- 电费编辑对话框 -->
<el-dialog title="编辑电费" :visible.sync="electricityBillDialogVisible" width="500px">
<el-form :model="electricityBillForm" :rules="electricityBillRules" ref="electricityBillForm">
<el-form-item label="开始日期" prop="startDate">
<el-date-picker v-model="electricityBillForm.startDate" type="date" placeholder="选择开始日期" style="width: 100%"></el-date-picker>
</el-form-item>
<el-form-item label="结束日期" prop="endDate">
<el-date-picker v-model="electricityBillForm.endDate" type="date" placeholder="选择结束日期" style="width: 100%"></el-date-picker>
</el-form-item>
<el-form-item label="起始度数" prop="startReading">
<el-input v-model.number="electricityBillForm.startReading" placeholder="请输入起始度数"></el-input>
</el-form-item>
<el-form-item label="结束度数" prop="endReading">
<el-input v-model.number="electricityBillForm.endReading" placeholder="请输入结束度数"></el-input>
</el-form-item>
<el-form-item label="单价(元/度)" prop="unitPrice">
<el-input v-model.number="electricityBillForm.unitPrice" placeholder="请输入单价"></el-input>
</el-form-item>
<el-form-item label="状态" prop="status">
<el-select v-model="electricityBillForm.status" placeholder="请选择状态">
<el-option label="未支付" value="unpaid"></el-option>
<el-option label="已支付" value="paid"></el-option>
</el-select>
</el-form-item>
</el-form>
<span slot="footer" class="dialog-footer">
<el-button @click="electricityBillDialogVisible = false">取消</el-button>
<el-button type="primary" @click="handleSaveElectricityBill">保存</el-button>
</span>
</el-dialog>
<!-- 租赁编辑对话框 --> <!-- 租赁编辑对话框 -->
<el-dialog title="编辑租赁记录" :visible.sync="rentalDialogVisible" width="500px"> <el-dialog :title="rentalForm.id ? '编辑租赁记录' : '新增租赁记录'" :visible.sync="rentalDialogVisible" width="500px">
<el-form :model="rentalForm" :rules="rentalRules" ref="rentalForm"> <el-form :model="rentalForm" :rules="rentalRules" ref="rentalForm">
<el-form-item label="租客姓名" prop="tenantName"> <el-form-item label="租客姓名" prop="tenantName">
<el-input v-model="rentalForm.tenantName" placeholder="请输入租客姓名"></el-input> <el-input v-model="rentalForm.tenantName" placeholder="请输入租客姓名"></el-input>
@ -231,7 +177,7 @@
</template> </template>
<script> <script>
import { roomApi, rentalApi, apartmentApi, waterBillApi, electricityBillApi } from '../../api/api' import { roomApi, rentalApi, apartmentApi, waterBillApi } from '../../api/api'
export default { export default {
name: 'RentalDetail', name: 'RentalDetail',
@ -242,13 +188,11 @@ export default {
apartments: [], apartments: [],
rentalHistory: [], rentalHistory: [],
waterBills: [], waterBills: [],
electricityBills: [],
isLoading: false, isLoading: false,
activeTab: 'rental', activeTab: 'rental',
// //
returnQuery: {}, returnQuery: {},
waterBillDialogVisible: false, waterBillDialogVisible: false,
electricityBillDialogVisible: false,
waterBillForm: { waterBillForm: {
id: '', id: '',
roomId: '', roomId: '',
@ -259,16 +203,6 @@ export default {
unitPrice: '', unitPrice: '',
status: 'unpaid' status: 'unpaid'
}, },
electricityBillForm: {
id: '',
roomId: '',
startDate: '',
endDate: '',
startReading: '',
endReading: '',
unitPrice: '',
status: 'unpaid'
},
waterBillRules: { waterBillRules: {
startDate: [{ required: true, message: '请选择开始日期', trigger: 'change' }], startDate: [{ required: true, message: '请选择开始日期', trigger: 'change' }],
endDate: [{ required: true, message: '请选择结束日期', trigger: 'change' }], endDate: [{ required: true, message: '请选择结束日期', trigger: 'change' }],
@ -277,14 +211,6 @@ export default {
unitPrice: [{ required: true, message: '请输入单价', trigger: 'blur' }], unitPrice: [{ required: true, message: '请输入单价', trigger: 'blur' }],
status: [{ required: true, message: '请选择状态', trigger: 'change' }] status: [{ required: true, message: '请选择状态', trigger: 'change' }]
}, },
electricityBillRules: {
startDate: [{ required: true, message: '请选择开始日期', trigger: 'change' }],
endDate: [{ required: true, message: '请选择结束日期', trigger: 'change' }],
startReading: [{ required: true, message: '请输入起始度数', trigger: 'blur' }],
endReading: [{ required: true, message: '请输入结束度数', trigger: 'blur' }],
unitPrice: [{ required: true, message: '请输入单价', trigger: 'blur' }],
status: [{ required: true, message: '请选择状态', trigger: 'change' }]
},
rentalDialogVisible: false, rentalDialogVisible: false,
rentalForm: { rentalForm: {
id: '', id: '',
@ -340,11 +266,8 @@ export default {
// //
const waterBillsResponse = await waterBillApi.getAll({ roomId }) const waterBillsResponse = await waterBillApi.getAll({ roomId })
this.waterBills = waterBillsResponse.data || waterBillsResponse this.waterBills = (waterBillsResponse.data || waterBillsResponse)
.sort((a, b) => new Date(b.createTime) - new Date(a.createTime))
//
const electricityBillsResponse = await electricityBillApi.getAll({ roomId })
this.electricityBills = electricityBillsResponse.data || electricityBillsResponse
// //
this.loadRentalHistory() this.loadRentalHistory()
@ -364,6 +287,7 @@ export default {
tenantName: rental.Tenant ? rental.Tenant.name : '' tenantName: rental.Tenant ? rental.Tenant.name : ''
} }
}) })
.sort((a, b) => new Date(b.createTime) - new Date(a.createTime))
}, },
getStatusType(status) { getStatusType(status) {
switch (status) { switch (status) {
@ -569,65 +493,7 @@ export default {
// //
}) })
}, },
handleAddElectricityBill() {
this.electricityBillForm = {
id: '',
roomId: this.$route.params.id,
startDate: '',
endDate: '',
startReading: '',
endReading: '',
unitPrice: '',
status: 'unpaid'
}
this.electricityBillDialogVisible = true
},
handleEditElectricityBill(bill) {
this.electricityBillForm = {
...bill,
startDate: bill.startDate ? new Date(bill.startDate) : '',
endDate: bill.endDate ? new Date(bill.endDate) : ''
}
this.electricityBillDialogVisible = true
},
async handleSaveElectricityBill() {
try {
const roomId = this.$route.params.id
if (this.electricityBillForm.id) {
//
await electricityBillApi.update(this.electricityBillForm.id, this.electricityBillForm)
this.$message.success('电费记录更新成功')
} else {
//
await electricityBillApi.create({
...this.electricityBillForm,
roomId
})
this.$message.success('电费记录添加成功')
}
this.electricityBillDialogVisible = false
this.loadData()
} catch (error) {
this.$message.error('操作失败')
}
},
async handleDeleteElectricityBill(id) {
this.$confirm('确定要删除这条电费记录吗?', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'danger'
}).then(async () => {
try {
await electricityBillApi.delete(id)
this.$message.success('电费记录删除成功')
this.loadData()
} catch (error) {
this.$message.error('删除失败')
}
}).catch(() => {
//
})
},
handleEditRental(rental) { handleEditRental(rental) {
this.rentalForm = { this.rentalForm = {
...rental, ...rental,
@ -636,6 +502,35 @@ export default {
} }
this.rentalDialogVisible = true this.rentalDialogVisible = true
}, },
handleRenewRental(rental) {
//
const oldEndDate = new Date(rental.endDate)
const newStartDate = new Date(oldEndDate)
//
const oldStartDate = new Date(rental.startDate)
const monthsDiff = (oldEndDate.getFullYear() - oldStartDate.getFullYear()) * 12 + (oldEndDate.getMonth() - oldStartDate.getMonth())
//
const newEndDate = new Date(newStartDate)
newEndDate.setMonth(newEndDate.getMonth() + monthsDiff)
// ID
this.rentalForm = {
id: '',
roomId: rental.roomId,
tenantName: rental.tenantName,
tenantPhone: rental.tenantPhone,
tenantIdCard: rental.tenantIdCard,
startDate: newStartDate,
endDate: newEndDate,
rent: rental.rent,
deposit: rental.deposit,
status: 'active',
remark: '续租'
}
this.rentalDialogVisible = true
},
async handleSaveRental() { async handleSaveRental() {
try { try {
if (this.rentalForm.id) { if (this.rentalForm.id) {