This commit is contained in:
parent
4d23e028bb
commit
c63230239d
|
|
@ -0,0 +1,3 @@
|
|||
# 生产环境配置
|
||||
NODE_ENV=production
|
||||
VUE_APP_API_BASE_URL=/api
|
||||
|
|
@ -780,6 +780,29 @@
|
|||
"webpack-merge": "^5.7.3",
|
||||
"webpack-virtual-modules": "^0.4.2",
|
||||
"whatwg-fetch": "^3.6.2"
|
||||
},
|
||||
"dependencies": {
|
||||
"@vue/vue-loader-v15": {
|
||||
"version": "npm:vue-loader@15.11.1",
|
||||
"resolved": "https://registry.npmmirror.com/vue-loader/-/vue-loader-15.11.1.tgz",
|
||||
"integrity": "sha512-0iw4VchYLePqJfJu9s62ACWUXeSqM30SQqlIftbYWM3C+jpPcEHKSPUZBLjSF9au4HTHQ/naF6OGnO3Q/qGR3Q==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@vue/component-compiler-utils": "^3.1.0",
|
||||
"hash-sum": "^1.0.2",
|
||||
"loader-utils": "^1.1.0",
|
||||
"vue-hot-reload-api": "^2.3.0",
|
||||
"vue-style-loader": "^4.1.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"hash-sum": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmmirror.com/hash-sum/-/hash-sum-1.0.2.tgz",
|
||||
"integrity": "sha512-fUs4B4L+mlt8/XAtSOGMUO1TXmAelItBPtJG7CyHJfYTdDjwisntGO2JQz7oUsatOY9o68+57eziUVNw/mRHmA==",
|
||||
"dev": true
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"@vue/cli-shared-utils": {
|
||||
|
|
@ -870,27 +893,6 @@
|
|||
}
|
||||
}
|
||||
},
|
||||
"@vue/vue-loader-v15": {
|
||||
"version": "npm:vue-loader@15.11.1",
|
||||
"resolved": "https://registry.npmmirror.com/vue-loader/-/vue-loader-15.11.1.tgz",
|
||||
"integrity": "sha512-0iw4VchYLePqJfJu9s62ACWUXeSqM30SQqlIftbYWM3C+jpPcEHKSPUZBLjSF9au4HTHQ/naF6OGnO3Q/qGR3Q==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@vue/component-compiler-utils": "^3.1.0",
|
||||
"hash-sum": "^1.0.2",
|
||||
"loader-utils": "^1.1.0",
|
||||
"vue-hot-reload-api": "^2.3.0",
|
||||
"vue-style-loader": "^4.1.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"hash-sum": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmmirror.com/hash-sum/-/hash-sum-1.0.2.tgz",
|
||||
"integrity": "sha512-fUs4B4L+mlt8/XAtSOGMUO1TXmAelItBPtJG7CyHJfYTdDjwisntGO2JQz7oUsatOY9o68+57eziUVNw/mRHmA==",
|
||||
"dev": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"@vue/web-component-wrapper": {
|
||||
"version": "1.3.0",
|
||||
"resolved": "https://registry.npmmirror.com/@vue/web-component-wrapper/-/web-component-wrapper-1.3.0.tgz",
|
||||
|
|
|
|||
186
src/api/api.js
186
src/api/api.js
|
|
@ -1,180 +1,84 @@
|
|||
// API服务层,用于与后端进行交互
|
||||
|
||||
const API_BASE_URL = '/api';
|
||||
|
||||
// 通用请求函数
|
||||
async function request(url, options = {}) {
|
||||
try {
|
||||
const response = await fetch(`${API_BASE_URL}${url}`, {
|
||||
...options,
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
...options.headers
|
||||
}
|
||||
});
|
||||
|
||||
if (!response.ok) {
|
||||
throw new Error(`HTTP error! status: ${response.status}`);
|
||||
}
|
||||
|
||||
return await response.json();
|
||||
} catch (error) {
|
||||
console.error('API request error:', error);
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
import { get, post, put, del } from './request';
|
||||
|
||||
// 区域管理API
|
||||
export const regionApi = {
|
||||
getAll: () => request('/regions'),
|
||||
getById: (id) => request(`/regions/${id}`),
|
||||
create: (data) => request('/regions', {
|
||||
method: 'POST',
|
||||
body: JSON.stringify(data)
|
||||
}),
|
||||
update: (id, data) => request(`/regions/${id}`, {
|
||||
method: 'PUT',
|
||||
body: JSON.stringify(data)
|
||||
}),
|
||||
delete: (id) => request(`/regions/${id}`, {
|
||||
method: 'DELETE'
|
||||
})
|
||||
getAll: () => get('/regions'),
|
||||
getById: (id) => get(`/regions/${id}`),
|
||||
create: (data) => post('/regions', data),
|
||||
update: (id, data) => put(`/regions/${id}`, data),
|
||||
delete: (id) => del(`/regions/${id}`)
|
||||
};
|
||||
|
||||
// 构建查询字符串
|
||||
function buildQueryString(params) {
|
||||
const query = Object.entries(params)
|
||||
.filter(([key, value]) => value !== undefined && value !== null && value !== '')
|
||||
.map(([key, value]) => `${encodeURIComponent(key)}=${encodeURIComponent(value)}`)
|
||||
.join('&');
|
||||
return query ? `?${query}` : '';
|
||||
}
|
||||
|
||||
// 公寓管理API
|
||||
export const apartmentApi = {
|
||||
getAll: (params = {}) => request(`/apartments${buildQueryString(params)}`),
|
||||
getById: (id) => request(`/apartments/${id}`),
|
||||
create: (data) => request('/apartments', {
|
||||
method: 'POST',
|
||||
body: JSON.stringify(data)
|
||||
}),
|
||||
update: (id, data) => request(`/apartments/${id}`, {
|
||||
method: 'PUT',
|
||||
body: JSON.stringify(data)
|
||||
}),
|
||||
delete: (id) => request(`/apartments/${id}`, {
|
||||
method: 'DELETE'
|
||||
})
|
||||
getAll: (params = {}) => get('/apartments', params),
|
||||
getById: (id) => get(`/apartments/${id}`),
|
||||
create: (data) => post('/apartments', data),
|
||||
update: (id, data) => put(`/apartments/${id}`, data),
|
||||
delete: (id) => del(`/apartments/${id}`)
|
||||
};
|
||||
|
||||
// 房间管理API
|
||||
export const roomApi = {
|
||||
getAll: (params = {}) => request(`/rooms${buildQueryString(params)}`),
|
||||
getById: (id) => request(`/rooms/${id}`),
|
||||
create: (data) => request('/rooms', {
|
||||
method: 'POST',
|
||||
body: JSON.stringify(data)
|
||||
}),
|
||||
update: (id, data) => request(`/rooms/${id}`, {
|
||||
method: 'PUT',
|
||||
body: JSON.stringify(data)
|
||||
}),
|
||||
delete: (id) => request(`/rooms/${id}`, {
|
||||
method: 'DELETE'
|
||||
})
|
||||
getAll: (params = {}) => get('/rooms', params),
|
||||
getById: (id) => get(`/rooms/${id}`),
|
||||
create: (data) => post('/rooms', data),
|
||||
update: (id, data) => put(`/rooms/${id}`, data),
|
||||
delete: (id) => del(`/rooms/${id}`)
|
||||
};
|
||||
|
||||
// 租客管理API
|
||||
export const tenantApi = {
|
||||
getAll: () => request('/tenants'),
|
||||
getById: (id) => request(`/tenants/${id}`),
|
||||
create: (data) => request('/tenants', {
|
||||
method: 'POST',
|
||||
body: JSON.stringify(data)
|
||||
}),
|
||||
update: (id, data) => request(`/tenants/${id}`, {
|
||||
method: 'PUT',
|
||||
body: JSON.stringify(data)
|
||||
}),
|
||||
delete: (id) => request(`/tenants/${id}`, {
|
||||
method: 'DELETE'
|
||||
})
|
||||
getAll: () => get('/tenants'),
|
||||
getById: (id) => get(`/tenants/${id}`),
|
||||
create: (data) => post('/tenants', data),
|
||||
update: (id, data) => put(`/tenants/${id}`, data),
|
||||
delete: (id) => del(`/tenants/${id}`)
|
||||
};
|
||||
|
||||
// 合同管理API
|
||||
export const contractApi = {
|
||||
getAll: () => request('/contracts'),
|
||||
getById: (id) => request(`/contracts/${id}`),
|
||||
create: (data) => request('/contracts', {
|
||||
method: 'POST',
|
||||
body: JSON.stringify(data)
|
||||
}),
|
||||
update: (id, data) => request(`/contracts/${id}`, {
|
||||
method: 'PUT',
|
||||
body: JSON.stringify(data)
|
||||
}),
|
||||
delete: (id) => request(`/contracts/${id}`, {
|
||||
method: 'DELETE'
|
||||
})
|
||||
getAll: () => get('/contracts'),
|
||||
getById: (id) => get(`/contracts/${id}`),
|
||||
create: (data) => post('/contracts', data),
|
||||
update: (id, data) => put(`/contracts/${id}`, data),
|
||||
delete: (id) => del(`/contracts/${id}`)
|
||||
};
|
||||
|
||||
// 租房管理API
|
||||
export const rentalApi = {
|
||||
getAll: (params = {}) => request(`/rentals${buildQueryString(params)}`),
|
||||
getById: (id) => request(`/rentals/${id}`),
|
||||
create: (data) => request('/rentals', {
|
||||
method: 'POST',
|
||||
body: JSON.stringify(data)
|
||||
}),
|
||||
update: (id, data) => request(`/rentals/${id}`, {
|
||||
method: 'PUT',
|
||||
body: JSON.stringify(data)
|
||||
}),
|
||||
delete: (id) => request(`/rentals/${id}`, {
|
||||
method: 'DELETE'
|
||||
})
|
||||
getAll: (params = {}) => get('/rentals', params),
|
||||
getById: (id) => get(`/rentals/${id}`),
|
||||
create: (data) => post('/rentals', data),
|
||||
update: (id, data) => put(`/rentals/${id}`, data),
|
||||
delete: (id) => del(`/rentals/${id}`)
|
||||
};
|
||||
|
||||
// 统计分析API
|
||||
export const statisticsApi = {
|
||||
getRentData: () => request('/statistics/rent'),
|
||||
getRoomStatus: () => request('/statistics/room-status'),
|
||||
getRegionHouseStats: () => request('/statistics/region-house'),
|
||||
getRegionApartmentHouseStats: () => request('/statistics/region-apartment-house')
|
||||
getRentData: () => get('/statistics/rent'),
|
||||
getRoomStatus: () => get('/statistics/room-status'),
|
||||
getRegionHouseStats: () => get('/statistics/region-house'),
|
||||
getRegionApartmentHouseStats: () => get('/statistics/region-apartment-house')
|
||||
};
|
||||
|
||||
// 水费管理API
|
||||
export const waterBillApi = {
|
||||
getAll: (params = {}) => request(`/water-bills${buildQueryString(params)}`),
|
||||
getById: (id) => request(`/water-bills/${id}`),
|
||||
create: (data) => request('/water-bills', {
|
||||
method: 'POST',
|
||||
body: JSON.stringify(data)
|
||||
}),
|
||||
update: (id, data) => request(`/water-bills/${id}`, {
|
||||
method: 'PUT',
|
||||
body: JSON.stringify(data)
|
||||
}),
|
||||
delete: (id) => request(`/water-bills/${id}`, {
|
||||
method: 'DELETE'
|
||||
})
|
||||
getAll: (params = {}) => get('/water-bills', params),
|
||||
getById: (id) => get(`/water-bills/${id}`),
|
||||
create: (data) => post('/water-bills', data),
|
||||
update: (id, data) => put(`/water-bills/${id}`, data),
|
||||
delete: (id) => del(`/water-bills/${id}`)
|
||||
};
|
||||
|
||||
// 电费管理API
|
||||
export const electricityBillApi = {
|
||||
getAll: (params = {}) => request(`/electricity-bills${buildQueryString(params)}`),
|
||||
getById: (id) => request(`/electricity-bills/${id}`),
|
||||
create: (data) => request('/electricity-bills', {
|
||||
method: 'POST',
|
||||
body: JSON.stringify(data)
|
||||
}),
|
||||
update: (id, data) => request(`/electricity-bills/${id}`, {
|
||||
method: 'PUT',
|
||||
body: JSON.stringify(data)
|
||||
}),
|
||||
delete: (id) => request(`/electricity-bills/${id}`, {
|
||||
method: 'DELETE'
|
||||
})
|
||||
getAll: (params = {}) => get('/electricity-bills', params),
|
||||
getById: (id) => get(`/electricity-bills/${id}`),
|
||||
create: (data) => post('/electricity-bills', data),
|
||||
update: (id, data) => put(`/electricity-bills/${id}`, data),
|
||||
delete: (id) => del(`/electricity-bills/${id}`)
|
||||
};
|
||||
|
||||
export default {
|
||||
|
|
|
|||
|
|
@ -0,0 +1,70 @@
|
|||
// 统一请求处理
|
||||
|
||||
const API_BASE_URL = process.env.VUE_APP_API_BASE_URL || '/api';
|
||||
|
||||
// 通用请求函数
|
||||
export async function request(url, options = {}) {
|
||||
try {
|
||||
const response = await fetch(`${API_BASE_URL}${url}`, {
|
||||
...options,
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
...options.headers
|
||||
}
|
||||
});
|
||||
|
||||
if (!response.ok) {
|
||||
throw new Error(`HTTP error! status: ${response.status}`);
|
||||
}
|
||||
|
||||
return await response.json();
|
||||
} catch (error) {
|
||||
console.error('API request error:', error);
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
// GET 请求
|
||||
export function get(url, params = {}) {
|
||||
const queryString = Object.entries(params)
|
||||
.filter(([key, value]) => value !== undefined && value !== null && value !== '')
|
||||
.map(([key, value]) => `${encodeURIComponent(key)}=${encodeURIComponent(value)}`)
|
||||
.join('&');
|
||||
|
||||
const fullUrl = queryString ? `${url}?${queryString}` : url;
|
||||
|
||||
return request(fullUrl, {
|
||||
method: 'GET'
|
||||
});
|
||||
}
|
||||
|
||||
// POST 请求
|
||||
export function post(url, data = {}) {
|
||||
return request(url, {
|
||||
method: 'POST',
|
||||
body: JSON.stringify(data)
|
||||
});
|
||||
}
|
||||
|
||||
// PUT 请求
|
||||
export function put(url, data = {}) {
|
||||
return request(url, {
|
||||
method: 'PUT',
|
||||
body: JSON.stringify(data)
|
||||
});
|
||||
}
|
||||
|
||||
// DELETE 请求
|
||||
export function del(url) {
|
||||
return request(url, {
|
||||
method: 'DELETE'
|
||||
});
|
||||
}
|
||||
|
||||
export default {
|
||||
get,
|
||||
post,
|
||||
put,
|
||||
delete: del,
|
||||
request
|
||||
};
|
||||
|
|
@ -37,11 +37,13 @@
|
|||
</el-table>
|
||||
<div class="pagination" style="margin-top: 20px;">
|
||||
<el-pagination
|
||||
layout="prev, pager, next"
|
||||
layout="total, sizes, prev, pager, next, jumper"
|
||||
:total="total"
|
||||
:page-size="pageSize"
|
||||
:page-sizes="[10, 20, 50, 100]"
|
||||
:current-page="currentPage"
|
||||
@current-change="handleCurrentChange"
|
||||
@size-change="handleSizeChange"
|
||||
></el-pagination>
|
||||
</div>
|
||||
</el-card>
|
||||
|
|
@ -135,7 +137,12 @@ export default {
|
|||
},
|
||||
handleCurrentChange(val) {
|
||||
this.currentPage = val
|
||||
this.loadData()
|
||||
this.loadApartments()
|
||||
},
|
||||
handleSizeChange(val) {
|
||||
this.pageSize = val
|
||||
this.currentPage = 1
|
||||
this.loadApartments()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -19,7 +19,7 @@
|
|||
<el-button @click="resetSearch">重置</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<el-table :data="filteredContracts" style="width: 100%">
|
||||
<el-table :data="contracts" style="width: 100%" v-loading="isLoading">
|
||||
<el-table-column prop="id" label="ID" width="80"></el-table-column>
|
||||
<el-table-column prop="regionName" label="区域"></el-table-column>
|
||||
<el-table-column prop="apartmentName" label="公寓"></el-table-column>
|
||||
|
|
@ -39,11 +39,13 @@
|
|||
</el-table>
|
||||
<div class="pagination" style="margin-top: 20px;">
|
||||
<el-pagination
|
||||
layout="prev, pager, next"
|
||||
:total="filteredContracts.length"
|
||||
:page-size="10"
|
||||
layout="total, sizes, prev, pager, next, jumper"
|
||||
:total="total"
|
||||
:page-size="pageSize"
|
||||
:page-sizes="[10, 20, 50, 100]"
|
||||
:current-page="currentPage"
|
||||
@current-change="handleCurrentChange"
|
||||
@size-change="handleSizeChange"
|
||||
></el-pagination>
|
||||
</div>
|
||||
</el-card>
|
||||
|
|
@ -58,17 +60,13 @@ export default {
|
|||
data() {
|
||||
return {
|
||||
contracts: [],
|
||||
total: 0,
|
||||
searchForm: {
|
||||
status: ''
|
||||
},
|
||||
currentPage: 1
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
filteredContracts() {
|
||||
return this.contracts.filter(contract => {
|
||||
return !this.searchForm.status || contract.status == this.searchForm.status
|
||||
})
|
||||
currentPage: 1,
|
||||
pageSize: 10,
|
||||
isLoading: false
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
|
|
@ -76,12 +74,19 @@ export default {
|
|||
},
|
||||
methods: {
|
||||
async loadContracts() {
|
||||
this.isLoading = true
|
||||
try {
|
||||
// 加载合同数据
|
||||
const contractsResponse = await contractApi.getAll()
|
||||
const params = {
|
||||
status: this.searchForm.status,
|
||||
page: this.currentPage,
|
||||
pageSize: this.pageSize
|
||||
}
|
||||
const contractsResponse = await contractApi.getAll(params)
|
||||
|
||||
// 处理合同数据,使用后端返回的关联信息
|
||||
this.contracts = contractsResponse.map(contract => {
|
||||
const contracts = contractsResponse.data || contractsResponse
|
||||
this.contracts = contracts.map(contract => {
|
||||
return {
|
||||
...contract,
|
||||
roomNumber: contract.Room ? contract.Room.roomNumber : '',
|
||||
|
|
@ -90,8 +95,11 @@ export default {
|
|||
regionName: contract.Room && contract.Room.Apartment && contract.Room.Apartment.Region ? contract.Room.Apartment.Region.name : ''
|
||||
}
|
||||
})
|
||||
this.total = contractsResponse.total || 0
|
||||
} catch (error) {
|
||||
this.$message.error('加载数据失败')
|
||||
} finally {
|
||||
this.isLoading = false
|
||||
}
|
||||
},
|
||||
handleAdd() {
|
||||
|
|
@ -118,15 +126,24 @@ export default {
|
|||
})
|
||||
},
|
||||
handleSearch() {
|
||||
// 搜索逻辑
|
||||
this.currentPage = 1
|
||||
this.loadContracts()
|
||||
},
|
||||
resetSearch() {
|
||||
this.searchForm = {
|
||||
status: ''
|
||||
}
|
||||
this.currentPage = 1
|
||||
this.loadContracts()
|
||||
},
|
||||
handleCurrentChange(val) {
|
||||
this.currentPage = val
|
||||
this.loadContracts()
|
||||
},
|
||||
handleSizeChange(val) {
|
||||
this.pageSize = val
|
||||
this.currentPage = 1
|
||||
this.loadContracts()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -27,7 +27,7 @@
|
|||
<el-button @click="resetSearch">重置</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<el-table :data="filteredHouses" style="width: 100%">
|
||||
<el-table :data="houses" style="width: 100%" v-loading="isLoading">
|
||||
<el-table-column prop="id" label="ID" width="80"></el-table-column>
|
||||
<el-table-column prop="regionName" label="区域"></el-table-column>
|
||||
<el-table-column prop="address" label="地址"></el-table-column>
|
||||
|
|
@ -48,11 +48,13 @@
|
|||
</el-table>
|
||||
<div class="pagination" style="margin-top: 20px;">
|
||||
<el-pagination
|
||||
layout="prev, pager, next"
|
||||
:total="filteredHouses.length"
|
||||
:page-size="10"
|
||||
layout="total, sizes, prev, pager, next, jumper"
|
||||
:total="total"
|
||||
:page-size="pageSize"
|
||||
:page-sizes="[10, 20, 50, 100]"
|
||||
:current-page="currentPage"
|
||||
@current-change="handleCurrentChange"
|
||||
@size-change="handleSizeChange"
|
||||
></el-pagination>
|
||||
</div>
|
||||
</el-card>
|
||||
|
|
@ -68,20 +70,14 @@ export default {
|
|||
return {
|
||||
regions: [],
|
||||
houses: [],
|
||||
total: 0,
|
||||
searchForm: {
|
||||
regionId: '',
|
||||
status: ''
|
||||
},
|
||||
currentPage: 1
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
filteredHouses() {
|
||||
return this.houses.filter(house => {
|
||||
const regionMatch = !this.searchForm.regionId || house.regionId == this.searchForm.regionId
|
||||
const statusMatch = !this.searchForm.status || house.status == this.searchForm.status
|
||||
return regionMatch && statusMatch
|
||||
})
|
||||
currentPage: 1,
|
||||
pageSize: 10,
|
||||
isLoading: false
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
|
|
@ -89,22 +85,33 @@ export default {
|
|||
},
|
||||
methods: {
|
||||
async loadData() {
|
||||
this.isLoading = true
|
||||
try {
|
||||
// 加载区域数据
|
||||
const regionsResponse = await regionApi.getAll()
|
||||
this.regions = regionsResponse
|
||||
|
||||
// 加载房源数据
|
||||
const housesResponse = await houseApi.getAll()
|
||||
this.houses = housesResponse.map(house => {
|
||||
const params = {
|
||||
regionId: this.searchForm.regionId,
|
||||
status: this.searchForm.status,
|
||||
page: this.currentPage,
|
||||
pageSize: this.pageSize
|
||||
}
|
||||
const housesResponse = await houseApi.getAll(params)
|
||||
const houses = housesResponse.data || housesResponse
|
||||
this.houses = houses.map(house => {
|
||||
const region = regionsResponse.find(r => r.id == house.regionId)
|
||||
return {
|
||||
...house,
|
||||
regionName: region ? region.name : ''
|
||||
}
|
||||
})
|
||||
this.total = housesResponse.total || 0
|
||||
} catch (error) {
|
||||
this.$message.error('加载数据失败')
|
||||
} finally {
|
||||
this.isLoading = false
|
||||
}
|
||||
},
|
||||
getStatusType(status) {
|
||||
|
|
@ -147,16 +154,25 @@ export default {
|
|||
})
|
||||
},
|
||||
handleSearch() {
|
||||
// 搜索逻辑
|
||||
this.currentPage = 1
|
||||
this.loadData()
|
||||
},
|
||||
resetSearch() {
|
||||
this.searchForm = {
|
||||
regionId: '',
|
||||
status: ''
|
||||
}
|
||||
this.currentPage = 1
|
||||
this.loadData()
|
||||
},
|
||||
handleCurrentChange(val) {
|
||||
this.currentPage = val
|
||||
this.loadData()
|
||||
},
|
||||
handleSizeChange(val) {
|
||||
this.pageSize = val
|
||||
this.currentPage = 1
|
||||
this.loadData()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@
|
|||
<el-button type="primary" @click="handleAdd">添加区域</el-button>
|
||||
</div>
|
||||
</template>
|
||||
<el-table :data="regions" style="width: 100%">
|
||||
<el-table :data="regions" style="width: 100%" v-loading="isLoading">
|
||||
<el-table-column prop="id" label="ID" width="80"></el-table-column>
|
||||
<el-table-column prop="name" label="区域名称"></el-table-column>
|
||||
<el-table-column prop="description" label="区域描述"></el-table-column>
|
||||
|
|
@ -21,11 +21,13 @@
|
|||
</el-table>
|
||||
<div class="pagination" style="margin-top: 20px;">
|
||||
<el-pagination
|
||||
layout="prev, pager, next"
|
||||
:total="regions.length"
|
||||
:page-size="10"
|
||||
layout="total, sizes, prev, pager, next, jumper"
|
||||
:total="total"
|
||||
:page-size="pageSize"
|
||||
:page-sizes="[10, 20, 50, 100]"
|
||||
:current-page="currentPage"
|
||||
@current-change="handleCurrentChange"
|
||||
@size-change="handleSizeChange"
|
||||
></el-pagination>
|
||||
</div>
|
||||
</el-card>
|
||||
|
|
@ -40,7 +42,10 @@ export default {
|
|||
data() {
|
||||
return {
|
||||
regions: [],
|
||||
currentPage: 1
|
||||
total: 0,
|
||||
currentPage: 1,
|
||||
pageSize: 10,
|
||||
isLoading: false
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
|
|
@ -48,11 +53,19 @@ export default {
|
|||
},
|
||||
methods: {
|
||||
async loadRegions() {
|
||||
this.isLoading = true
|
||||
try {
|
||||
const response = await regionApi.getAll()
|
||||
this.regions = response
|
||||
const params = {
|
||||
page: this.currentPage,
|
||||
pageSize: this.pageSize
|
||||
}
|
||||
const response = await regionApi.getAll(params)
|
||||
this.regions = response.data || response
|
||||
this.total = response.total || 0
|
||||
} catch (error) {
|
||||
this.$message.error('加载区域数据失败')
|
||||
} finally {
|
||||
this.isLoading = false
|
||||
}
|
||||
},
|
||||
handleAdd() {
|
||||
|
|
@ -62,7 +75,7 @@ export default {
|
|||
this.$router.push(`/region/edit/${id}`)
|
||||
},
|
||||
async handleDelete(id) {
|
||||
this.$confirm('确定要删除这个区域吗?', '提示', {
|
||||
this.$confirm('确定要删除这个区域吗?', '提示', {
|
||||
confirmButtonText: '确定',
|
||||
cancelButtonText: '取消',
|
||||
type: 'warning'
|
||||
|
|
@ -75,11 +88,17 @@ export default {
|
|||
this.$message.error('删除失败')
|
||||
}
|
||||
}).catch(() => {
|
||||
this.$message.info('已取消删除')
|
||||
// 取消删除
|
||||
})
|
||||
},
|
||||
handleCurrentChange(val) {
|
||||
this.currentPage = val
|
||||
this.loadRegions()
|
||||
},
|
||||
handleSizeChange(val) {
|
||||
this.pageSize = val
|
||||
this.currentPage = 1
|
||||
this.loadRegions()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -34,8 +34,19 @@
|
|||
type="date"
|
||||
placeholder="选择开始日期"
|
||||
style="width: 100%"
|
||||
@change="updateEndDate"
|
||||
></el-date-picker>
|
||||
</el-form-item>
|
||||
<el-form-item label="租期" prop="leaseMonths">
|
||||
<el-select v-model="leaseMonths" placeholder="请选择租期" style="width: 100%" @change="updateEndDate">
|
||||
<el-option
|
||||
v-for="option in monthOptions"
|
||||
:key="option.value"
|
||||
:label="option.label"
|
||||
:value="option.value"
|
||||
></el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="结束日期" prop="endDate">
|
||||
<el-date-picker
|
||||
v-model="rentalForm.endDate"
|
||||
|
|
@ -44,7 +55,7 @@
|
|||
style="width: 100%"
|
||||
></el-date-picker>
|
||||
</el-form-item>
|
||||
<el-form-item label="租金(元/月)" prop="rent">
|
||||
<el-form-item label="租金(元)" prop="rent">
|
||||
<el-input v-model.number="rentalForm.rent" placeholder="请输入租金"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="押金(元)" prop="deposit">
|
||||
|
|
@ -88,22 +99,45 @@ export default {
|
|||
status: 'active',
|
||||
remark: ''
|
||||
},
|
||||
// 保存返回时的查询参数
|
||||
returnQuery: {},
|
||||
rules: {
|
||||
roomId: [{ required: true, message: '请选择房间', trigger: 'blur' }],
|
||||
tenantName: [{ required: true, message: '请输入租客姓名', trigger: 'blur' }],
|
||||
tenantPhone: [{ required: true, message: '请输入租客电话', trigger: 'blur' }],
|
||||
tenantIdCard: [{ required: true, message: '请输入身份证号', trigger: 'blur' }],
|
||||
tenantPhone: [{ message: '请输入租客电话', trigger: 'blur' }],
|
||||
tenantIdCard: [{ message: '请输入身份证号', trigger: 'blur' }],
|
||||
startDate: [{ required: true, message: '请选择开始日期', trigger: 'blur' }],
|
||||
endDate: [{ required: true, message: '请选择结束日期', trigger: 'blur' }],
|
||||
rent: [{ required: true, message: '请输入租金', trigger: 'blur' }],
|
||||
deposit: [{ required: true, message: '请输入押金', trigger: 'blur' }],
|
||||
deposit: [{ message: '请输入押金', trigger: 'blur' }],
|
||||
status: [{ required: true, message: '请选择状态', trigger: 'blur' }]
|
||||
},
|
||||
rooms: [],
|
||||
apartments: []
|
||||
apartments: [],
|
||||
leaseMonths: 1,
|
||||
monthOptions: [
|
||||
{ label: '1个月', value: 1 },
|
||||
{ label: '2个月', value: 2 },
|
||||
{ label: '3个月', value: 3 },
|
||||
{ label: '4个月', value: 4 },
|
||||
{ label: '5个月', value: 5 },
|
||||
{ label: '6个月', value: 6 },
|
||||
{ label: '7个月', value: 7 },
|
||||
{ label: '8个月', value: 8 },
|
||||
{ label: '9个月', value: 9 },
|
||||
{ label: '10个月', value: 10 },
|
||||
{ label: '11个月', value: 11 },
|
||||
{ label: '12个月', value: 12 }
|
||||
]
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
// 获取返回时的查询参数
|
||||
this.returnQuery = this.$route.query
|
||||
// 初始化开始日期为今天
|
||||
this.rentalForm.startDate = new Date()
|
||||
// 初始化结束日期
|
||||
this.updateEndDate()
|
||||
this.loadData()
|
||||
},
|
||||
methods: {
|
||||
|
|
@ -128,7 +162,7 @@ export default {
|
|||
const room = this.rooms.find(r => r.id.toString() == roomId.toString())
|
||||
if (room) {
|
||||
// 自动填充租金
|
||||
this.rentalForm.rent = room.price
|
||||
this.rentalForm.rent = room.monthlyPrice
|
||||
}
|
||||
}
|
||||
} catch (error) {
|
||||
|
|
@ -148,7 +182,10 @@ export default {
|
|||
try {
|
||||
await rentalApi.create(this.rentalForm)
|
||||
this.$message.success('添加成功')
|
||||
this.$router.push('/rental/list')
|
||||
this.$router.push({
|
||||
path: '/rental/list',
|
||||
query: this.returnQuery
|
||||
})
|
||||
} catch (error) {
|
||||
this.$message.error('添加失败')
|
||||
}
|
||||
|
|
@ -162,7 +199,17 @@ export default {
|
|||
this.$refs.rentalForm.resetFields()
|
||||
},
|
||||
goBack() {
|
||||
this.$router.push('/rental/list')
|
||||
this.$router.push({
|
||||
path: '/rental/list',
|
||||
query: this.returnQuery
|
||||
})
|
||||
},
|
||||
updateEndDate() {
|
||||
if (this.rentalForm.startDate) {
|
||||
const endDate = new Date(this.rentalForm.startDate)
|
||||
endDate.setMonth(endDate.getMonth() + this.leaseMonths)
|
||||
this.rentalForm.endDate = endDate
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -7,9 +7,10 @@
|
|||
<div class="action-buttons">
|
||||
<el-button v-if="room.status === 'empty'" type="primary" @click="handleRent">租房</el-button>
|
||||
<el-button v-if="room.status === 'rented'" type="warning" @click="handleCheckout">退房</el-button>
|
||||
<el-button v-if="room.status === 'empty'" type="info" @click="handleCleaning">打扫</el-button>
|
||||
<el-button v-if="room.status === 'empty'" type="danger" @click="handleMaintenance">维修</el-button>
|
||||
<el-button v-if="room.status === 'cleaning' || room.status === 'maintenance'" type="success" @click="handleComplete">完成</el-button>
|
||||
<el-button v-if="!room.otherStatus || room.otherStatus === ''" type="info" @click="handleCleaning">打扫</el-button>
|
||||
<el-button v-if="!room.otherStatus || room.otherStatus === ''" type="danger" @click="handleMaintenance">维修</el-button>
|
||||
<el-button v-if="room.otherStatus === 'cleaning'" type="success" @click="handleComplete">打扫完成</el-button>
|
||||
<el-button v-if="room.otherStatus === 'maintenance'" type="success" @click="handleComplete">维修完成</el-button>
|
||||
<el-button type="primary" @click="goBack">返回</el-button>
|
||||
</div>
|
||||
</div>
|
||||
|
|
@ -23,12 +24,17 @@
|
|||
</div>
|
||||
<div class="info-item">
|
||||
<span class="label">租金:</span>
|
||||
<span class="value">¥{{ room.price }}/月</span>
|
||||
<span class="value">
|
||||
¥{{ room.monthlyPrice }}/月
|
||||
<span v-if="room.yearlyPrice" style="margin-left: 10px;">¥{{ room.yearlyPrice }}/年</span>
|
||||
</span>
|
||||
</div>
|
||||
<div class="info-item">
|
||||
<span class="label">状态:</span>
|
||||
<span class="value">
|
||||
<span class="value" style="display: flex; gap: 8px;">
|
||||
<el-tag :type="getStatusType(room.status)">{{ getStatusText(room.status) }}</el-tag>
|
||||
<el-tag v-if="room.status === 'rented' && room.subStatus" :type="getSubStatusType(room.subStatus)">{{ getSubStatusText(room.subStatus) }}</el-tag>
|
||||
<el-tag v-if="room.otherStatus && room.otherStatus !== ''" :type="getOtherStatusType(room.otherStatus)">{{ getOtherStatusText(room.otherStatus) }}</el-tag>
|
||||
</span>
|
||||
</div>
|
||||
<div class="info-item">
|
||||
|
|
@ -55,6 +61,12 @@
|
|||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="createTime" label="创建时间" width="180"></el-table-column>
|
||||
<el-table-column label="操作" width="150">
|
||||
<template slot-scope="scope">
|
||||
<el-button type="primary" size="small" @click="handleEditRental(scope.row)">编辑</el-button>
|
||||
<el-button type="danger" size="small" @click="handleDeleteRental(scope.row.id)">删除</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
</el-tab-pane>
|
||||
<el-tab-pane label="水费记录" name="water">
|
||||
|
|
@ -174,6 +186,46 @@
|
|||
<el-button type="primary" @click="handleSaveElectricityBill">保存</el-button>
|
||||
</span>
|
||||
</el-dialog>
|
||||
|
||||
<!-- 租赁编辑对话框 -->
|
||||
<el-dialog title="编辑租赁记录" :visible.sync="rentalDialogVisible" width="500px">
|
||||
<el-form :model="rentalForm" :rules="rentalRules" ref="rentalForm">
|
||||
<el-form-item label="租客姓名" prop="tenantName">
|
||||
<el-input v-model="rentalForm.tenantName" placeholder="请输入租客姓名"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="租客电话" prop="tenantPhone">
|
||||
<el-input v-model="rentalForm.tenantPhone" placeholder="请输入租客电话"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="身份证号" prop="tenantIdCard">
|
||||
<el-input v-model="rentalForm.tenantIdCard" placeholder="请输入身份证号"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="开始日期" prop="startDate">
|
||||
<el-date-picker v-model="rentalForm.startDate" type="date" placeholder="选择开始日期" style="width: 100%"></el-date-picker>
|
||||
</el-form-item>
|
||||
<el-form-item label="结束日期" prop="endDate">
|
||||
<el-date-picker v-model="rentalForm.endDate" type="date" placeholder="选择结束日期" style="width: 100%"></el-date-picker>
|
||||
</el-form-item>
|
||||
<el-form-item label="租金(元)" prop="rent">
|
||||
<el-input v-model.number="rentalForm.rent" placeholder="请输入租金"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="押金(元)" prop="deposit">
|
||||
<el-input v-model.number="rentalForm.deposit" placeholder="请输入押金"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="状态" prop="status">
|
||||
<el-select v-model="rentalForm.status" placeholder="请选择状态" style="width: 100%">
|
||||
<el-option label="有效" value="active"></el-option>
|
||||
<el-option label="到期" value="expired"></el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="备注" prop="remark">
|
||||
<el-input v-model="rentalForm.remark" type="textarea" rows="3" placeholder="请输入备注信息"></el-input>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<span slot="footer" class="dialog-footer">
|
||||
<el-button @click="rentalDialogVisible = false">取消</el-button>
|
||||
<el-button type="primary" @click="handleSaveRental">保存</el-button>
|
||||
</span>
|
||||
</el-dialog>
|
||||
</el-card>
|
||||
</div>
|
||||
</template>
|
||||
|
|
@ -193,6 +245,8 @@ export default {
|
|||
electricityBills: [],
|
||||
isLoading: false,
|
||||
activeTab: 'rental',
|
||||
// 保存返回时的查询参数
|
||||
returnQuery: {},
|
||||
waterBillDialogVisible: false,
|
||||
electricityBillDialogVisible: false,
|
||||
waterBillForm: {
|
||||
|
|
@ -230,10 +284,34 @@ export default {
|
|||
endReading: [{ required: true, message: '请输入结束度数', trigger: 'blur' }],
|
||||
unitPrice: [{ required: true, message: '请输入单价', trigger: 'blur' }],
|
||||
status: [{ required: true, message: '请选择状态', trigger: 'change' }]
|
||||
},
|
||||
rentalDialogVisible: false,
|
||||
rentalForm: {
|
||||
id: '',
|
||||
roomId: '',
|
||||
tenantName: '',
|
||||
tenantPhone: '',
|
||||
tenantIdCard: '',
|
||||
startDate: '',
|
||||
endDate: '',
|
||||
rent: '',
|
||||
deposit: '',
|
||||
status: 'active',
|
||||
remark: ''
|
||||
},
|
||||
rentalRules: {
|
||||
tenantName: [{ required: true, message: '请输入租客姓名', trigger: 'blur' }],
|
||||
startDate: [{ required: true, message: '请选择开始日期', trigger: 'blur' }],
|
||||
endDate: [{ required: true, message: '请选择结束日期', trigger: 'blur' }],
|
||||
rent: [{ required: true, message: '请输入租金', trigger: 'blur' }],
|
||||
deposit: [{ message: '请输入押金', trigger: 'blur' }],
|
||||
status: [{ required: true, message: '请选择状态', trigger: 'blur' }]
|
||||
}
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
// 获取返回时的查询参数
|
||||
this.returnQuery = this.$route.query
|
||||
this.loadData()
|
||||
},
|
||||
methods: {
|
||||
|
|
@ -309,8 +387,44 @@ export default {
|
|||
default: return status
|
||||
}
|
||||
},
|
||||
getSubStatusType(status) {
|
||||
switch (status) {
|
||||
case 'normal': return 'success'
|
||||
case 'soon_expire': return 'warning'
|
||||
case 'expired': return 'danger'
|
||||
default: return ''
|
||||
}
|
||||
},
|
||||
getSubStatusText(status) {
|
||||
switch (status) {
|
||||
case 'normal': return '正常'
|
||||
case 'soon_expire': return '即将到期'
|
||||
case 'expired': return '已到期'
|
||||
default: return status
|
||||
}
|
||||
},
|
||||
getOtherStatusType(status) {
|
||||
switch (status) {
|
||||
case 'cleaning': return 'info'
|
||||
case 'maintenance': return 'danger'
|
||||
default: return ''
|
||||
}
|
||||
},
|
||||
getOtherStatusText(status) {
|
||||
switch (status) {
|
||||
case 'cleaning': return '打扫中'
|
||||
case 'maintenance': return '维修中'
|
||||
default: return status
|
||||
}
|
||||
},
|
||||
handleRent() {
|
||||
this.$router.push(`/rental/add?roomId=${this.room.id}`)
|
||||
this.$router.push({
|
||||
path: `/rental/add`,
|
||||
query: {
|
||||
roomId: this.room.id,
|
||||
...this.returnQuery
|
||||
}
|
||||
})
|
||||
},
|
||||
async handleCheckout() {
|
||||
this.$confirm('确定要退房吗?', '提示', {
|
||||
|
|
@ -350,7 +464,7 @@ export default {
|
|||
}).then(async () => {
|
||||
try {
|
||||
const roomId = this.$route.params.id
|
||||
await roomApi.update(roomId, { status: 'cleaning' })
|
||||
await roomApi.update(roomId, { otherStatus: 'cleaning' })
|
||||
this.$message.success('标记为打扫中成功')
|
||||
this.loadData()
|
||||
} catch (error) {
|
||||
|
|
@ -368,7 +482,7 @@ export default {
|
|||
}).then(async () => {
|
||||
try {
|
||||
const roomId = this.$route.params.id
|
||||
await roomApi.update(roomId, { status: 'maintenance' })
|
||||
await roomApi.update(roomId, { otherStatus: 'maintenance' })
|
||||
this.$message.success('标记为维修中成功')
|
||||
this.loadData()
|
||||
} catch (error) {
|
||||
|
|
@ -379,15 +493,15 @@ export default {
|
|||
})
|
||||
},
|
||||
async handleComplete() {
|
||||
this.$confirm('确定要完成打扫/维修并将状态改为空房吗?', '提示', {
|
||||
this.$confirm('确定要完成打扫/维修吗?', '提示', {
|
||||
confirmButtonText: '确定',
|
||||
cancelButtonText: '取消',
|
||||
type: 'success'
|
||||
}).then(async () => {
|
||||
try {
|
||||
const roomId = this.$route.params.id
|
||||
await roomApi.update(roomId, { status: 'empty' })
|
||||
this.$message.success('操作成功,房间状态已改为空房')
|
||||
await roomApi.update(roomId, { otherStatus: '' })
|
||||
this.$message.success('操作成功,已完成打扫/维修')
|
||||
this.loadData()
|
||||
} catch (error) {
|
||||
this.$message.error('操作失败')
|
||||
|
|
@ -514,8 +628,53 @@ export default {
|
|||
// 取消删除
|
||||
})
|
||||
},
|
||||
handleEditRental(rental) {
|
||||
this.rentalForm = {
|
||||
...rental,
|
||||
startDate: rental.startDate ? new Date(rental.startDate) : '',
|
||||
endDate: rental.endDate ? new Date(rental.endDate) : ''
|
||||
}
|
||||
this.rentalDialogVisible = true
|
||||
},
|
||||
async handleSaveRental() {
|
||||
try {
|
||||
if (this.rentalForm.id) {
|
||||
// 更新租赁记录
|
||||
await rentalApi.update(this.rentalForm.id, this.rentalForm)
|
||||
this.$message.success('租赁记录更新成功')
|
||||
} else {
|
||||
// 创建租赁记录
|
||||
await rentalApi.create(this.rentalForm)
|
||||
this.$message.success('租赁记录添加成功')
|
||||
}
|
||||
this.rentalDialogVisible = false
|
||||
this.loadData()
|
||||
} catch (error) {
|
||||
this.$message.error('操作失败')
|
||||
}
|
||||
},
|
||||
async handleDeleteRental(id) {
|
||||
this.$confirm('确定要删除这条租赁记录吗?', '提示', {
|
||||
confirmButtonText: '确定',
|
||||
cancelButtonText: '取消',
|
||||
type: 'danger'
|
||||
}).then(async () => {
|
||||
try {
|
||||
await rentalApi.delete(id)
|
||||
this.$message.success('租赁记录删除成功')
|
||||
this.loadData()
|
||||
} catch (error) {
|
||||
this.$message.error('删除失败')
|
||||
}
|
||||
}).catch(() => {
|
||||
// 取消删除
|
||||
})
|
||||
},
|
||||
goBack() {
|
||||
this.$router.push('/rental/list')
|
||||
this.$router.push({
|
||||
path: '/rental/list',
|
||||
query: this.returnQuery
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -44,7 +44,7 @@
|
|||
style="width: 100%"
|
||||
></el-date-picker>
|
||||
</el-form-item>
|
||||
<el-form-item label="租金(元/月)" prop="rent">
|
||||
<el-form-item label="租金(元)" prop="rent">
|
||||
<el-input v-model.number="rentalForm.rent" placeholder="请输入租金"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="押金(元)" prop="deposit">
|
||||
|
|
@ -85,15 +85,17 @@ export default {
|
|||
deposit: '',
|
||||
status: ''
|
||||
},
|
||||
// 保存返回时的查询参数
|
||||
returnQuery: {},
|
||||
rules: {
|
||||
roomId: [{ required: true, message: '请选择房间', trigger: 'blur' }],
|
||||
tenantName: [{ required: true, message: '请输入租客姓名', trigger: 'blur' }],
|
||||
tenantPhone: [{ required: true, message: '请输入租客电话', trigger: 'blur' }],
|
||||
tenantIdCard: [{ required: true, message: '请输入身份证号', trigger: 'blur' }],
|
||||
tenantPhone: [{ message: '请输入租客电话', trigger: 'blur' }],
|
||||
tenantIdCard: [{ message: '请输入身份证号', trigger: 'blur' }],
|
||||
startDate: [{ required: true, message: '请选择开始日期', trigger: 'blur' }],
|
||||
endDate: [{ required: true, message: '请选择结束日期', trigger: 'blur' }],
|
||||
rent: [{ required: true, message: '请输入租金', trigger: 'blur' }],
|
||||
deposit: [{ required: true, message: '请输入押金', trigger: 'blur' }],
|
||||
deposit: [{ message: '请输入押金', trigger: 'blur' }],
|
||||
status: [{ required: true, message: '请选择状态', trigger: 'blur' }]
|
||||
},
|
||||
rooms: [],
|
||||
|
|
@ -101,6 +103,8 @@ export default {
|
|||
}
|
||||
},
|
||||
mounted() {
|
||||
// 获取返回时的查询参数
|
||||
this.returnQuery = this.$route.query
|
||||
this.loadData()
|
||||
this.loadRentalData()
|
||||
},
|
||||
|
|
@ -144,7 +148,10 @@ export default {
|
|||
try {
|
||||
await rentalApi.update(this.rentalForm.id, this.rentalForm)
|
||||
this.$message.success('编辑成功')
|
||||
this.$router.push('/rental/list')
|
||||
this.$router.push({
|
||||
path: '/rental/list',
|
||||
query: this.returnQuery
|
||||
})
|
||||
} catch (error) {
|
||||
this.$message.error('编辑失败')
|
||||
}
|
||||
|
|
@ -158,7 +165,10 @@ export default {
|
|||
this.loadRentalData()
|
||||
},
|
||||
goBack() {
|
||||
this.$router.push('/rental/list')
|
||||
this.$router.push({
|
||||
path: '/rental/list',
|
||||
query: this.returnQuery
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -13,17 +13,31 @@
|
|||
<el-option v-for="apartment in apartments" :key="apartment.id" :label="apartment.name" :value="apartment.id"></el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="状态">
|
||||
<el-select v-model="searchForm.status" placeholder="请选择状态">
|
||||
<el-form-item label="主状态">
|
||||
<el-select v-model="searchForm.status" placeholder="请选择主状态">
|
||||
<el-option label="全部" value=""></el-option>
|
||||
<el-option label="空房" value="empty"></el-option>
|
||||
<el-option label="在租" value="rented"></el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="附属状态">
|
||||
<el-select v-model="searchForm.subStatus" placeholder="请选择附属状态">
|
||||
<el-option label="全部" value=""></el-option>
|
||||
<el-option label="正常" value="normal"></el-option>
|
||||
<el-option label="即将到期" value="soon_expire"></el-option>
|
||||
<el-option label="已到期" value="expired"></el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="其他状态">
|
||||
<el-select v-model="searchForm.otherStatus" placeholder="请选择其他状态">
|
||||
<el-option label="全部" value=""></el-option>
|
||||
<el-option label="打扫中" value="cleaning"></el-option>
|
||||
<el-option label="维修中" value="maintenance"></el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="房间号">
|
||||
<el-input v-model="searchForm.roomNumber" placeholder="请输入房间号"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button type="primary" @click="handleSearch">搜索</el-button>
|
||||
<el-button @click="resetSearch">重置</el-button>
|
||||
|
|
@ -37,17 +51,24 @@
|
|||
style="cursor: pointer;"
|
||||
>
|
||||
<el-card
|
||||
:class="['room-card', `status-${room.status}`]"
|
||||
:class="['room-card', `status-${room.status === 'rented' ? room.subStatus : room.status}`]"
|
||||
>
|
||||
<div class="room-card-header">
|
||||
<h3>{{ getApartmentName(room.apartmentId) }}</h3>
|
||||
<el-tag :type="getStatusType(room.status)">{{ getStatusText(room.status) }}</el-tag>
|
||||
<div style="display: flex; gap: 8px;">
|
||||
<el-tag v-if="room.status === 'rented'" :type="getSubStatusType(room.subStatus)">{{ getSubStatusText(room.subStatus) }}</el-tag>
|
||||
<el-tag v-else>空房</el-tag>
|
||||
<el-tag v-if="room.otherStatus" :type="getOtherStatusType(room.otherStatus)">{{ getOtherStatusText(room.otherStatus) }}</el-tag>
|
||||
</div>
|
||||
</div>
|
||||
<div class="room-card-body">
|
||||
<div class="room-info">
|
||||
<span class="room-number">{{ room.roomNumber }}</span>
|
||||
<span class="room-area">{{ room.area }}㎡</span>
|
||||
<span class="room-price">¥{{ room.price }}/月</span>
|
||||
<div class="price-info">
|
||||
<span class="room-price">¥{{ room.monthlyPrice }}/月</span>
|
||||
<span v-if="room.yearlyPrice" class="room-price yearly">¥{{ room.yearlyPrice }}/年</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="rental-info" v-if="room.Rentals && room.Rentals.length > 0">
|
||||
<p>租客: {{ room.Rentals[0].Tenant.name }}</p>
|
||||
|
|
@ -87,7 +108,10 @@ export default {
|
|||
total: 0,
|
||||
searchForm: {
|
||||
apartmentId: '',
|
||||
status: ''
|
||||
status: '',
|
||||
subStatus: '',
|
||||
otherStatus: '',
|
||||
roomNumber: ''
|
||||
},
|
||||
currentPage: 1,
|
||||
pageSize: 50,
|
||||
|
|
@ -95,9 +119,26 @@ export default {
|
|||
}
|
||||
},
|
||||
mounted() {
|
||||
// 从路由参数中获取查询参数和页码
|
||||
this.initFromQuery()
|
||||
this.loadData()
|
||||
},
|
||||
methods: {
|
||||
// 从路由参数初始化搜索参数和页码
|
||||
initFromQuery() {
|
||||
const query = this.$route.query
|
||||
if (query) {
|
||||
// 初始化搜索参数
|
||||
if (query.apartmentId) this.searchForm.apartmentId = parseInt(query.apartmentId)
|
||||
if (query.status) this.searchForm.status = query.status
|
||||
if (query.subStatus) this.searchForm.subStatus = query.subStatus
|
||||
if (query.otherStatus) this.searchForm.otherStatus = query.otherStatus
|
||||
if (query.roomNumber) this.searchForm.roomNumber = query.roomNumber
|
||||
// 初始化页码
|
||||
if (query.page) this.currentPage = parseInt(query.page)
|
||||
if (query.pageSize) this.pageSize = parseInt(query.pageSize)
|
||||
}
|
||||
},
|
||||
async loadData() {
|
||||
if (this.isLoading) return
|
||||
|
||||
|
|
@ -111,6 +152,9 @@ export default {
|
|||
const params = {
|
||||
apartmentId: this.searchForm.apartmentId,
|
||||
status: this.searchForm.status,
|
||||
subStatus: this.searchForm.subStatus,
|
||||
otherStatus: this.searchForm.otherStatus,
|
||||
roomNumber: this.searchForm.roomNumber,
|
||||
page: this.currentPage,
|
||||
pageSize: this.pageSize
|
||||
}
|
||||
|
|
@ -135,23 +179,31 @@ export default {
|
|||
const apartment = this.apartments.find(a => a.id == apartmentId)
|
||||
return apartment ? apartment.name : ''
|
||||
},
|
||||
getStatusType(status) {
|
||||
getSubStatusType(status) {
|
||||
switch (status) {
|
||||
case 'empty': return ''
|
||||
case 'rented': return 'success'
|
||||
case 'normal': return 'success'
|
||||
case 'soon_expire': return 'warning'
|
||||
case 'expired': return 'danger'
|
||||
default: return ''
|
||||
}
|
||||
},
|
||||
getSubStatusText(status) {
|
||||
switch (status) {
|
||||
case 'normal': return '正常'
|
||||
case 'soon_expire': return '即将到期'
|
||||
case 'expired': return '已到期'
|
||||
default: return status
|
||||
}
|
||||
},
|
||||
getOtherStatusType(status) {
|
||||
switch (status) {
|
||||
case 'cleaning': return 'info'
|
||||
case 'maintenance': return 'danger'
|
||||
default: return ''
|
||||
}
|
||||
},
|
||||
getStatusText(status) {
|
||||
getOtherStatusText(status) {
|
||||
switch (status) {
|
||||
case 'empty': return '空房'
|
||||
case 'rented': return '在租'
|
||||
case 'soon_expire': return '即将到期'
|
||||
case 'expired': return '到期'
|
||||
case 'cleaning': return '打扫中'
|
||||
case 'maintenance': return '维修中'
|
||||
default: return status
|
||||
|
|
@ -163,7 +215,15 @@ export default {
|
|||
},
|
||||
handleRoomClick(roomId) {
|
||||
try {
|
||||
this.$router.push(`/rental/detail/${roomId}`)
|
||||
// 保存当前的查询参数和页码到路由参数
|
||||
this.$router.push({
|
||||
path: `/rental/detail/${roomId}`,
|
||||
query: {
|
||||
...this.searchForm,
|
||||
page: this.currentPage,
|
||||
pageSize: this.pageSize
|
||||
}
|
||||
})
|
||||
} catch (error) {
|
||||
console.error('Navigation error:', error)
|
||||
}
|
||||
|
|
@ -175,18 +235,39 @@ export default {
|
|||
resetSearch() {
|
||||
this.searchForm = {
|
||||
apartmentId: '',
|
||||
status: ''
|
||||
status: '',
|
||||
subStatus: '',
|
||||
otherStatus: '',
|
||||
roomNumber: ''
|
||||
}
|
||||
this.currentPage = 1
|
||||
this.loadData()
|
||||
},
|
||||
handleCurrentChange(val) {
|
||||
this.currentPage = val
|
||||
// 更新路由参数,保存查询状态
|
||||
this.$router.push({
|
||||
path: this.$route.path,
|
||||
query: {
|
||||
...this.searchForm,
|
||||
page: this.currentPage,
|
||||
pageSize: this.pageSize
|
||||
}
|
||||
})
|
||||
this.loadData()
|
||||
},
|
||||
handleSizeChange(val) {
|
||||
this.pageSize = val
|
||||
this.currentPage = 1
|
||||
// 更新路由参数,保存查询状态
|
||||
this.$router.push({
|
||||
path: this.$route.path,
|
||||
query: {
|
||||
...this.searchForm,
|
||||
page: this.currentPage,
|
||||
pageSize: this.pageSize
|
||||
}
|
||||
})
|
||||
this.loadData()
|
||||
}
|
||||
}
|
||||
|
|
@ -259,6 +340,7 @@ export default {
|
|||
.room-info {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
margin-bottom: 15px;
|
||||
padding-bottom: 15px;
|
||||
border-bottom: 1px solid #e4e7ed;
|
||||
|
|
@ -274,11 +356,23 @@ export default {
|
|||
color: #606266;
|
||||
}
|
||||
|
||||
.price-info {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: flex-end;
|
||||
}
|
||||
|
||||
.room-price {
|
||||
color: #409EFF;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.room-price.yearly {
|
||||
font-size: 12px;
|
||||
color: #909399;
|
||||
margin-top: 2px;
|
||||
}
|
||||
|
||||
.rental-info {
|
||||
margin-top: 10px;
|
||||
flex: 1;
|
||||
|
|
@ -298,7 +392,7 @@ export default {
|
|||
background-color: #f9f9f9;
|
||||
}
|
||||
|
||||
.status-rented {
|
||||
.status-normal {
|
||||
border-color: #67c23a;
|
||||
background-color: #f0f9eb;
|
||||
}
|
||||
|
|
@ -312,14 +406,4 @@ export default {
|
|||
border-color: #f56c6c;
|
||||
background-color: #fef0f0;
|
||||
}
|
||||
|
||||
.status-cleaning {
|
||||
border-color: #909399;
|
||||
background-color: #f4f4f5;
|
||||
}
|
||||
|
||||
.status-maintenance {
|
||||
border-color: #303133;
|
||||
background-color: #f4f4f5;
|
||||
}
|
||||
</style>
|
||||
|
|
@ -18,15 +18,30 @@
|
|||
<el-form-item label="面积(㎡)" prop="area">
|
||||
<el-input type="number" v-model="roomForm.area" placeholder="请输入面积"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="租金(元/月)" prop="price">
|
||||
<el-input type="number" v-model="roomForm.price" placeholder="请输入租金"></el-input>
|
||||
<el-form-item label="月租金(元)" prop="monthlyPrice">
|
||||
<el-input type="number" v-model="roomForm.monthlyPrice" placeholder="请输入月租金"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="状态" prop="status">
|
||||
<el-select v-model="roomForm.status" placeholder="请选择状态">
|
||||
<el-form-item label="年租金(元)" prop="yearlyPrice">
|
||||
<el-input type="number" v-model="roomForm.yearlyPrice" placeholder="请输入年租金"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="主状态" prop="status">
|
||||
<el-select v-model="roomForm.status" placeholder="请选择主状态">
|
||||
<el-option label="空房" value="empty"></el-option>
|
||||
<el-option label="在租" value="rented"></el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="附属状态" prop="subStatus" v-if="roomForm.status === 'rented'">
|
||||
<el-select v-model="roomForm.subStatus" placeholder="请选择附属状态">
|
||||
<el-option label="正常" value="normal"></el-option>
|
||||
<el-option label="即将到期" value="soon_expire"></el-option>
|
||||
<el-option label="已到期" value="expired"></el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="其他状态" prop="otherStatus">
|
||||
<el-select v-model="roomForm.otherStatus" placeholder="请选择其他状态">
|
||||
<el-option label="无" value=""></el-option>
|
||||
<el-option label="打扫中" value="cleaning"></el-option>
|
||||
<el-option label="维修中" value="maintenance"></el-option>
|
||||
</el-select>
|
||||
|
|
@ -52,8 +67,11 @@ export default {
|
|||
apartmentId: '',
|
||||
roomNumber: '',
|
||||
area: '',
|
||||
price: '',
|
||||
status: 'empty'
|
||||
monthlyPrice: '',
|
||||
yearlyPrice: '',
|
||||
status: 'empty',
|
||||
otherStatus: '',
|
||||
subStatus: 'normal'
|
||||
},
|
||||
apartments: [],
|
||||
rules: {
|
||||
|
|
@ -75,7 +93,18 @@ export default {
|
|||
}
|
||||
}, trigger: 'blur' }
|
||||
],
|
||||
price: [
|
||||
monthlyPrice: [
|
||||
{ validator: (rule, value, callback) => {
|
||||
if (value === '' || value === null || value === undefined) {
|
||||
callback()
|
||||
} else if (isNaN(Number(value))) {
|
||||
callback(new Error('请输入数字'))
|
||||
} else {
|
||||
callback()
|
||||
}
|
||||
}, trigger: 'blur' }
|
||||
],
|
||||
yearlyPrice: [
|
||||
{ validator: (rule, value, callback) => {
|
||||
if (value === '' || value === null || value === undefined) {
|
||||
callback()
|
||||
|
|
|
|||
|
|
@ -18,15 +18,30 @@
|
|||
<el-form-item label="面积(㎡)" prop="area">
|
||||
<el-input type="number" v-model="roomForm.area" placeholder="请输入面积"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="租金(元/月)" prop="price">
|
||||
<el-input type="number" v-model="roomForm.price" placeholder="请输入租金"></el-input>
|
||||
<el-form-item label="月租金(元)" prop="monthlyPrice">
|
||||
<el-input type="number" v-model="roomForm.monthlyPrice" placeholder="请输入月租金"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="状态" prop="status">
|
||||
<el-select v-model="roomForm.status" placeholder="请选择状态">
|
||||
<el-form-item label="年租金(元)" prop="yearlyPrice">
|
||||
<el-input type="number" v-model="roomForm.yearlyPrice" placeholder="请输入年租金"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="主状态" prop="status">
|
||||
<el-select v-model="roomForm.status" placeholder="请选择主状态">
|
||||
<el-option label="空房" value="empty"></el-option>
|
||||
<el-option label="在租" value="rented"></el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="附属状态" prop="subStatus" v-if="roomForm.status === 'rented'">
|
||||
<el-select v-model="roomForm.subStatus" placeholder="请选择附属状态">
|
||||
<el-option label="正常" value="normal"></el-option>
|
||||
<el-option label="即将到期" value="soon_expire"></el-option>
|
||||
<el-option label="已到期" value="expired"></el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="其他状态" prop="otherStatus">
|
||||
<el-select v-model="roomForm.otherStatus" placeholder="请选择其他状态">
|
||||
<el-option label="无" value=""></el-option>
|
||||
<el-option label="打扫中" value="cleaning"></el-option>
|
||||
<el-option label="维修中" value="maintenance"></el-option>
|
||||
</el-select>
|
||||
|
|
@ -53,9 +68,14 @@ export default {
|
|||
apartmentId: '',
|
||||
roomNumber: '',
|
||||
area: '',
|
||||
price: '',
|
||||
status: ''
|
||||
monthlyPrice: '',
|
||||
yearlyPrice: '',
|
||||
status: '',
|
||||
otherStatus: '',
|
||||
subStatus: 'normal'
|
||||
},
|
||||
// 保存返回时的查询参数
|
||||
returnQuery: {},
|
||||
apartments: [],
|
||||
rules: {
|
||||
apartmentId: [
|
||||
|
|
@ -76,7 +96,18 @@ export default {
|
|||
}
|
||||
}, trigger: 'blur' }
|
||||
],
|
||||
price: [
|
||||
monthlyPrice: [
|
||||
{ validator: (rule, value, callback) => {
|
||||
if (value === '' || value === null || value === undefined) {
|
||||
callback()
|
||||
} else if (isNaN(Number(value))) {
|
||||
callback(new Error('请输入数字'))
|
||||
} else {
|
||||
callback()
|
||||
}
|
||||
}, trigger: 'blur' }
|
||||
],
|
||||
yearlyPrice: [
|
||||
{ validator: (rule, value, callback) => {
|
||||
if (value === '' || value === null || value === undefined) {
|
||||
callback()
|
||||
|
|
@ -94,6 +125,8 @@ export default {
|
|||
}
|
||||
},
|
||||
mounted() {
|
||||
// 获取返回时的查询参数
|
||||
this.returnQuery = this.$route.query
|
||||
this.loadApartments()
|
||||
this.loadRoomData()
|
||||
},
|
||||
|
|
@ -123,7 +156,10 @@ export default {
|
|||
try {
|
||||
await roomApi.update(this.roomForm.id, this.roomForm)
|
||||
this.$message.success('编辑成功')
|
||||
this.$router.push('/room/list')
|
||||
this.$router.push({
|
||||
path: '/room/list',
|
||||
query: this.returnQuery
|
||||
})
|
||||
} catch (error) {
|
||||
this.$message.error('编辑失败')
|
||||
}
|
||||
|
|
@ -136,7 +172,10 @@ export default {
|
|||
this.loadRoomData()
|
||||
},
|
||||
goBack() {
|
||||
this.$router.push('/room/list')
|
||||
this.$router.push({
|
||||
path: '/room/list',
|
||||
query: this.returnQuery
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -14,13 +14,24 @@
|
|||
<el-option v-for="apartment in apartments" :key="apartment.id" :label="apartment.name" :value="apartment.id"></el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="状态">
|
||||
<el-select v-model="searchForm.status" placeholder="请选择状态">
|
||||
<el-form-item label="主状态">
|
||||
<el-select v-model="searchForm.status" placeholder="请选择主状态">
|
||||
<el-option label="全部" value=""></el-option>
|
||||
<el-option label="空房" value="empty"></el-option>
|
||||
<el-option label="在租" value="rented"></el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="附属状态">
|
||||
<el-select v-model="searchForm.subStatus" placeholder="请选择附属状态">
|
||||
<el-option label="全部" value=""></el-option>
|
||||
<el-option label="正常" value="normal"></el-option>
|
||||
<el-option label="即将到期" value="soon_expire"></el-option>
|
||||
<el-option label="已到期" value="expired"></el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="其他状态">
|
||||
<el-select v-model="searchForm.otherStatus" placeholder="请选择其他状态">
|
||||
<el-option label="全部" value=""></el-option>
|
||||
<el-option label="打扫中" value="cleaning"></el-option>
|
||||
<el-option label="维修中" value="maintenance"></el-option>
|
||||
</el-select>
|
||||
|
|
@ -40,14 +51,29 @@
|
|||
<el-table-column prop="apartmentName" label="公寓" width="150"></el-table-column>
|
||||
<el-table-column prop="roomNumber" label="房间号" width="100"></el-table-column>
|
||||
<el-table-column prop="area" label="面积(㎡)" width="100"></el-table-column>
|
||||
<el-table-column prop="price" label="租金(元/月)" width="120"></el-table-column>
|
||||
<el-table-column prop="status" label="状态" width="120">
|
||||
<el-table-column prop="monthlyPrice" label="月租金(元)" width="120"></el-table-column>
|
||||
<el-table-column prop="yearlyPrice" label="年租金(元)" width="120"></el-table-column>
|
||||
<el-table-column prop="status" label="主状态" width="100">
|
||||
<template slot-scope="scope">
|
||||
<el-tag :type="getStatusType(scope.row.status)">{{ getStatusText(scope.row.status) }}</el-tag>
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
||||
<el-table-column prop="subStatus" label="附属状态" width="120">
|
||||
<template slot-scope="scope">
|
||||
<el-tag v-if="scope.row.status === 'rented'" :type="getSubStatusType(scope.row.subStatus)">{{ getSubStatusText(scope.row.subStatus) }}</el-tag>
|
||||
<span v-else>无</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="createTime" label="创建时间" width="180"></el-table-column>
|
||||
<el-table-column label="操作" width="150">
|
||||
<el-table-column prop="otherStatus" label="其他状态" width="120">
|
||||
<template slot-scope="scope">
|
||||
<el-tag v-if="scope.row.otherStatus" :type="getOtherStatusType(scope.row.otherStatus)">{{ getOtherStatusText(scope.row.otherStatus) }}</el-tag>
|
||||
<span v-else>无</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
||||
<el-table-column label="操作" width="200">
|
||||
<template slot-scope="scope">
|
||||
<el-button size="small" type="primary" @click="handleEdit(scope.row.id)">编辑</el-button>
|
||||
<el-button size="small" type="danger" @click="handleDelete(scope.row.id)">删除</el-button>
|
||||
|
|
@ -56,11 +82,13 @@
|
|||
</el-table>
|
||||
<div class="pagination" style="margin-top: 20px;">
|
||||
<el-pagination
|
||||
layout="prev, pager, next"
|
||||
layout="total, sizes, prev, pager, next, jumper"
|
||||
:total="total"
|
||||
:page-size="pageSize"
|
||||
:page-sizes="[10, 20, 50, 100]"
|
||||
:current-page="currentPage"
|
||||
@current-change="handleCurrentChange"
|
||||
@size-change="handleSizeChange"
|
||||
></el-pagination>
|
||||
</div>
|
||||
</el-card>
|
||||
|
|
@ -74,12 +102,14 @@ export default {
|
|||
name: 'RoomList',
|
||||
data() {
|
||||
return {
|
||||
apartments: [],
|
||||
rooms: [],
|
||||
apartments: [],
|
||||
total: 0,
|
||||
searchForm: {
|
||||
apartmentId: '',
|
||||
status: '',
|
||||
subStatus: '',
|
||||
otherStatus: '',
|
||||
roomNumber: ''
|
||||
},
|
||||
currentPage: 1,
|
||||
|
|
@ -88,9 +118,26 @@ export default {
|
|||
}
|
||||
},
|
||||
mounted() {
|
||||
// 从路由参数中获取查询参数和页码
|
||||
this.initFromQuery()
|
||||
this.loadData()
|
||||
},
|
||||
methods: {
|
||||
// 从路由参数初始化搜索参数和页码
|
||||
initFromQuery() {
|
||||
const query = this.$route.query
|
||||
if (query) {
|
||||
// 初始化搜索参数
|
||||
if (query.apartmentId) this.searchForm.apartmentId = parseInt(query.apartmentId)
|
||||
if (query.status) this.searchForm.status = query.status
|
||||
if (query.subStatus) this.searchForm.subStatus = query.subStatus
|
||||
if (query.otherStatus) this.searchForm.otherStatus = query.otherStatus
|
||||
if (query.roomNumber) this.searchForm.roomNumber = query.roomNumber
|
||||
// 初始化页码
|
||||
if (query.page) this.currentPage = parseInt(query.page)
|
||||
if (query.pageSize) this.pageSize = parseInt(query.pageSize)
|
||||
}
|
||||
},
|
||||
async loadData() {
|
||||
if (this.isLoading) return
|
||||
|
||||
|
|
@ -104,6 +151,8 @@ export default {
|
|||
const params = {
|
||||
apartmentId: this.searchForm.apartmentId,
|
||||
status: this.searchForm.status,
|
||||
otherStatus: this.searchForm.otherStatus,
|
||||
subStatus: this.searchForm.subStatus,
|
||||
roomNumber: this.searchForm.roomNumber,
|
||||
page: this.currentPage,
|
||||
pageSize: this.pageSize
|
||||
|
|
@ -142,10 +191,6 @@ export default {
|
|||
switch (status) {
|
||||
case 'empty': return ''
|
||||
case 'rented': return 'success'
|
||||
case 'soon_expire': return 'warning'
|
||||
case 'expired': return 'danger'
|
||||
case 'cleaning': return 'info'
|
||||
case 'maintenance': return 'danger'
|
||||
default: return ''
|
||||
}
|
||||
},
|
||||
|
|
@ -153,18 +198,52 @@ export default {
|
|||
switch (status) {
|
||||
case 'empty': return '空房'
|
||||
case 'rented': return '在租'
|
||||
case 'soon_expire': return '即将到期'
|
||||
case 'expired': return '到期'
|
||||
default: return status
|
||||
}
|
||||
},
|
||||
getOtherStatusType(status) {
|
||||
switch (status) {
|
||||
case 'cleaning': return 'info'
|
||||
case 'maintenance': return 'danger'
|
||||
default: return ''
|
||||
}
|
||||
},
|
||||
getOtherStatusText(status) {
|
||||
switch (status) {
|
||||
case 'cleaning': return '打扫中'
|
||||
case 'maintenance': return '维修中'
|
||||
default: return status
|
||||
}
|
||||
},
|
||||
getSubStatusType(status) {
|
||||
switch (status) {
|
||||
case 'normal': return 'success'
|
||||
case 'soon_expire': return 'warning'
|
||||
case 'expired': return 'danger'
|
||||
default: return ''
|
||||
}
|
||||
},
|
||||
getSubStatusText(status) {
|
||||
switch (status) {
|
||||
case 'normal': return '正常'
|
||||
case 'soon_expire': return '即将到期'
|
||||
case 'expired': return '已到期'
|
||||
default: return status
|
||||
}
|
||||
},
|
||||
handleAdd() {
|
||||
this.$router.push('/room/add')
|
||||
},
|
||||
handleEdit(id) {
|
||||
this.$router.push(`/room/edit/${id}`)
|
||||
// 保存当前的查询参数和页码到路由参数
|
||||
this.$router.push({
|
||||
path: `/room/edit/${id}`,
|
||||
query: {
|
||||
...this.searchForm,
|
||||
page: this.currentPage,
|
||||
pageSize: this.pageSize
|
||||
}
|
||||
})
|
||||
},
|
||||
async handleDelete(id) {
|
||||
this.$confirm('确定要删除这个房间吗?', '提示', {
|
||||
|
|
@ -191,6 +270,8 @@ export default {
|
|||
this.searchForm = {
|
||||
apartmentId: '',
|
||||
status: '',
|
||||
otherStatus: '',
|
||||
subStatus: '',
|
||||
roomNumber: ''
|
||||
}
|
||||
this.currentPage = 1
|
||||
|
|
@ -199,6 +280,11 @@ export default {
|
|||
handleCurrentChange(val) {
|
||||
this.currentPage = val
|
||||
this.loadData()
|
||||
},
|
||||
handleSizeChange(val) {
|
||||
this.pageSize = val
|
||||
this.currentPage = 1
|
||||
this.loadData()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -18,7 +18,7 @@
|
|||
<el-button @click="resetSearch">重置</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<el-table :data="filteredTenants" style="width: 100%">
|
||||
<el-table :data="tenants" style="width: 100%" v-loading="isLoading">
|
||||
<el-table-column prop="id" label="ID" width="80"></el-table-column>
|
||||
<el-table-column prop="name" label="姓名"></el-table-column>
|
||||
<el-table-column prop="phone" label="电话"></el-table-column>
|
||||
|
|
@ -28,11 +28,13 @@
|
|||
</el-table>
|
||||
<div class="pagination" style="margin-top: 20px;">
|
||||
<el-pagination
|
||||
layout="prev, pager, next"
|
||||
:total="filteredTenants.length"
|
||||
:page-size="10"
|
||||
layout="total, sizes, prev, pager, next, jumper"
|
||||
:total="total"
|
||||
:page-size="pageSize"
|
||||
:page-sizes="[10, 20, 50, 100]"
|
||||
:current-page="currentPage"
|
||||
@current-change="handleCurrentChange"
|
||||
@size-change="handleSizeChange"
|
||||
></el-pagination>
|
||||
</div>
|
||||
</el-card>
|
||||
|
|
@ -47,20 +49,14 @@ export default {
|
|||
data() {
|
||||
return {
|
||||
tenants: [],
|
||||
total: 0,
|
||||
searchForm: {
|
||||
name: '',
|
||||
phone: ''
|
||||
},
|
||||
currentPage: 1
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
filteredTenants() {
|
||||
return this.tenants.filter(tenant => {
|
||||
const nameMatch = !this.searchForm.name || tenant.name.includes(this.searchForm.name)
|
||||
const phoneMatch = !this.searchForm.phone || tenant.phone.includes(this.searchForm.phone)
|
||||
return nameMatch && phoneMatch
|
||||
})
|
||||
currentPage: 1,
|
||||
pageSize: 10,
|
||||
isLoading: false
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
|
|
@ -68,11 +64,21 @@ export default {
|
|||
},
|
||||
methods: {
|
||||
async loadTenants() {
|
||||
this.isLoading = true
|
||||
try {
|
||||
const response = await tenantApi.getAll()
|
||||
this.tenants = response
|
||||
const params = {
|
||||
name: this.searchForm.name,
|
||||
phone: this.searchForm.phone,
|
||||
page: this.currentPage,
|
||||
pageSize: this.pageSize
|
||||
}
|
||||
const response = await tenantApi.getAll(params)
|
||||
this.tenants = response.data || response
|
||||
this.total = response.total || 0
|
||||
} catch (error) {
|
||||
this.$message.error('加载租客数据失败')
|
||||
} finally {
|
||||
this.isLoading = false
|
||||
}
|
||||
},
|
||||
handleAdd() {
|
||||
|
|
@ -99,16 +105,25 @@ export default {
|
|||
})
|
||||
},
|
||||
handleSearch() {
|
||||
// 搜索逻辑
|
||||
this.currentPage = 1
|
||||
this.loadTenants()
|
||||
},
|
||||
resetSearch() {
|
||||
this.searchForm = {
|
||||
name: '',
|
||||
phone: ''
|
||||
}
|
||||
this.currentPage = 1
|
||||
this.loadTenants()
|
||||
},
|
||||
handleCurrentChange(val) {
|
||||
this.currentPage = val
|
||||
this.loadTenants()
|
||||
},
|
||||
handleSizeChange(val) {
|
||||
this.pageSize = val
|
||||
this.currentPage = 1
|
||||
this.loadTenants()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,14 @@
|
|||
module.exports = {
|
||||
devServer: {
|
||||
proxy: {
|
||||
'/api': {
|
||||
target: 'http://localhost:3000',
|
||||
changeOrigin: true,
|
||||
pathRewrite: {
|
||||
'^/api': '/api'
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
lintOnSave: false
|
||||
};
|
||||
Loading…
Reference in New Issue