Commit 2c760b978dd3fcc8f758ef3f5b063cb7017f74f1
1 parent
a3057712
完成停车功能
Showing
22 changed files
with
2407 additions
and
5 deletions
src/api/car/addParkingSpaceApplyApi.js
0 → 100644
| 1 | +import request from '@/utils/request' | ||
| 2 | + | ||
| 3 | +// 查询业主列表 | ||
| 4 | +export function queryOwners(params) { | ||
| 5 | + return new Promise((resolve, reject) => { | ||
| 6 | + request({ | ||
| 7 | + url: '/owner.queryOwners', | ||
| 8 | + method: 'get', | ||
| 9 | + params | ||
| 10 | + }).then(response => { | ||
| 11 | + const res = response.data | ||
| 12 | + if (res.code === 0) { | ||
| 13 | + resolve({ | ||
| 14 | + data: res.data, | ||
| 15 | + total: res.records, | ||
| 16 | + currentPage: params.page, | ||
| 17 | + pageSize: params.row | ||
| 18 | + }) | ||
| 19 | + } else { | ||
| 20 | + reject(new Error(res.msg || 'Failed to query owners')) | ||
| 21 | + } | ||
| 22 | + }).catch(error => { | ||
| 23 | + reject(error) | ||
| 24 | + }) | ||
| 25 | + }) | ||
| 26 | +} | ||
| 27 | + | ||
| 28 | +// 保存车位申请 | ||
| 29 | +export function saveParkingSpaceApply(data) { | ||
| 30 | + return new Promise((resolve, reject) => { | ||
| 31 | + request({ | ||
| 32 | + url: '/parkingSpaceApply.saveParkingSpaceApply', | ||
| 33 | + method: 'post', | ||
| 34 | + data | ||
| 35 | + }).then(response => { | ||
| 36 | + const res = response.data | ||
| 37 | + if (res.code === 0) { | ||
| 38 | + resolve(res) | ||
| 39 | + } else { | ||
| 40 | + reject(new Error(res.msg || 'Failed to save parking space apply')) | ||
| 41 | + } | ||
| 42 | + }).catch(error => { | ||
| 43 | + reject(error) | ||
| 44 | + }) | ||
| 45 | + }) | ||
| 46 | +} | ||
| 0 | \ No newline at end of file | 47 | \ No newline at end of file |
src/api/car/auditParkingSpaceApplyApi.js
0 → 100644
| 1 | +import request from '@/utils/request' | ||
| 2 | + | ||
| 3 | +// 查询停车位申请详情 | ||
| 4 | +export function getParkingSpaceApplyDetail(params) { | ||
| 5 | + return new Promise((resolve, reject) => { | ||
| 6 | + request({ | ||
| 7 | + url: '/parkingSpaceApply.listParkingSpaceApply', | ||
| 8 | + method: 'get', | ||
| 9 | + params | ||
| 10 | + }).then(response => { | ||
| 11 | + const res = response.data | ||
| 12 | + if (res.code == 0) { | ||
| 13 | + resolve(res) | ||
| 14 | + } else { | ||
| 15 | + reject(new Error(res.msg || '获取申请详情失败')) | ||
| 16 | + } | ||
| 17 | + }).catch(error => { | ||
| 18 | + reject(error) | ||
| 19 | + }) | ||
| 20 | + }) | ||
| 21 | +} | ||
| 22 | + | ||
| 23 | +// 审核停车位申请 | ||
| 24 | +export function auditParkingSpaceApply(data) { | ||
| 25 | + return new Promise((resolve, reject) => { | ||
| 26 | + request({ | ||
| 27 | + url: '/parkingSpaceApply.auditParkingSpaceApply', | ||
| 28 | + method: 'post', | ||
| 29 | + data | ||
| 30 | + }).then(response => { | ||
| 31 | + const res = response.data | ||
| 32 | + if (res.code == 0) { | ||
| 33 | + resolve(res) | ||
| 34 | + } else { | ||
| 35 | + reject(new Error(res.msg || '审核失败')) | ||
| 36 | + } | ||
| 37 | + }).catch(error => { | ||
| 38 | + reject(error) | ||
| 39 | + }) | ||
| 40 | + }) | ||
| 41 | +} | ||
| 42 | + | ||
| 43 | +// 查询停车位列表 | ||
| 44 | +export function queryParkingSpaces(params) { | ||
| 45 | + return new Promise((resolve, reject) => { | ||
| 46 | + request({ | ||
| 47 | + url: '/parkingSpace.queryParkingSpaces', | ||
| 48 | + method: 'get', | ||
| 49 | + params | ||
| 50 | + }).then(response => { | ||
| 51 | + const res = response.data | ||
| 52 | + if (res.code == 0) { | ||
| 53 | + resolve(res) | ||
| 54 | + } else { | ||
| 55 | + reject(new Error(res.msg || '查询停车位失败')) | ||
| 56 | + } | ||
| 57 | + }).catch(error => { | ||
| 58 | + reject(error) | ||
| 59 | + }) | ||
| 60 | + }) | ||
| 61 | +} | ||
| 62 | + | ||
| 63 | +// 查询停车场列表 | ||
| 64 | +export function listParkingAreas(params) { | ||
| 65 | + return new Promise((resolve, reject) => { | ||
| 66 | + request({ | ||
| 67 | + url: '/parkingArea.listParkingAreas', | ||
| 68 | + method: 'get', | ||
| 69 | + params | ||
| 70 | + }).then(response => { | ||
| 71 | + const res = response.data | ||
| 72 | + if (res.code == 0) { | ||
| 73 | + resolve(res) | ||
| 74 | + } else { | ||
| 75 | + reject(new Error(res.msg || '查询停车场失败')) | ||
| 76 | + } | ||
| 77 | + }).catch(error => { | ||
| 78 | + reject(error) | ||
| 79 | + }) | ||
| 80 | + }) | ||
| 81 | +} | ||
| 0 | \ No newline at end of file | 82 | \ No newline at end of file |
src/api/car/parkingSpaceApplyManageApi.js
0 → 100644
| 1 | +import request from '@/utils/request' | ||
| 2 | +import { getCommunityId } from '@/api/community/communityApi' | ||
| 3 | + | ||
| 4 | +// 获取车位申请列表 | ||
| 5 | +export function listParkingSpaceApply(params) { | ||
| 6 | + return new Promise((resolve, reject) => { | ||
| 7 | + params.communityId = getCommunityId() | ||
| 8 | + request({ | ||
| 9 | + url: '/parkingSpaceApply.listParkingSpaceApply', | ||
| 10 | + method: 'get', | ||
| 11 | + params | ||
| 12 | + }).then(response => { | ||
| 13 | + const res = response.data | ||
| 14 | + if (res.code === 0) { | ||
| 15 | + resolve(res) | ||
| 16 | + } else { | ||
| 17 | + reject(new Error(res.msg || '获取车位申请列表失败')) | ||
| 18 | + } | ||
| 19 | + }).catch(error => { | ||
| 20 | + reject(error) | ||
| 21 | + }) | ||
| 22 | + }) | ||
| 23 | +} | ||
| 24 | + | ||
| 25 | +// 更新车位申请 | ||
| 26 | +export function updateParkingSpaceApply(data) { | ||
| 27 | + return new Promise((resolve, reject) => { | ||
| 28 | + data.communityId = getCommunityId() | ||
| 29 | + request({ | ||
| 30 | + url: '/parkingSpaceApply.updateParkingSpaceApply', | ||
| 31 | + method: 'post', | ||
| 32 | + data | ||
| 33 | + }).then(response => { | ||
| 34 | + const res = response.data | ||
| 35 | + if (res.code === 0) { | ||
| 36 | + resolve(res) | ||
| 37 | + } else { | ||
| 38 | + reject(new Error(res.msg || '更新车位申请失败')) | ||
| 39 | + } | ||
| 40 | + }).catch(error => { | ||
| 41 | + reject(error) | ||
| 42 | + }) | ||
| 43 | + }) | ||
| 44 | +} | ||
| 45 | + | ||
| 46 | +// 删除车位申请 | ||
| 47 | +export function deleteParkingSpaceApply(data) { | ||
| 48 | + return new Promise((resolve, reject) => { | ||
| 49 | + data.communityId = getCommunityId() | ||
| 50 | + request({ | ||
| 51 | + url: '/parkingSpaceApply.deleteParkingSpaceApply', | ||
| 52 | + method: 'post', | ||
| 53 | + data | ||
| 54 | + }).then(response => { | ||
| 55 | + const res = response.data | ||
| 56 | + if (res.code === 0) { | ||
| 57 | + resolve(res) | ||
| 58 | + } else { | ||
| 59 | + reject(new Error(res.msg || '删除车位申请失败')) | ||
| 60 | + } | ||
| 61 | + }).catch(error => { | ||
| 62 | + reject(error) | ||
| 63 | + }) | ||
| 64 | + }) | ||
| 65 | +} | ||
| 0 | \ No newline at end of file | 66 | \ No newline at end of file |
src/api/car/remainingParkingSpaceApi.js
0 → 100644
| 1 | +import request from '@/utils/request' | ||
| 2 | + | ||
| 3 | +/** | ||
| 4 | + * 获取剩余车位信息 | ||
| 5 | + * @param {Object} params 请求参数 | ||
| 6 | + * @returns {Promise} Promise对象 | ||
| 7 | + */ | ||
| 8 | +export function getRemainingParkingSpace(params) { | ||
| 9 | + return new Promise((resolve, reject) => { | ||
| 10 | + request({ | ||
| 11 | + url: '/iot.getOpenApi', | ||
| 12 | + method: 'get', | ||
| 13 | + params | ||
| 14 | + }).then(response => { | ||
| 15 | + const res = response.data | ||
| 16 | + if (res.code === 0) { | ||
| 17 | + resolve(res) | ||
| 18 | + } else { | ||
| 19 | + reject(new Error(res.msg || 'Failed to get remaining parking space')) | ||
| 20 | + } | ||
| 21 | + }).catch(error => { | ||
| 22 | + reject(error) | ||
| 23 | + }) | ||
| 24 | + }) | ||
| 25 | +} | ||
| 0 | \ No newline at end of file | 26 | \ No newline at end of file |
src/api/car/tempCarPaymentApi.js
0 → 100644
| 1 | +import request from '@/utils/request' | ||
| 2 | + | ||
| 3 | +// 获取停车区域列表 | ||
| 4 | +export function listParkingAreas(params) { | ||
| 5 | + return new Promise((resolve, reject) => { | ||
| 6 | + request({ | ||
| 7 | + url: '/parkingArea.listParkingAreas', | ||
| 8 | + method: 'get', | ||
| 9 | + params | ||
| 10 | + }).then(response => { | ||
| 11 | + const res = response.data | ||
| 12 | + resolve(res) | ||
| 13 | + }).catch(error => { | ||
| 14 | + reject(error) | ||
| 15 | + }) | ||
| 16 | + }) | ||
| 17 | +} | ||
| 18 | + | ||
| 19 | +// 获取车辆进出支付列表 | ||
| 20 | +export function getCarInoutPaymentList(params) { | ||
| 21 | + return new Promise((resolve, reject) => { | ||
| 22 | + request({ | ||
| 23 | + url: '/iot.getOpenApi', | ||
| 24 | + method: 'get', | ||
| 25 | + params | ||
| 26 | + }).then(response => { | ||
| 27 | + const res = response.data | ||
| 28 | + if (res.code === 0) { | ||
| 29 | + resolve({ | ||
| 30 | + data: res.data, | ||
| 31 | + total: res.total, | ||
| 32 | + records: res.records | ||
| 33 | + }) | ||
| 34 | + } else { | ||
| 35 | + reject(new Error(res.msg || '获取车辆进出支付列表失败')) | ||
| 36 | + } | ||
| 37 | + }).catch(error => { | ||
| 38 | + reject(error) | ||
| 39 | + }) | ||
| 40 | + }) | ||
| 41 | +} | ||
| 0 | \ No newline at end of file | 42 | \ No newline at end of file |
src/components/car/chooseParkingSpace.vue
0 → 100644
| 1 | +<template> | ||
| 2 | + <el-dialog :title="$t('auditParkingSpaceApply.selectParkingSpace')" :visible.sync="visible" width="80%" | ||
| 3 | + @close="handleClose"> | ||
| 4 | + <el-card> | ||
| 5 | + <el-row :gutter="20"> | ||
| 6 | + <el-col :span="18"></el-col> | ||
| 7 | + <el-col :span="6"> | ||
| 8 | + <el-input-group> | ||
| 9 | + <el-input v-model="searchParams.areaNum" :placeholder="$t('auditParkingSpaceApply.inputParkingLot')" /> | ||
| 10 | + <el-button type="primary" @click="queryParkingSpaces"> | ||
| 11 | + {{ $t('common.search') }} | ||
| 12 | + </el-button> | ||
| 13 | + </el-input-group> | ||
| 14 | + </el-col> | ||
| 15 | + </el-row> | ||
| 16 | + | ||
| 17 | + <el-table :data="parkingSpaces" style="width: 100%" border> | ||
| 18 | + <el-table-column prop="areaNum" :label="$t('auditParkingSpaceApply.parkingLot')" align="center"> | ||
| 19 | + <template slot-scope="scope"> | ||
| 20 | + {{ scope.row.areaNum }}{{ $t('auditParkingSpaceApply.parkingLotUnit') }} | ||
| 21 | + </template> | ||
| 22 | + </el-table-column> | ||
| 23 | + <el-table-column prop="num" :label="$t('auditParkingSpaceApply.parkingSpace')" align="center"> | ||
| 24 | + <template slot-scope="scope"> | ||
| 25 | + {{ scope.row.num }}{{ $t('auditParkingSpaceApply.parkingSpaceUnit') }} | ||
| 26 | + </template> | ||
| 27 | + </el-table-column> | ||
| 28 | + <el-table-column prop="state" :label="$t('auditParkingSpaceApply.parkingStatus')" align="center"> | ||
| 29 | + <template slot-scope="scope"> | ||
| 30 | + {{ viewParkingSpaceState(scope.row.state) }} | ||
| 31 | + </template> | ||
| 32 | + </el-table-column> | ||
| 33 | + <el-table-column prop="parkingTypeName" :label="$t('auditParkingSpaceApply.parkingType')" align="center" /> | ||
| 34 | + <el-table-column prop="area" :label="$t('auditParkingSpaceApply.area')" align="center" /> | ||
| 35 | + <el-table-column prop="psId" :label="$t('auditParkingSpaceApply.parkingSpace') + 'ID'" align="center" /> | ||
| 36 | + <el-table-column :label="$t('auditParkingSpaceApply.operation')" align="center"> | ||
| 37 | + <template slot-scope="scope"> | ||
| 38 | + <el-button size="mini" type="primary" @click="chooseParkingSpace(scope.row)"> | ||
| 39 | + {{ $t('auditParkingSpaceApply.choose') }} | ||
| 40 | + </el-button> | ||
| 41 | + </template> | ||
| 42 | + </el-table-column> | ||
| 43 | + </el-table> | ||
| 44 | + | ||
| 45 | + <el-pagination :current-page="pagination.currentPage" :page-sizes="[10, 20, 30, 50]" | ||
| 46 | + :page-size="pagination.pageSize" layout="total, sizes, prev, pager, next, jumper" :total="pagination.total" | ||
| 47 | + @size-change="handleSizeChange" @current-change="handleCurrentChange" /> | ||
| 48 | + </el-card> | ||
| 49 | + </el-dialog> | ||
| 50 | +</template> | ||
| 51 | + | ||
| 52 | +<script> | ||
| 53 | +import { queryParkingSpaces } from '@/api/car/auditParkingSpaceApplyApi' | ||
| 54 | +import { getCommunityId } from '@/api/community/communityApi' | ||
| 55 | + | ||
| 56 | +export default { | ||
| 57 | + name: 'ChooseParkingSpace', | ||
| 58 | + props: { | ||
| 59 | + visible: { | ||
| 60 | + type: Boolean, | ||
| 61 | + default: false | ||
| 62 | + }, | ||
| 63 | + paId: { | ||
| 64 | + type: String, | ||
| 65 | + default: '' | ||
| 66 | + } | ||
| 67 | + }, | ||
| 68 | + data() { | ||
| 69 | + return { | ||
| 70 | + searchParams: { | ||
| 71 | + areaNum: '', | ||
| 72 | + state: 'F' // 默认查询空闲车位 | ||
| 73 | + }, | ||
| 74 | + parkingSpaces: [], | ||
| 75 | + pagination: { | ||
| 76 | + currentPage: 1, | ||
| 77 | + pageSize: 10, | ||
| 78 | + total: 0 | ||
| 79 | + }, | ||
| 80 | + communityId: getCommunityId() | ||
| 81 | + } | ||
| 82 | + }, | ||
| 83 | + methods: { | ||
| 84 | + open() { | ||
| 85 | + this.visible = true | ||
| 86 | + this.queryParkingSpaces() | ||
| 87 | + }, | ||
| 88 | + handleClose() { | ||
| 89 | + this.$emit('update:visible', false) | ||
| 90 | + }, | ||
| 91 | + async queryParkingSpaces() { | ||
| 92 | + try { | ||
| 93 | + const params = { | ||
| 94 | + page: this.pagination.currentPage, | ||
| 95 | + row: this.pagination.pageSize, | ||
| 96 | + communityId: this.communityId, | ||
| 97 | + ...this.searchParams, | ||
| 98 | + paId: this.paId | ||
| 99 | + } | ||
| 100 | + | ||
| 101 | + const res = await queryParkingSpaces(params) | ||
| 102 | + this.parkingSpaces = res.data.parkingSpaces | ||
| 103 | + this.pagination.total = res.data.total | ||
| 104 | + } catch (error) { | ||
| 105 | + this.$message.error(this.$t('common.queryFailed')) | ||
| 106 | + } | ||
| 107 | + }, | ||
| 108 | + chooseParkingSpace(parkingSpace) { | ||
| 109 | + this.$emit('choose', parkingSpace) | ||
| 110 | + this.handleClose() | ||
| 111 | + }, | ||
| 112 | + viewParkingSpaceState(state) { | ||
| 113 | + const states = { | ||
| 114 | + 'F': this.$t('auditParkingSpaceApply.free'), | ||
| 115 | + 'S': this.$t('auditParkingSpaceApply.sold'), | ||
| 116 | + 'H': this.$t('auditParkingSpaceApply.rented'), | ||
| 117 | + } | ||
| 118 | + return states[state] || this.$t('auditParkingSpaceApply.unknown') | ||
| 119 | + }, | ||
| 120 | + handleSizeChange(val) { | ||
| 121 | + this.pagination.pageSize = val | ||
| 122 | + this.queryParkingSpaces() | ||
| 123 | + }, | ||
| 124 | + handleCurrentChange(val) { | ||
| 125 | + this.pagination.currentPage = val | ||
| 126 | + this.queryParkingSpaces() | ||
| 127 | + } | ||
| 128 | + } | ||
| 129 | +} | ||
| 130 | +</script> | ||
| 131 | + | ||
| 132 | +<style scoped> | ||
| 133 | +.el-input-group { | ||
| 134 | + display: flex; | ||
| 135 | +} | ||
| 136 | +</style> | ||
| 0 | \ No newline at end of file | 137 | \ No newline at end of file |
src/components/car/deleteParkingSpaceApply.vue
0 → 100644
| 1 | +<template> | ||
| 2 | + <el-dialog | ||
| 3 | + :title="$t('deleteParkingSpaceApply.confirmOperation')" | ||
| 4 | + :visible.sync="visible" | ||
| 5 | + width="500px" | ||
| 6 | + > | ||
| 7 | + <div class="text-center"> | ||
| 8 | + <p style="font-size: 16px; margin-bottom: 20px;"> | ||
| 9 | + {{ $t('deleteParkingSpaceApply.deletePrompt') }} | ||
| 10 | + </p> | ||
| 11 | + </div> | ||
| 12 | + | ||
| 13 | + <div slot="footer" class="dialog-footer"> | ||
| 14 | + <el-button @click="visible = false"> | ||
| 15 | + {{ $t('deleteParkingSpaceApply.cancel') }} | ||
| 16 | + </el-button> | ||
| 17 | + <el-button type="danger" @click="confirmDelete"> | ||
| 18 | + {{ $t('deleteParkingSpaceApply.confirmDeleteAction') }} | ||
| 19 | + </el-button> | ||
| 20 | + </div> | ||
| 21 | + </el-dialog> | ||
| 22 | +</template> | ||
| 23 | + | ||
| 24 | +<script> | ||
| 25 | +import { deleteParkingSpaceApply } from '@/api/car/parkingSpaceApplyManageApi' | ||
| 26 | + | ||
| 27 | +export default { | ||
| 28 | + name: 'DeleteParkingSpaceApply', | ||
| 29 | + data() { | ||
| 30 | + return { | ||
| 31 | + visible: false, | ||
| 32 | + currentApply: {} | ||
| 33 | + } | ||
| 34 | + }, | ||
| 35 | + methods: { | ||
| 36 | + open(apply) { | ||
| 37 | + this.currentApply = { ...apply } | ||
| 38 | + this.visible = true | ||
| 39 | + }, | ||
| 40 | + | ||
| 41 | + async confirmDelete() { | ||
| 42 | + try { | ||
| 43 | + const response = await deleteParkingSpaceApply({ | ||
| 44 | + applyId: this.currentApply.applyId | ||
| 45 | + }) | ||
| 46 | + | ||
| 47 | + if (response.code === 0) { | ||
| 48 | + this.$message.success(this.$t('common.deleteSuccess')) | ||
| 49 | + this.visible = false | ||
| 50 | + this.$emit('success') | ||
| 51 | + } else { | ||
| 52 | + this.$message.error(response.msg || this.$t('common.deleteFailed')) | ||
| 53 | + } | ||
| 54 | + } catch (error) { | ||
| 55 | + console.error('Error deleting parking space application:', error) | ||
| 56 | + this.$message.error(this.$t('common.requestError')) | ||
| 57 | + } | ||
| 58 | + } | ||
| 59 | + } | ||
| 60 | +} | ||
| 61 | +</script> | ||
| 0 | \ No newline at end of file | 62 | \ No newline at end of file |
src/components/car/editParkingSpaceApply.vue
0 → 100644
| 1 | +<template> | ||
| 2 | + <el-dialog | ||
| 3 | + :title="$t('editParkingSpaceApply.editApplication')" | ||
| 4 | + :visible.sync="visible" | ||
| 5 | + width="800px" | ||
| 6 | + @close="closeDialog" | ||
| 7 | + > | ||
| 8 | + <el-form | ||
| 9 | + ref="form" | ||
| 10 | + :model="formData" | ||
| 11 | + :rules="rules" | ||
| 12 | + label-width="150px" | ||
| 13 | + > | ||
| 14 | + <el-form-item | ||
| 15 | + :label="$t('editParkingSpaceApply.licensePlate')" | ||
| 16 | + prop="carNum" | ||
| 17 | + > | ||
| 18 | + <el-input | ||
| 19 | + v-model="formData.carNum" | ||
| 20 | + :placeholder="$t('editParkingSpaceApply.fillLicensePlate')" | ||
| 21 | + /> | ||
| 22 | + </el-form-item> | ||
| 23 | + | ||
| 24 | + <el-form-item | ||
| 25 | + :label="$t('editParkingSpaceApply.carBrand')" | ||
| 26 | + prop="carBrand" | ||
| 27 | + > | ||
| 28 | + <el-input | ||
| 29 | + v-model="formData.carBrand" | ||
| 30 | + :placeholder="$t('editParkingSpaceApply.fillCarBrand')" | ||
| 31 | + /> | ||
| 32 | + </el-form-item> | ||
| 33 | + | ||
| 34 | + <el-form-item | ||
| 35 | + :label="$t('editParkingSpaceApply.vehicleType')" | ||
| 36 | + prop="carType" | ||
| 37 | + > | ||
| 38 | + <el-select | ||
| 39 | + v-model="formData.carType" | ||
| 40 | + :placeholder="$t('editParkingSpaceApply.selectVehicleType')" | ||
| 41 | + style="width: 100%" | ||
| 42 | + > | ||
| 43 | + <el-option | ||
| 44 | + :label="$t('parkingSpaceApplyManage.homeCar')" | ||
| 45 | + value="9901" | ||
| 46 | + /> | ||
| 47 | + <el-option | ||
| 48 | + :label="$t('parkingSpaceApplyManage.bus')" | ||
| 49 | + value="9902" | ||
| 50 | + /> | ||
| 51 | + <el-option | ||
| 52 | + :label="$t('parkingSpaceApplyManage.truck')" | ||
| 53 | + value="9903" | ||
| 54 | + /> | ||
| 55 | + </el-select> | ||
| 56 | + </el-form-item> | ||
| 57 | + | ||
| 58 | + <el-form-item | ||
| 59 | + :label="$t('editParkingSpaceApply.color')" | ||
| 60 | + prop="carColor" | ||
| 61 | + > | ||
| 62 | + <el-input | ||
| 63 | + v-model="formData.carColor" | ||
| 64 | + :placeholder="$t('editParkingSpaceApply.fillColor')" | ||
| 65 | + /> | ||
| 66 | + </el-form-item> | ||
| 67 | + | ||
| 68 | + <el-form-item | ||
| 69 | + :label="$t('editParkingSpaceApply.startTime')" | ||
| 70 | + prop="startTime" | ||
| 71 | + > | ||
| 72 | + <el-date-picker | ||
| 73 | + v-model="formData.startTime" | ||
| 74 | + type="datetime" | ||
| 75 | + :placeholder="$t('editParkingSpaceApply.fillStartTime')" | ||
| 76 | + value-format="yyyy-MM-dd HH:mm:ss" | ||
| 77 | + style="width: 100%" | ||
| 78 | + /> | ||
| 79 | + </el-form-item> | ||
| 80 | + | ||
| 81 | + <el-form-item | ||
| 82 | + :label="$t('editParkingSpaceApply.endTime')" | ||
| 83 | + prop="endTime" | ||
| 84 | + > | ||
| 85 | + <el-date-picker | ||
| 86 | + v-model="formData.endTime" | ||
| 87 | + type="datetime" | ||
| 88 | + :placeholder="$t('editParkingSpaceApply.fillEndTime')" | ||
| 89 | + value-format="yyyy-MM-dd HH:mm:ss" | ||
| 90 | + style="width: 100%" | ||
| 91 | + /> | ||
| 92 | + </el-form-item> | ||
| 93 | + | ||
| 94 | + <el-form-item :label="$t('editParkingSpaceApply.applicant')"> | ||
| 95 | + <el-input | ||
| 96 | + v-model="formData.applyPersonName" | ||
| 97 | + disabled | ||
| 98 | + :placeholder="$t('editParkingSpaceApply.fillApplicant')" | ||
| 99 | + /> | ||
| 100 | + </el-form-item> | ||
| 101 | + | ||
| 102 | + <el-form-item :label="$t('editParkingSpaceApply.applicantPhone')"> | ||
| 103 | + <el-input | ||
| 104 | + v-model="formData.applyPersonLink" | ||
| 105 | + disabled | ||
| 106 | + :placeholder="$t('editParkingSpaceApply.fillApplicantPhone')" | ||
| 107 | + /> | ||
| 108 | + </el-form-item> | ||
| 109 | + | ||
| 110 | + <el-form-item :label="$t('editParkingSpaceApply.remarks')"> | ||
| 111 | + <el-input | ||
| 112 | + v-model="formData.remark" | ||
| 113 | + type="textarea" | ||
| 114 | + :rows="3" | ||
| 115 | + :placeholder="$t('editParkingSpaceApply.optional')" | ||
| 116 | + /> | ||
| 117 | + </el-form-item> | ||
| 118 | + </el-form> | ||
| 119 | + | ||
| 120 | + <div slot="footer" class="dialog-footer"> | ||
| 121 | + <el-button @click="visible = false"> | ||
| 122 | + {{ $t('editParkingSpaceApply.cancel') }} | ||
| 123 | + </el-button> | ||
| 124 | + <el-button type="primary" @click="submitForm"> | ||
| 125 | + {{ $t('editParkingSpaceApply.save') }} | ||
| 126 | + </el-button> | ||
| 127 | + </div> | ||
| 128 | + </el-dialog> | ||
| 129 | +</template> | ||
| 130 | + | ||
| 131 | +<script> | ||
| 132 | +import { updateParkingSpaceApply } from '@/api/car/parkingSpaceApplyManageApi' | ||
| 133 | + | ||
| 134 | +export default { | ||
| 135 | + name: 'EditParkingSpaceApply', | ||
| 136 | + data() { | ||
| 137 | + return { | ||
| 138 | + visible: false, | ||
| 139 | + formData: { | ||
| 140 | + applyId: '', | ||
| 141 | + carNum: '', | ||
| 142 | + carBrand: '', | ||
| 143 | + carType: '', | ||
| 144 | + carColor: '', | ||
| 145 | + startTime: '', | ||
| 146 | + endTime: '', | ||
| 147 | + applyPersonName: '', | ||
| 148 | + applyPersonLink: '', | ||
| 149 | + applyPersonId: '', | ||
| 150 | + state: '1001', | ||
| 151 | + remark: '' | ||
| 152 | + }, | ||
| 153 | + rules: { | ||
| 154 | + carNum: [ | ||
| 155 | + { required: true, message: this.$t('editParkingSpaceApply.fillLicensePlate'), trigger: 'blur' } | ||
| 156 | + ], | ||
| 157 | + carBrand: [ | ||
| 158 | + { required: true, message: this.$t('editParkingSpaceApply.fillCarBrand'), trigger: 'blur' } | ||
| 159 | + ], | ||
| 160 | + carType: [ | ||
| 161 | + { required: true, message: this.$t('editParkingSpaceApply.selectVehicleType'), trigger: 'change' } | ||
| 162 | + ], | ||
| 163 | + carColor: [ | ||
| 164 | + { required: true, message: this.$t('editParkingSpaceApply.fillColor'), trigger: 'blur' } | ||
| 165 | + ], | ||
| 166 | + startTime: [ | ||
| 167 | + { required: true, message: this.$t('editParkingSpaceApply.fillStartTime'), trigger: 'change' } | ||
| 168 | + ], | ||
| 169 | + endTime: [ | ||
| 170 | + { required: true, message: this.$t('editParkingSpaceApply.fillEndTime'), trigger: 'change' } | ||
| 171 | + ] | ||
| 172 | + } | ||
| 173 | + } | ||
| 174 | + }, | ||
| 175 | + methods: { | ||
| 176 | + open(data) { | ||
| 177 | + this.formData = { ...data } | ||
| 178 | + this.visible = true | ||
| 179 | + }, | ||
| 180 | + | ||
| 181 | + closeDialog() { | ||
| 182 | + this.$refs.form.resetFields() | ||
| 183 | + }, | ||
| 184 | + | ||
| 185 | + submitForm() { | ||
| 186 | + this.$refs.form.validate(async valid => { | ||
| 187 | + if (valid) { | ||
| 188 | + try { | ||
| 189 | + const response = await updateParkingSpaceApply(this.formData) | ||
| 190 | + if (response.code === 0) { | ||
| 191 | + this.$message.success(this.$t('common.updateSuccess')) | ||
| 192 | + this.visible = false | ||
| 193 | + this.$emit('success') | ||
| 194 | + } else { | ||
| 195 | + this.$message.error(response.msg || this.$t('common.updateFailed')) | ||
| 196 | + } | ||
| 197 | + } catch (error) { | ||
| 198 | + console.error('Error updating parking space application:', error) | ||
| 199 | + this.$message.error(this.$t('common.requestError')) | ||
| 200 | + } | ||
| 201 | + } | ||
| 202 | + }) | ||
| 203 | + } | ||
| 204 | + } | ||
| 205 | +} | ||
| 206 | +</script> | ||
| 0 | \ No newline at end of file | 207 | \ No newline at end of file |
src/components/car/searchOwner.vue
0 → 100644
| 1 | +<template> | ||
| 2 | + <el-dialog | ||
| 3 | + :title="$t('searchOwner.title')" | ||
| 4 | + :visible.sync="visible" | ||
| 5 | + width="80%" | ||
| 6 | + @close="handleClose" | ||
| 7 | + > | ||
| 8 | + <el-card> | ||
| 9 | + <el-row :gutter="20"> | ||
| 10 | + <el-col :span="8"> | ||
| 11 | + <el-input | ||
| 12 | + v-model="searchInfo.roomName" | ||
| 13 | + :placeholder="$t('searchOwner.placeholderRoom')" | ||
| 14 | + clearable | ||
| 15 | + /> | ||
| 16 | + </el-col> | ||
| 17 | + <el-col :span="8"> | ||
| 18 | + <el-input | ||
| 19 | + v-model="searchInfo._currentOwnerName" | ||
| 20 | + :placeholder="$t('searchOwner.placeholderOwner')" | ||
| 21 | + clearable | ||
| 22 | + /> | ||
| 23 | + </el-col> | ||
| 24 | + <el-col :span="8" style="text-align: right"> | ||
| 25 | + <el-button | ||
| 26 | + type="primary" | ||
| 27 | + @click="searchOwners" | ||
| 28 | + > | ||
| 29 | + <i class="el-icon-search"></i> | ||
| 30 | + {{ $t('common.search') }} | ||
| 31 | + </el-button> | ||
| 32 | + <el-button | ||
| 33 | + type="primary" | ||
| 34 | + @click="resetOwners" | ||
| 35 | + > | ||
| 36 | + {{ $t('common.reset') }} | ||
| 37 | + </el-button> | ||
| 38 | + </el-col> | ||
| 39 | + </el-row> | ||
| 40 | + | ||
| 41 | + <el-table | ||
| 42 | + :data="owners" | ||
| 43 | + style="width: 100%; margin-top: 20px" | ||
| 44 | + border | ||
| 45 | + > | ||
| 46 | + <el-table-column | ||
| 47 | + prop="memberId" | ||
| 48 | + :label="$t('searchOwner.memberId')" | ||
| 49 | + align="center" | ||
| 50 | + /> | ||
| 51 | + <el-table-column | ||
| 52 | + prop="name" | ||
| 53 | + :label="$t('searchOwner.name')" | ||
| 54 | + align="center" | ||
| 55 | + /> | ||
| 56 | + <el-table-column | ||
| 57 | + prop="personTypeName" | ||
| 58 | + :label="$t('searchOwner.personType')" | ||
| 59 | + align="center" | ||
| 60 | + /> | ||
| 61 | + <el-table-column | ||
| 62 | + prop="personRoleName" | ||
| 63 | + :label="$t('searchOwner.personRole')" | ||
| 64 | + align="center" | ||
| 65 | + /> | ||
| 66 | + <el-table-column | ||
| 67 | + prop="idCard" | ||
| 68 | + :label="$t('searchOwner.idCard')" | ||
| 69 | + align="center" | ||
| 70 | + /> | ||
| 71 | + <el-table-column | ||
| 72 | + prop="link" | ||
| 73 | + :label="$t('searchOwner.link')" | ||
| 74 | + align="center" | ||
| 75 | + /> | ||
| 76 | + <el-table-column | ||
| 77 | + :label="$t('common.operation')" | ||
| 78 | + align="center" | ||
| 79 | + > | ||
| 80 | + <template slot-scope="scope"> | ||
| 81 | + <el-button | ||
| 82 | + type="primary" | ||
| 83 | + size="small" | ||
| 84 | + @click="chooseOwner(scope.row)" | ||
| 85 | + > | ||
| 86 | + {{ $t('common.select') }} | ||
| 87 | + </el-button> | ||
| 88 | + </template> | ||
| 89 | + </el-table-column> | ||
| 90 | + </el-table> | ||
| 91 | + | ||
| 92 | + <el-pagination | ||
| 93 | + :current-page="page.current" | ||
| 94 | + :page-sizes="[10, 20, 30, 50]" | ||
| 95 | + :page-size="page.size" | ||
| 96 | + :total="page.total" | ||
| 97 | + layout="total, sizes, prev, pager, next, jumper" | ||
| 98 | + style="margin-top: 20px" | ||
| 99 | + @size-change="handleSizeChange" | ||
| 100 | + @current-change="handleCurrentChange" | ||
| 101 | + /> | ||
| 102 | + </el-card> | ||
| 103 | + </el-dialog> | ||
| 104 | +</template> | ||
| 105 | + | ||
| 106 | +<script> | ||
| 107 | +import { queryOwners } from '@/api/car/addParkingSpaceApplyApi' | ||
| 108 | + | ||
| 109 | +export default { | ||
| 110 | + name: 'SearchOwner', | ||
| 111 | + data() { | ||
| 112 | + return { | ||
| 113 | + visible: false, | ||
| 114 | + searchInfo: { | ||
| 115 | + owners: [], | ||
| 116 | + _currentOwnerName: '', | ||
| 117 | + roomName: '', | ||
| 118 | + ownerTypeCd: '1001' | ||
| 119 | + }, | ||
| 120 | + owners: [], | ||
| 121 | + page: { | ||
| 122 | + current: 1, | ||
| 123 | + size: 10, | ||
| 124 | + total: 0 | ||
| 125 | + } | ||
| 126 | + } | ||
| 127 | + }, | ||
| 128 | + methods: { | ||
| 129 | + open() { | ||
| 130 | + this.visible = true | ||
| 131 | + this.resetOwners() | ||
| 132 | + this._loadAllOwnerInfo(1, 10) | ||
| 133 | + }, | ||
| 134 | + handleClose() { | ||
| 135 | + this.visible = false | ||
| 136 | + }, | ||
| 137 | + async _loadAllOwnerInfo(page, size) { | ||
| 138 | + try { | ||
| 139 | + const params = { | ||
| 140 | + page: page, | ||
| 141 | + row: size, | ||
| 142 | + communityId: this.$store.getters.communityId, | ||
| 143 | + name: this.searchInfo._currentOwnerName.trim(), | ||
| 144 | + roomName: this.searchInfo.roomName.trim(), | ||
| 145 | + ownerTypeCd: this.searchInfo.ownerTypeCd | ||
| 146 | + } | ||
| 147 | + | ||
| 148 | + const res = await queryOwners(params) | ||
| 149 | + this.owners = res.data | ||
| 150 | + this.page.total = res.total | ||
| 151 | + this.page.current = page | ||
| 152 | + this.page.size = size | ||
| 153 | + } catch (error) { | ||
| 154 | + console.error('获取业主列表失败:', error) | ||
| 155 | + } | ||
| 156 | + }, | ||
| 157 | + chooseOwner(owner) { | ||
| 158 | + this.$emit('choose-owner', owner) | ||
| 159 | + this.visible = false | ||
| 160 | + }, | ||
| 161 | + searchOwners() { | ||
| 162 | + this._loadAllOwnerInfo(1, this.page.size) | ||
| 163 | + }, | ||
| 164 | + resetOwners() { | ||
| 165 | + this.searchInfo = { | ||
| 166 | + owners: [], | ||
| 167 | + _currentOwnerName: '', | ||
| 168 | + roomName: '', | ||
| 169 | + ownerTypeCd: '1001' | ||
| 170 | + } | ||
| 171 | + this._loadAllOwnerInfo(1, this.page.size) | ||
| 172 | + }, | ||
| 173 | + handleSizeChange(size) { | ||
| 174 | + this._loadAllOwnerInfo(this.page.current, size) | ||
| 175 | + }, | ||
| 176 | + handleCurrentChange(page) { | ||
| 177 | + this._loadAllOwnerInfo(page, this.page.size) | ||
| 178 | + } | ||
| 179 | + } | ||
| 180 | +} | ||
| 181 | +</script> | ||
| 0 | \ No newline at end of file | 182 | \ No newline at end of file |
src/components/car/searchOwnerLang.js
0 → 100644
| 1 | +export default { | ||
| 2 | + en: { | ||
| 3 | + searchOwner: { | ||
| 4 | + title: 'Select Owner', | ||
| 5 | + placeholderRoom: 'Enter room number (building-unit-room)', | ||
| 6 | + placeholderOwner: 'Enter owner name', | ||
| 7 | + memberId: 'Owner ID', | ||
| 8 | + name: 'Name', | ||
| 9 | + personType: 'Person Type', | ||
| 10 | + personRole: 'Person Role', | ||
| 11 | + idCard: 'ID Card', | ||
| 12 | + link: 'Contact' | ||
| 13 | + } | ||
| 14 | + }, | ||
| 15 | + zh: { | ||
| 16 | + searchOwner: { | ||
| 17 | + title: '选择业主', | ||
| 18 | + placeholderRoom: '输入房屋编号楼栋-单元-房屋', | ||
| 19 | + placeholderOwner: '输入业主名称', | ||
| 20 | + memberId: '业主编号', | ||
| 21 | + name: '名称', | ||
| 22 | + personType: '人员类型', | ||
| 23 | + personRole: '人员角色', | ||
| 24 | + idCard: '证件号', | ||
| 25 | + link: '联系方式' | ||
| 26 | + } | ||
| 27 | + } | ||
| 28 | +} | ||
| 0 | \ No newline at end of file | 29 | \ No newline at end of file |
src/i18n/index.js
| @@ -153,6 +153,11 @@ import { messages as carAddParkingSpaceMessages } from '../views/car/carAddParki | @@ -153,6 +153,11 @@ import { messages as carAddParkingSpaceMessages } from '../views/car/carAddParki | ||
| 153 | import { messages as buyCarMonthCardMessages } from '../views/fee/buyCarMonthCardLang' | 153 | import { messages as buyCarMonthCardMessages } from '../views/fee/buyCarMonthCardLang' |
| 154 | import { messages as carInoutManageMessages } from '../views/car/carInoutManageLang' | 154 | import { messages as carInoutManageMessages } from '../views/car/carInoutManageLang' |
| 155 | import { messages as carInManageMessages } from '../views/car/carInManageLang' | 155 | import { messages as carInManageMessages } from '../views/car/carInManageLang' |
| 156 | +import { messages as remainingParkingSpaceMessages } from '../views/car/remainingParkingSpaceLang' | ||
| 157 | +import { messages as tempCarPaymentMessages } from '../views/car/tempCarPaymentLang' | ||
| 158 | +import { messages as parkingSpaceApplyManageMessages } from '../views/car/parkingSpaceApplyManageLang' | ||
| 159 | +import { messages as addParkingSpaceApplyMessages } from '../views/car/addParkingSpaceApplyLang' | ||
| 160 | +import { messages as auditParkingSpaceApplyMessages } from '../views/car/auditParkingSpaceApplyLang' | ||
| 156 | 161 | ||
| 157 | Vue.use(VueI18n) | 162 | Vue.use(VueI18n) |
| 158 | 163 | ||
| @@ -310,6 +315,11 @@ const messages = { | @@ -310,6 +315,11 @@ const messages = { | ||
| 310 | ...buyCarMonthCardMessages.en, | 315 | ...buyCarMonthCardMessages.en, |
| 311 | ...carInoutManageMessages.en, | 316 | ...carInoutManageMessages.en, |
| 312 | ...carInManageMessages.en, | 317 | ...carInManageMessages.en, |
| 318 | + ...remainingParkingSpaceMessages.en, | ||
| 319 | + ...tempCarPaymentMessages.en, | ||
| 320 | + ...parkingSpaceApplyManageMessages.en, | ||
| 321 | + ...addParkingSpaceApplyMessages.en, | ||
| 322 | + ...auditParkingSpaceApplyMessages.en, | ||
| 313 | }, | 323 | }, |
| 314 | zh: { | 324 | zh: { |
| 315 | ...loginMessages.zh, | 325 | ...loginMessages.zh, |
| @@ -463,6 +473,11 @@ const messages = { | @@ -463,6 +473,11 @@ const messages = { | ||
| 463 | ...buyCarMonthCardMessages.zh, | 473 | ...buyCarMonthCardMessages.zh, |
| 464 | ...carInoutManageMessages.zh, | 474 | ...carInoutManageMessages.zh, |
| 465 | ...carInManageMessages.zh, | 475 | ...carInManageMessages.zh, |
| 476 | + ...remainingParkingSpaceMessages.zh, | ||
| 477 | + ...tempCarPaymentMessages.zh, | ||
| 478 | + ...parkingSpaceApplyManageMessages.zh, | ||
| 479 | + ...addParkingSpaceApplyMessages.zh, | ||
| 480 | + ...auditParkingSpaceApplyMessages.zh, | ||
| 466 | } | 481 | } |
| 467 | } | 482 | } |
| 468 | 483 |
src/router/index.js
| @@ -752,15 +752,40 @@ const routes = [ | @@ -752,15 +752,40 @@ const routes = [ | ||
| 752 | component: () => import('@/views/fee/buyCarMonthCardList.vue') | 752 | component: () => import('@/views/fee/buyCarMonthCardList.vue') |
| 753 | }, | 753 | }, |
| 754 | { | 754 | { |
| 755 | - path:'/pages/property/carInoutManage', | ||
| 756 | - name:'/pages/property/carInoutManage', | 755 | + path: '/pages/property/carInoutManage', |
| 756 | + name: '/pages/property/carInoutManage', | ||
| 757 | component: () => import('@/views/car/carInoutManageList.vue') | 757 | component: () => import('@/views/car/carInoutManageList.vue') |
| 758 | + }, | ||
| 759 | + { | ||
| 760 | + path: '/pages/property/carInManage', | ||
| 761 | + name: '/pages/property/carInManage', | ||
| 762 | + component: () => import('@/views/car/carInManageList.vue') | ||
| 763 | + }, | ||
| 764 | + { | ||
| 765 | + path: '/pages/property/remainingParkingSpace', | ||
| 766 | + name: '/pages/property/remainingParkingSpace', | ||
| 767 | + component: () => import('@/views/car/remainingParkingSpaceList.vue') | ||
| 768 | + }, | ||
| 769 | + { | ||
| 770 | + path:'/pages/car/tempCarPayment', | ||
| 771 | + name:'/pages/car/tempCarPayment', | ||
| 772 | + component: () => import('@/views/car/tempCarPaymentList.vue') | ||
| 758 | }, | 773 | }, |
| 759 | { | 774 | { |
| 760 | - path:'/pages/property/carInManage', | ||
| 761 | - name:'/pages/property/carInManage', | ||
| 762 | - component: () => import('@/views/car/carInManageList.vue') | 775 | + path:'/pages/property/parkingSpaceApplyManage', |
| 776 | + name:'/pages/property/parkingSpaceApplyManage', | ||
| 777 | + component: () => import('@/views/car/parkingSpaceApplyManageList.vue') | ||
| 763 | }, | 778 | }, |
| 779 | + { | ||
| 780 | + path:'/views/car/addParkingSpaceApply', | ||
| 781 | + name:'/views/car/addParkingSpaceApply', | ||
| 782 | + component: () => import('@/views/car/addParkingSpaceApply.vue') | ||
| 783 | + }, | ||
| 784 | + { | ||
| 785 | + path:'/views/car/auditParkingSpaceApply', | ||
| 786 | + name:'/views/car/auditParkingSpaceApply', | ||
| 787 | + component: () => import('@/views/car/auditParkingSpaceApply.vue') | ||
| 788 | + }, | ||
| 764 | // 其他子路由可以在这里添加 | 789 | // 其他子路由可以在这里添加 |
| 765 | ] | 790 | ] |
| 766 | }, | 791 | }, |
src/views/car/addParkingSpaceApply.vue
0 → 100644
| 1 | +<template> | ||
| 2 | + <el-card class="box-card"> | ||
| 3 | + <div slot="header" class=" flex justify-between"> | ||
| 4 | + <div>{{ $t('addParkingSpaceApply.title') }}</div> | ||
| 5 | + <div> | ||
| 6 | + <el-button type="primary" size="small" icon="el-icon-close" @click="_goBack"> | ||
| 7 | + {{ $t('common.back') }} | ||
| 8 | + </el-button> | ||
| 9 | + </div> | ||
| 10 | + </div> | ||
| 11 | + | ||
| 12 | + <el-form ref="form" :model="addParkingSpaceApplyInfo" label-width="120px"> | ||
| 13 | + <el-row :gutter="20"> | ||
| 14 | + <el-col :span="12"> | ||
| 15 | + <el-form-item :label="$t('addParkingSpaceApply.carNum')" prop="carNum" :rules="[ | ||
| 16 | + { required: true, message: $t('addParkingSpaceApply.requiredCarNum') }, | ||
| 17 | + { pattern: /^[\u4e00-\u9fa5A-Za-z0-9]{6,12}$/, message: $t('addParkingSpaceApply.invalidCarNum') } | ||
| 18 | + ]"> | ||
| 19 | + <el-input v-model="addParkingSpaceApplyInfo.carNum" | ||
| 20 | + :placeholder="$t('addParkingSpaceApply.placeholderCarNum')" /> | ||
| 21 | + </el-form-item> | ||
| 22 | + </el-col> | ||
| 23 | + <el-col :span="12"> | ||
| 24 | + <el-form-item :label="$t('addParkingSpaceApply.carBrand')" prop="carBrand" :rules="[ | ||
| 25 | + { required: true, message: $t('addParkingSpaceApply.requiredCarBrand') }, | ||
| 26 | + { max: 50, message: $t('addParkingSpaceApply.maxCarBrand') } | ||
| 27 | + ]"> | ||
| 28 | + <el-input v-model="addParkingSpaceApplyInfo.carBrand" | ||
| 29 | + :placeholder="$t('addParkingSpaceApply.placeholderCarBrand')" /> | ||
| 30 | + </el-form-item> | ||
| 31 | + </el-col> | ||
| 32 | + </el-row> | ||
| 33 | + | ||
| 34 | + <el-row :gutter="20"> | ||
| 35 | + <el-col :span="12"> | ||
| 36 | + <el-form-item :label="$t('addParkingSpaceApply.carType')" prop="carType" | ||
| 37 | + :rules="[{ required: true, message: $t('addParkingSpaceApply.requiredCarType') }]"> | ||
| 38 | + <el-select v-model="addParkingSpaceApplyInfo.carType" style="width: 100%" | ||
| 39 | + :placeholder="$t('addParkingSpaceApply.placeholderCarType')"> | ||
| 40 | + <el-option v-for="item in carTypes" :key="item.statusCd" :label="item.name" :value="item.statusCd" /> | ||
| 41 | + </el-select> | ||
| 42 | + </el-form-item> | ||
| 43 | + </el-col> | ||
| 44 | + <el-col :span="12"> | ||
| 45 | + <el-form-item :label="$t('addParkingSpaceApply.carColor')" prop="carColor" :rules="[ | ||
| 46 | + { required: true, message: $t('addParkingSpaceApply.requiredCarColor') }, | ||
| 47 | + { max: 12, message: $t('addParkingSpaceApply.maxCarColor') } | ||
| 48 | + ]"> | ||
| 49 | + <el-input v-model="addParkingSpaceApplyInfo.carColor" | ||
| 50 | + :placeholder="$t('addParkingSpaceApply.placeholderCarColor')" /> | ||
| 51 | + </el-form-item> | ||
| 52 | + </el-col> | ||
| 53 | + </el-row> | ||
| 54 | + | ||
| 55 | + <el-row :gutter="20"> | ||
| 56 | + <el-col :span="8"> | ||
| 57 | + <el-form-item :label="$t('addParkingSpaceApply.applyPersonName')" prop="applyPersonName" :rules="[ | ||
| 58 | + { required: true, message: $t('addParkingSpaceApply.requiredApplyPersonName') }, | ||
| 59 | + { max: 64, message: $t('addParkingSpaceApply.maxApplyPersonName') } | ||
| 60 | + ]"> | ||
| 61 | + <el-input v-model="addParkingSpaceApplyInfo.applyPersonName" | ||
| 62 | + :placeholder="$t('addParkingSpaceApply.placeholderApplyPersonName')" | ||
| 63 | + style="width: calc(100% - 70px); margin-right: 10px" /> | ||
| 64 | + | ||
| 65 | + </el-form-item> | ||
| 66 | + </el-col> | ||
| 67 | + <el-col :span="4"> | ||
| 68 | + <el-button type="primary" size="small" @click="_openChooseOwner"> | ||
| 69 | + {{ $t('addParkingSpaceApply.selectOwner') }} | ||
| 70 | + </el-button> | ||
| 71 | + </el-col> | ||
| 72 | + <el-col :span="12"> | ||
| 73 | + <el-form-item :label="$t('addParkingSpaceApply.applyPersonLink')" prop="applyPersonLink" :rules="[ | ||
| 74 | + { required: true, message: $t('addParkingSpaceApply.requiredApplyPersonLink') }, | ||
| 75 | + { max: 11, message: $t('addParkingSpaceApply.maxApplyPersonLink') } | ||
| 76 | + ]"> | ||
| 77 | + <el-input v-model="addParkingSpaceApplyInfo.applyPersonLink" | ||
| 78 | + :placeholder="$t('addParkingSpaceApply.placeholderApplyPersonLink')" /> | ||
| 79 | + </el-form-item> | ||
| 80 | + </el-col> | ||
| 81 | + </el-row> | ||
| 82 | + | ||
| 83 | + <el-row> | ||
| 84 | + <el-col :span="24"> | ||
| 85 | + <el-form-item :label="$t('addParkingSpaceApply.remark')" prop="remark" | ||
| 86 | + :rules="[{ max: 300, message: $t('addParkingSpaceApply.maxRemark') }]"> | ||
| 87 | + <el-input v-model="addParkingSpaceApplyInfo.remark" type="textarea" | ||
| 88 | + :placeholder="$t('addParkingSpaceApply.placeholderRemark')" /> | ||
| 89 | + </el-form-item> | ||
| 90 | + </el-col> | ||
| 91 | + </el-row> | ||
| 92 | + | ||
| 93 | + <el-row> | ||
| 94 | + <el-col :span="24" style="text-align: right"> | ||
| 95 | + <el-button type="warning" style="margin-right: 20px" @click="_goBack"> | ||
| 96 | + {{ $t('common.back') }} | ||
| 97 | + </el-button> | ||
| 98 | + <el-button type="primary" @click="saveParkingSpaceApplyInfo"> | ||
| 99 | + <i class="el-icon-check"></i> | ||
| 100 | + {{ $t('common.submit') }} | ||
| 101 | + </el-button> | ||
| 102 | + </el-col> | ||
| 103 | + </el-row> | ||
| 104 | + </el-form> | ||
| 105 | + | ||
| 106 | + <search-owner ref="searchOwner" @chooseOwner="handleChooseOwner" /> | ||
| 107 | + </el-card> | ||
| 108 | +</template> | ||
| 109 | + | ||
| 110 | +<script> | ||
| 111 | +import { saveParkingSpaceApply } from '@/api/car/addParkingSpaceApplyApi' | ||
| 112 | +import { getDict } from '@/api/community/communityApi' | ||
| 113 | +import SearchOwner from '@/components/owner/SearchOwner' | ||
| 114 | + | ||
| 115 | +export default { | ||
| 116 | + name: 'AddParkingSpaceApply', | ||
| 117 | + components: { | ||
| 118 | + SearchOwner | ||
| 119 | + }, | ||
| 120 | + data() { | ||
| 121 | + return { | ||
| 122 | + addParkingSpaceApplyInfo: { | ||
| 123 | + paName: '', | ||
| 124 | + paId: '', | ||
| 125 | + psId: '', | ||
| 126 | + psName: '', | ||
| 127 | + applyId: '', | ||
| 128 | + carNum: '', | ||
| 129 | + carBrand: '', | ||
| 130 | + carType: '', | ||
| 131 | + carColor: '', | ||
| 132 | + applyPersonName: '', | ||
| 133 | + applyPersonLink: '', | ||
| 134 | + applyPersonId: '', | ||
| 135 | + state: '1001', | ||
| 136 | + remark: '' | ||
| 137 | + }, | ||
| 138 | + carTypes: [] | ||
| 139 | + } | ||
| 140 | + }, | ||
| 141 | + async created() { | ||
| 142 | + await this.getCarTypeDict() | ||
| 143 | + }, | ||
| 144 | + methods: { | ||
| 145 | + async getCarTypeDict() { | ||
| 146 | + try { | ||
| 147 | + const data = await getDict('owner_car', 'car_type') | ||
| 148 | + this.carTypes = data | ||
| 149 | + } catch (error) { | ||
| 150 | + console.error('获取车辆类型字典失败:', error) | ||
| 151 | + } | ||
| 152 | + }, | ||
| 153 | + handleChooseOwner(owner) { | ||
| 154 | + this.addParkingSpaceApplyInfo.applyPersonName = owner.name | ||
| 155 | + this.addParkingSpaceApplyInfo.applyPersonLink = owner.link | ||
| 156 | + this.addParkingSpaceApplyInfo.applyPersonId = owner.ownerId | ||
| 157 | + }, | ||
| 158 | + _openChooseOwner() { | ||
| 159 | + this.$refs.searchOwner.open() | ||
| 160 | + }, | ||
| 161 | + async saveParkingSpaceApplyInfo() { | ||
| 162 | + try { | ||
| 163 | + await this.$refs.form.validate() | ||
| 164 | + | ||
| 165 | + const data = { | ||
| 166 | + ...this.addParkingSpaceApplyInfo, | ||
| 167 | + communityId: this.getCommunityId() | ||
| 168 | + } | ||
| 169 | + | ||
| 170 | + await saveParkingSpaceApply(data) | ||
| 171 | + this.$message.success(this.$t('common.submitSuccess')) | ||
| 172 | + this.clearAddParkingSpaceApplyInfo() | ||
| 173 | + this._goBack() | ||
| 174 | + } catch (error) { | ||
| 175 | + if (error.errors) { | ||
| 176 | + this.$message.error(Object.values(error.errors).join('; ')) | ||
| 177 | + } else { | ||
| 178 | + console.error('保存失败:', error) | ||
| 179 | + } | ||
| 180 | + } | ||
| 181 | + }, | ||
| 182 | + clearAddParkingSpaceApplyInfo() { | ||
| 183 | + this.addParkingSpaceApplyInfo = { | ||
| 184 | + paName: '', | ||
| 185 | + paId: '', | ||
| 186 | + psId: '', | ||
| 187 | + psName: '', | ||
| 188 | + applyId: '', | ||
| 189 | + carNum: '', | ||
| 190 | + carBrand: '', | ||
| 191 | + carType: '', | ||
| 192 | + carColor: '', | ||
| 193 | + applyPersonName: '', | ||
| 194 | + applyPersonLink: '', | ||
| 195 | + applyPersonId: '', | ||
| 196 | + state: '1001', | ||
| 197 | + remark: '' | ||
| 198 | + } | ||
| 199 | + }, | ||
| 200 | + _goBack() { | ||
| 201 | + this.$router.go(-1) | ||
| 202 | + } | ||
| 203 | + } | ||
| 204 | +} | ||
| 205 | +</script> | ||
| 206 | + | ||
| 207 | +<style scoped> | ||
| 208 | +.box-card { | ||
| 209 | + margin: 20px; | ||
| 210 | +} | ||
| 211 | + | ||
| 212 | +.el-form-item { | ||
| 213 | + margin-bottom: 22px; | ||
| 214 | +} | ||
| 215 | +</style> | ||
| 0 | \ No newline at end of file | 216 | \ No newline at end of file |
src/views/car/addParkingSpaceApplyLang.js
0 → 100644
| 1 | +export const messages = { | ||
| 2 | + en: { | ||
| 3 | + addParkingSpaceApply: { | ||
| 4 | + title: 'Parking Space Application', | ||
| 5 | + carNum: 'License Plate', | ||
| 6 | + carBrand: 'Car Brand', | ||
| 7 | + carType: 'Vehicle Type', | ||
| 8 | + carColor: 'Color', | ||
| 9 | + applyPersonName: 'Applicant', | ||
| 10 | + applyPersonLink: 'Applicant Phone', | ||
| 11 | + remark: 'Remarks', | ||
| 12 | + requiredCarNum: 'License plate is required', | ||
| 13 | + invalidCarNum: 'Invalid license plate format', | ||
| 14 | + requiredCarBrand: 'Car brand is required', | ||
| 15 | + maxCarBrand: 'Car brand max 50 characters', | ||
| 16 | + requiredCarType: 'Vehicle type is required', | ||
| 17 | + requiredCarColor: 'Color is required', | ||
| 18 | + maxCarColor: 'Color max 12 characters', | ||
| 19 | + requiredApplyPersonName: 'Applicant name is required', | ||
| 20 | + maxApplyPersonName: 'Applicant name max 64 characters', | ||
| 21 | + requiredApplyPersonLink: 'Applicant phone is required', | ||
| 22 | + maxApplyPersonLink: 'Applicant phone max 11 characters', | ||
| 23 | + maxRemark: 'Remarks max 300 characters', | ||
| 24 | + placeholderCarNum: 'Required, please enter license plate', | ||
| 25 | + placeholderCarBrand: 'Required, please enter car brand', | ||
| 26 | + placeholderCarType: 'Required, please select vehicle type', | ||
| 27 | + placeholderCarColor: 'Required, please enter color', | ||
| 28 | + placeholderApplyPersonName: 'Required, please enter applicant', | ||
| 29 | + placeholderApplyPersonLink: 'Required, please enter applicant phone', | ||
| 30 | + placeholderRemark: 'Optional, please enter remarks', | ||
| 31 | + selectOwner: 'Select Owner', | ||
| 32 | + } | ||
| 33 | + }, | ||
| 34 | + zh: { | ||
| 35 | + addParkingSpaceApply: { | ||
| 36 | + title: '车位申请', | ||
| 37 | + carNum: '车牌号', | ||
| 38 | + carBrand: '汽车品牌', | ||
| 39 | + carType: '车辆类型', | ||
| 40 | + carColor: '颜色', | ||
| 41 | + applyPersonName: '申请人', | ||
| 42 | + applyPersonLink: '申请人电话', | ||
| 43 | + remark: '备注', | ||
| 44 | + requiredCarNum: '车牌号不能为空', | ||
| 45 | + invalidCarNum: '车牌号格式错误', | ||
| 46 | + requiredCarBrand: '汽车品牌不能为空', | ||
| 47 | + maxCarBrand: '汽车品牌不能超过50位', | ||
| 48 | + requiredCarType: '车辆类型不能为空', | ||
| 49 | + requiredCarColor: '颜色不能为空', | ||
| 50 | + maxCarColor: '颜色不能超过12位', | ||
| 51 | + requiredApplyPersonName: '申请人不能为空', | ||
| 52 | + maxApplyPersonName: '申请人名称不能超过64位', | ||
| 53 | + requiredApplyPersonLink: '申请人电话不能为空', | ||
| 54 | + maxApplyPersonLink: '申请人电话不能超过11位', | ||
| 55 | + maxRemark: '备注不能超过300位', | ||
| 56 | + placeholderCarNum: '必填,请填写车牌号', | ||
| 57 | + placeholderCarBrand: '必填,请填写汽车品牌', | ||
| 58 | + placeholderCarType: '必填,请选择车辆类型', | ||
| 59 | + placeholderCarColor: '必填,请填写颜色', | ||
| 60 | + placeholderApplyPersonName: '必填,请填写申请人', | ||
| 61 | + placeholderApplyPersonLink: '必填,请填写申请人电话', | ||
| 62 | + placeholderRemark: '选填,请填写备注', | ||
| 63 | + selectOwner: '选择车主', | ||
| 64 | + } | ||
| 65 | + } | ||
| 66 | +} | ||
| 0 | \ No newline at end of file | 67 | \ No newline at end of file |
src/views/car/auditParkingSpaceApply.vue
0 → 100644
| 1 | +<template> | ||
| 2 | + <div class="audit-container"> | ||
| 3 | + <el-card class="box-card"> | ||
| 4 | + <div slot="header" class=" flex justify-between"> | ||
| 5 | + <span>{{ $t('auditParkingSpaceApply.applyInfo') }}</span> | ||
| 6 | + <el-button style="float: right; padding: 3px 0" type="text" @click="goBack"> | ||
| 7 | + {{ $t('auditParkingSpaceApply.back') }} | ||
| 8 | + </el-button> | ||
| 9 | + </div> | ||
| 10 | + <el-form ref="viewForm" :model="formData" label-width="120px" class="text-left"> | ||
| 11 | + <el-row :gutter="20"> | ||
| 12 | + <el-col :span="6"> | ||
| 13 | + <el-form-item :label="$t('auditParkingSpaceApply.licensePlate') + ':'"> | ||
| 14 | + <span>{{ formData.carNum }}</span> | ||
| 15 | + </el-form-item> | ||
| 16 | + </el-col> | ||
| 17 | + <el-col :span="6"> | ||
| 18 | + <el-form-item :label="$t('auditParkingSpaceApply.carBrand') + ':'"> | ||
| 19 | + <span>{{ formData.carBrand }}</span> | ||
| 20 | + </el-form-item> | ||
| 21 | + </el-col> | ||
| 22 | + <el-col :span="6"> | ||
| 23 | + <el-form-item :label="$t('auditParkingSpaceApply.carType') + ':'"> | ||
| 24 | + <span>{{ formData.carType }}</span> | ||
| 25 | + </el-form-item> | ||
| 26 | + </el-col> | ||
| 27 | + <el-col :span="6"> | ||
| 28 | + <el-form-item :label="$t('auditParkingSpaceApply.color') + ':'"> | ||
| 29 | + <span>{{ formData.carColor }}</span> | ||
| 30 | + </el-form-item> | ||
| 31 | + </el-col> | ||
| 32 | + <el-col :span="6"> | ||
| 33 | + <el-form-item :label="$t('auditParkingSpaceApply.startRentTime') + ':'"> | ||
| 34 | + <span>{{ formData.startTime }}</span> | ||
| 35 | + </el-form-item> | ||
| 36 | + </el-col> | ||
| 37 | + <el-col :span="6"> | ||
| 38 | + <el-form-item :label="$t('auditParkingSpaceApply.endRentTime') + ':'"> | ||
| 39 | + <span>{{ formData.endTime }}</span> | ||
| 40 | + </el-form-item> | ||
| 41 | + </el-col> | ||
| 42 | + | ||
| 43 | + <el-col :span="6"> | ||
| 44 | + <el-form-item :label="$t('auditParkingSpaceApply.applicant') + ':'"> | ||
| 45 | + <span>{{ formData.applyPersonName }}</span> | ||
| 46 | + </el-form-item> | ||
| 47 | + </el-col> | ||
| 48 | + <el-col :span="6"> | ||
| 49 | + <el-form-item :label="$t('auditParkingSpaceApply.applicantPhone') + ':'"> | ||
| 50 | + <span>{{ formData.applyPersonLink }}</span> | ||
| 51 | + </el-form-item> | ||
| 52 | + </el-col> | ||
| 53 | + <el-col :span="6"> | ||
| 54 | + <el-form-item :label="$t('auditParkingSpaceApply.applicantId') + ':'"> | ||
| 55 | + <span>{{ formData.applyPersonId }}</span> | ||
| 56 | + </el-form-item> | ||
| 57 | + </el-col> | ||
| 58 | + <el-col :span="16"> | ||
| 59 | + <el-form-item :label="$t('auditParkingSpaceApply.remark') + ':'"> | ||
| 60 | + <span>{{ formData.remark }}</span> | ||
| 61 | + </el-form-item> | ||
| 62 | + </el-col> | ||
| 63 | + </el-row> | ||
| 64 | + </el-form> | ||
| 65 | + </el-card> | ||
| 66 | + | ||
| 67 | + <el-card class="box-card" style="margin-top: 20px;"> | ||
| 68 | + <div slot="header" class="clearfix"> | ||
| 69 | + <span>{{ $t('auditParkingSpaceApply.auditInfo') }}</span> | ||
| 70 | + </div> | ||
| 71 | + | ||
| 72 | + <el-form ref="form" :model="formData" label-width="120px"> | ||
| 73 | + <el-form-item :label="$t('auditParkingSpaceApply.startRentTime')" required> | ||
| 74 | + <el-date-picker v-model="formData.startTime" type="datetime" | ||
| 75 | + :placeholder="$t('auditParkingSpaceApply.requiredField')" value-format="yyyy-MM-dd HH:mm:ss" | ||
| 76 | + style="width: 100%;" /> | ||
| 77 | + </el-form-item> | ||
| 78 | + | ||
| 79 | + <el-form-item :label="$t('auditParkingSpaceApply.endRentTime')" required> | ||
| 80 | + <el-date-picker v-model="formData.endTime" type="datetime" | ||
| 81 | + :placeholder="$t('auditParkingSpaceApply.requiredField')" value-format="yyyy-MM-dd HH:mm:ss" | ||
| 82 | + style="width: 100%;" /> | ||
| 83 | + </el-form-item> | ||
| 84 | + | ||
| 85 | + <el-form-item :label="$t('auditParkingSpaceApply.auditResult')" required> | ||
| 86 | + <el-select v-model="formData.state" :placeholder="$t('auditParkingSpaceApply.selectResult')" style="width:100%"> | ||
| 87 | + <el-option :label="$t('auditParkingSpaceApply.pass')" value="3003" /> | ||
| 88 | + <el-option :label="$t('auditParkingSpaceApply.reject')" value="4004" /> | ||
| 89 | + </el-select> | ||
| 90 | + </el-form-item> | ||
| 91 | + | ||
| 92 | + <el-form-item v-if="formData.state === '3003'" :label="$t('auditParkingSpaceApply.selectParkingSpace')"> | ||
| 93 | + <el-input v-model="formData.psName" :placeholder="$t('auditParkingSpaceApply.selectParkingSpace')" readonly | ||
| 94 | + style="width: 80%;" /> | ||
| 95 | + <el-button type="primary" @click="openChooseParkingSpace" style="margin-left: 10px;"> | ||
| 96 | + <i class="el-icon-search"></i> | ||
| 97 | + {{ $t('auditParkingSpaceApply.select') }} | ||
| 98 | + </el-button> | ||
| 99 | + </el-form-item> | ||
| 100 | + | ||
| 101 | + <el-form-item :label="$t('auditParkingSpaceApply.auditOpinion')"> | ||
| 102 | + <el-input v-model="formData.remark2" type="textarea" :placeholder="$t('auditParkingSpaceApply.optional')" | ||
| 103 | + :rows="3" /> | ||
| 104 | + </el-form-item> | ||
| 105 | + | ||
| 106 | + <el-form-item> | ||
| 107 | + <el-button @click="goBack"> | ||
| 108 | + {{ $t('auditParkingSpaceApply.back') }} | ||
| 109 | + </el-button> | ||
| 110 | + <el-button type="primary" @click="doAudit"> | ||
| 111 | + {{ $t('auditParkingSpaceApply.submit') }} | ||
| 112 | + </el-button> | ||
| 113 | + </el-form-item> | ||
| 114 | + </el-form> | ||
| 115 | + </el-card> | ||
| 116 | + | ||
| 117 | + | ||
| 118 | + <!-- 搜索车位组件 --> | ||
| 119 | + <search-parking-space | ||
| 120 | + ref="searchParkingSpace" | ||
| 121 | + :ps-flag="formData.parkingSpaceFlag" | ||
| 122 | + @choose-parking-space="handleChooseParkingSpace" | ||
| 123 | + /> | ||
| 124 | + </div> | ||
| 125 | +</template> | ||
| 126 | + | ||
| 127 | +<script> | ||
| 128 | +import { getParkingSpaceApplyDetail, auditParkingSpaceApply } from '@/api/car/auditParkingSpaceApplyApi' | ||
| 129 | +import SearchParkingSpace from '@/components/car/SearchParkingSpace' | ||
| 130 | + | ||
| 131 | +import { getCommunityId } from '@/api/community/communityApi' | ||
| 132 | + | ||
| 133 | +export default { | ||
| 134 | + name: 'AuditParkingSpaceApply', | ||
| 135 | + components: { | ||
| 136 | + SearchParkingSpace | ||
| 137 | + }, | ||
| 138 | + data() { | ||
| 139 | + return { | ||
| 140 | + formData: { | ||
| 141 | + applyId: '', | ||
| 142 | + communityId: getCommunityId(), | ||
| 143 | + psId: '', | ||
| 144 | + psName: '', | ||
| 145 | + carNum: '', | ||
| 146 | + carBrand: '', | ||
| 147 | + carType: '', | ||
| 148 | + carColor: '', | ||
| 149 | + startTime: '', | ||
| 150 | + endTime: '', | ||
| 151 | + applyPersonName: '', | ||
| 152 | + applyPersonLink: '', | ||
| 153 | + applyPersonId: '', | ||
| 154 | + state: '', | ||
| 155 | + remark: '', | ||
| 156 | + remark2: '', | ||
| 157 | + parkingSpaceFlag: 'F' | ||
| 158 | + } | ||
| 159 | + } | ||
| 160 | + }, | ||
| 161 | + created() { | ||
| 162 | + this.formData.applyId = this.$route.query.applyId | ||
| 163 | + this.getApplyDetail() | ||
| 164 | + }, | ||
| 165 | + methods: { | ||
| 166 | + async getApplyDetail() { | ||
| 167 | + try { | ||
| 168 | + const params = { | ||
| 169 | + page: 1, | ||
| 170 | + row: 1, | ||
| 171 | + applyId: this.formData.applyId | ||
| 172 | + } | ||
| 173 | + | ||
| 174 | + const res = await getParkingSpaceApplyDetail(params) | ||
| 175 | + if (res.data && res.data.length > 0) { | ||
| 176 | + Object.assign(this.formData, res.data[0]) | ||
| 177 | + } | ||
| 178 | + } catch (error) { | ||
| 179 | + this.$message.error(this.$t('common.queryFailed')) | ||
| 180 | + } | ||
| 181 | + }, | ||
| 182 | + openChooseParkingSpace() { | ||
| 183 | + this.$refs.searchParkingSpace.open() | ||
| 184 | + }, | ||
| 185 | + handleChooseParkingSpace(parkingSpace) { | ||
| 186 | + console.log('选择车位', parkingSpace) | ||
| 187 | + this.formData.psId = parkingSpace.psId | ||
| 188 | + this.formData.psName = parkingSpace.num | ||
| 189 | + }, | ||
| 190 | + async doAudit() { | ||
| 191 | + // 验证逻辑 | ||
| 192 | + if (!this.formData.state) { | ||
| 193 | + this.$message.warning(this.$t('auditParkingSpaceApply.selectResult')) | ||
| 194 | + return | ||
| 195 | + } | ||
| 196 | + | ||
| 197 | + if (this.formData.state === '3003' && !this.formData.psId) { | ||
| 198 | + this.$message.warning(this.$t('auditParkingSpaceApply.selectParkingSpace')) | ||
| 199 | + return | ||
| 200 | + } | ||
| 201 | + | ||
| 202 | + if (this.formData.state === '4004' && !this.formData.remark2) { | ||
| 203 | + this.$message.warning(this.$t('auditParkingSpaceApply.auditOpinionRequired')) | ||
| 204 | + return | ||
| 205 | + } | ||
| 206 | + | ||
| 207 | + try { | ||
| 208 | + // 合并备注信息 | ||
| 209 | + const remark = `${this.formData.remark}\n审核意见:${this.formData.remark2}` | ||
| 210 | + | ||
| 211 | + const data = { | ||
| 212 | + ...this.formData, | ||
| 213 | + remark | ||
| 214 | + } | ||
| 215 | + | ||
| 216 | + await auditParkingSpaceApply(data) | ||
| 217 | + this.$message.success(this.$t('common.submitSuccess')) | ||
| 218 | + this.goBack() | ||
| 219 | + } catch (error) { | ||
| 220 | + this.$message.error(this.$t('common.submitFailed')) | ||
| 221 | + } | ||
| 222 | + }, | ||
| 223 | + goBack() { | ||
| 224 | + this.$router.go(-1) | ||
| 225 | + } | ||
| 226 | + } | ||
| 227 | +} | ||
| 228 | +</script> | ||
| 229 | + | ||
| 230 | +<style scoped> | ||
| 231 | +.audit-container { | ||
| 232 | + padding: 20px; | ||
| 233 | +} | ||
| 234 | + | ||
| 235 | +.box-card { | ||
| 236 | + margin-bottom: 20px; | ||
| 237 | +} | ||
| 238 | + | ||
| 239 | +.clearfix:before, | ||
| 240 | +.clearfix:after { | ||
| 241 | + display: table; | ||
| 242 | + content: ""; | ||
| 243 | +} | ||
| 244 | + | ||
| 245 | +.clearfix:after { | ||
| 246 | + clear: both; | ||
| 247 | +} | ||
| 248 | +</style> | ||
| 0 | \ No newline at end of file | 249 | \ No newline at end of file |
src/views/car/auditParkingSpaceApplyLang.js
0 → 100644
| 1 | +export const messages = { | ||
| 2 | + en: { | ||
| 3 | + auditParkingSpaceApply: { | ||
| 4 | + applyInfo: 'Application Information', | ||
| 5 | + back: 'Back', | ||
| 6 | + licensePlate: 'License Plate', | ||
| 7 | + carBrand: 'Car Brand', | ||
| 8 | + carType: 'Car Type', | ||
| 9 | + color: 'Color', | ||
| 10 | + startRentTime: 'Start Rent Time', | ||
| 11 | + endRentTime: 'End Rent Time', | ||
| 12 | + applicant: 'Applicant', | ||
| 13 | + applicantPhone: 'Applicant Phone', | ||
| 14 | + applicantId: 'Applicant ID', | ||
| 15 | + remark: 'Remark', | ||
| 16 | + auditInfo: 'Audit Information', | ||
| 17 | + auditResult: 'Audit Result', | ||
| 18 | + selectResult: 'Please select audit result', | ||
| 19 | + pass: 'Pass', | ||
| 20 | + reject: 'Reject', | ||
| 21 | + selectParkingSpace: 'Select Parking Space', | ||
| 22 | + select: 'Select', | ||
| 23 | + auditOpinion: 'Audit Opinion', | ||
| 24 | + optional: 'Optional', | ||
| 25 | + submit: 'Submit', | ||
| 26 | + requiredField: 'Required field', | ||
| 27 | + parkingLot: 'Parking Lot', | ||
| 28 | + parkingSpace: 'Parking Space', | ||
| 29 | + parkingStatus: 'Parking Status', | ||
| 30 | + parkingType: 'Parking Type', | ||
| 31 | + area: 'Area', | ||
| 32 | + operation: 'Operation', | ||
| 33 | + choose: 'Choose', | ||
| 34 | + parkingLotCode: 'Parking Lot Code', | ||
| 35 | + parkingSpaceCode: 'Parking Space Code', | ||
| 36 | + parkingLotType: 'Parking Lot Type', | ||
| 37 | + groundParking: 'Ground Parking', | ||
| 38 | + undergroundParking: 'Underground Parking', | ||
| 39 | + free: 'Free', | ||
| 40 | + sold: 'Sold', | ||
| 41 | + rented: 'Rented', | ||
| 42 | + unknown: 'Unknown' | ||
| 43 | + } | ||
| 44 | + }, | ||
| 45 | + zh: { | ||
| 46 | + auditParkingSpaceApply: { | ||
| 47 | + applyInfo: '申请信息', | ||
| 48 | + back: '返回', | ||
| 49 | + licensePlate: '车牌号', | ||
| 50 | + carBrand: '汽车品牌', | ||
| 51 | + carType: '车辆类型', | ||
| 52 | + color: '颜色', | ||
| 53 | + startRentTime: '起租时间', | ||
| 54 | + endRentTime: '结租时间', | ||
| 55 | + applicant: '申请人', | ||
| 56 | + applicantPhone: '申请人电话', | ||
| 57 | + applicantId: '申请人ID', | ||
| 58 | + remark: '备注', | ||
| 59 | + auditInfo: '审核信息', | ||
| 60 | + auditResult: '审核结果', | ||
| 61 | + selectResult: '请选择审核结果', | ||
| 62 | + pass: '通过', | ||
| 63 | + reject: '不通过', | ||
| 64 | + selectParkingSpace: '选择车位', | ||
| 65 | + select: '选择', | ||
| 66 | + auditOpinion: '审核意见', | ||
| 67 | + optional: '选填', | ||
| 68 | + submit: '提交', | ||
| 69 | + requiredField: '必填', | ||
| 70 | + parkingLot: '停车场', | ||
| 71 | + parkingSpace: '车位', | ||
| 72 | + parkingStatus: '车位状态', | ||
| 73 | + parkingType: '车位类型', | ||
| 74 | + area: '面积', | ||
| 75 | + operation: '操作', | ||
| 76 | + choose: '选择', | ||
| 77 | + parkingLotCode: '停车场编码', | ||
| 78 | + parkingSpaceCode: '停车位编码', | ||
| 79 | + parkingLotType: '停车场类型', | ||
| 80 | + groundParking: '地上停车位', | ||
| 81 | + undergroundParking: '地下停车位', | ||
| 82 | + free: '空闲', | ||
| 83 | + sold: '已售卖', | ||
| 84 | + rented: '已出租', | ||
| 85 | + unknown: '未知' | ||
| 86 | + } | ||
| 87 | + } | ||
| 88 | +} | ||
| 0 | \ No newline at end of file | 89 | \ No newline at end of file |
src/views/car/parkingSpaceApplyManageLang.js
0 → 100644
| 1 | +export const messages = { | ||
| 2 | + en: { | ||
| 3 | + parkingSpaceApplyManage: { | ||
| 4 | + searchCondition: 'Search Condition', | ||
| 5 | + licensePlate: 'License Plate', | ||
| 6 | + carBrand: 'Car Brand', | ||
| 7 | + applicantName: 'Applicant Name', | ||
| 8 | + applicantPhone: 'Applicant Phone', | ||
| 9 | + status: 'Status', | ||
| 10 | + selectStatus: 'Select Status', | ||
| 11 | + pendingReview: 'Pending Review', | ||
| 12 | + pendingPayment: 'Pending Payment', | ||
| 13 | + completed: 'Completed', | ||
| 14 | + applicationFailed: 'Application Failed', | ||
| 15 | + search: 'Search', | ||
| 16 | + reset: 'Reset', | ||
| 17 | + parkingSpaceApplication: 'Parking Space Application', | ||
| 18 | + applyForSpace: 'Apply for Space', | ||
| 19 | + applicationId: 'Application ID', | ||
| 20 | + parkingSpace: 'Parking Space', | ||
| 21 | + vehicleType: 'Vehicle Type', | ||
| 22 | + color: 'Color', | ||
| 23 | + startTime: 'Start Time', | ||
| 24 | + endTime: 'End Time', | ||
| 25 | + applicant: 'Applicant', | ||
| 26 | + phoneNumber: 'Phone Number', | ||
| 27 | + reviewResult: 'Review Result', | ||
| 28 | + operation: 'Operation', | ||
| 29 | + audit: 'Audit', | ||
| 30 | + edit: 'Edit', | ||
| 31 | + delete: 'Delete', | ||
| 32 | + homeCar: 'Home Car', | ||
| 33 | + bus: 'Bus', | ||
| 34 | + truck: 'Truck', | ||
| 35 | + abnormalVehicle: 'Abnormal Vehicle', | ||
| 36 | + statusAbnormal: 'Status Abnormal' | ||
| 37 | + }, | ||
| 38 | + editParkingSpaceApply: { | ||
| 39 | + editApplication: 'Edit Parking Space Application', | ||
| 40 | + licensePlate: 'License Plate', | ||
| 41 | + carBrand: 'Car Brand', | ||
| 42 | + vehicleType: 'Vehicle Type', | ||
| 43 | + color: 'Color', | ||
| 44 | + startTime: 'Start Time', | ||
| 45 | + endTime: 'End Time', | ||
| 46 | + applicant: 'Applicant', | ||
| 47 | + applicantPhone: 'Applicant Phone', | ||
| 48 | + remarks: 'Remarks', | ||
| 49 | + required: 'Required', | ||
| 50 | + optional: 'Optional', | ||
| 51 | + save: 'Save', | ||
| 52 | + cancel: 'Cancel', | ||
| 53 | + fillLicensePlate: 'Please fill in license plate', | ||
| 54 | + fillCarBrand: 'Please fill in car brand', | ||
| 55 | + selectVehicleType: 'Please select vehicle type', | ||
| 56 | + fillColor: 'Please fill in color', | ||
| 57 | + fillStartTime: 'Please fill in start time', | ||
| 58 | + fillEndTime: 'Please fill in end time', | ||
| 59 | + fillApplicant: 'Please fill in applicant', | ||
| 60 | + fillApplicantPhone: 'Please fill in applicant phone' | ||
| 61 | + }, | ||
| 62 | + deleteParkingSpaceApply: { | ||
| 63 | + confirmOperation: 'Please confirm your operation', | ||
| 64 | + confirmDelete: 'Confirm delete parking space application', | ||
| 65 | + cancel: 'Cancel', | ||
| 66 | + confirmDeleteAction: 'Confirm Delete', | ||
| 67 | + deletePrompt: 'Are you sure you want to delete this parking space application?' | ||
| 68 | + } | ||
| 69 | + }, | ||
| 70 | + zh: { | ||
| 71 | + parkingSpaceApplyManage: { | ||
| 72 | + searchCondition: '查询条件', | ||
| 73 | + licensePlate: '车牌号', | ||
| 74 | + carBrand: '车辆品牌', | ||
| 75 | + applicantName: '申请人名称', | ||
| 76 | + applicantPhone: '申请人电话', | ||
| 77 | + status: '状态', | ||
| 78 | + selectStatus: '请选择状态', | ||
| 79 | + pendingReview: '待审核', | ||
| 80 | + pendingPayment: '待缴费', | ||
| 81 | + completed: '完成', | ||
| 82 | + applicationFailed: '申请失败', | ||
| 83 | + search: '查询', | ||
| 84 | + reset: '重置', | ||
| 85 | + parkingSpaceApplication: '车位申请', | ||
| 86 | + applyForSpace: '申请车位', | ||
| 87 | + applicationId: '申请ID', | ||
| 88 | + parkingSpace: '停车位', | ||
| 89 | + vehicleType: '车辆类型', | ||
| 90 | + color: '颜色', | ||
| 91 | + startTime: '起租时间', | ||
| 92 | + endTime: '结租时间', | ||
| 93 | + applicant: '申请人', | ||
| 94 | + phoneNumber: '手机号', | ||
| 95 | + reviewResult: '审核结果', | ||
| 96 | + operation: '操作', | ||
| 97 | + audit: '审核', | ||
| 98 | + edit: '修改', | ||
| 99 | + delete: '删除', | ||
| 100 | + homeCar: '家用小汽车', | ||
| 101 | + bus: '客车', | ||
| 102 | + truck: '货车', | ||
| 103 | + abnormalVehicle: '异常车辆', | ||
| 104 | + statusAbnormal: '状态异常' | ||
| 105 | + }, | ||
| 106 | + editParkingSpaceApply: { | ||
| 107 | + editApplication: '修改车位申请', | ||
| 108 | + licensePlate: '车牌号', | ||
| 109 | + carBrand: '汽车品牌', | ||
| 110 | + vehicleType: '车辆类型', | ||
| 111 | + color: '颜色', | ||
| 112 | + startTime: '起租时间', | ||
| 113 | + endTime: '结租时间', | ||
| 114 | + applicant: '申请人', | ||
| 115 | + applicantPhone: '申请人电话', | ||
| 116 | + remarks: '备注', | ||
| 117 | + required: '必填', | ||
| 118 | + optional: '选填', | ||
| 119 | + save: '保存', | ||
| 120 | + cancel: '取消', | ||
| 121 | + fillLicensePlate: '请填写车牌号', | ||
| 122 | + fillCarBrand: '请填写汽车品牌', | ||
| 123 | + selectVehicleType: '请选择车辆类型', | ||
| 124 | + fillColor: '请填写颜色', | ||
| 125 | + fillStartTime: '请填写起租时间', | ||
| 126 | + fillEndTime: '请填写结租时间', | ||
| 127 | + fillApplicant: '请填写申请人', | ||
| 128 | + fillApplicantPhone: '请填写申请人电话' | ||
| 129 | + }, | ||
| 130 | + deleteParkingSpaceApply: { | ||
| 131 | + confirmOperation: '请确认您的操作', | ||
| 132 | + confirmDelete: '确定删除车位申请', | ||
| 133 | + cancel: '点错了', | ||
| 134 | + confirmDeleteAction: '确认删除', | ||
| 135 | + deletePrompt: '确定删除车位申请吗?' | ||
| 136 | + } | ||
| 137 | + } | ||
| 138 | +} | ||
| 0 | \ No newline at end of file | 139 | \ No newline at end of file |
src/views/car/parkingSpaceApplyManageList.vue
0 → 100644
| 1 | +<template> | ||
| 2 | + <div class="parking-space-apply-manage"> | ||
| 3 | + <el-card class="search-card"> | ||
| 4 | + <div slot="header" class="clearfix flex justify-between"> | ||
| 5 | + <span>{{ $t('parkingSpaceApplyManage.searchCondition') }}</span> | ||
| 6 | + </div> | ||
| 7 | + <el-form :model="conditions" label-width="0"> | ||
| 8 | + <el-row :gutter="20"> | ||
| 9 | + <el-col :span="4"> | ||
| 10 | + <el-form-item> | ||
| 11 | + <el-input v-model="conditions.carNum" :placeholder="$t('parkingSpaceApplyManage.licensePlate')" clearable /> | ||
| 12 | + </el-form-item> | ||
| 13 | + </el-col> | ||
| 14 | + <el-col :span="4"> | ||
| 15 | + <el-form-item> | ||
| 16 | + <el-input v-model="conditions.carBrand" :placeholder="$t('parkingSpaceApplyManage.carBrand')" clearable /> | ||
| 17 | + </el-form-item> | ||
| 18 | + </el-col> | ||
| 19 | + <el-col :span="4"> | ||
| 20 | + <el-form-item> | ||
| 21 | + <el-input v-model="conditions.applyPersonName" :placeholder="$t('parkingSpaceApplyManage.applicantName')" | ||
| 22 | + clearable /> | ||
| 23 | + </el-form-item> | ||
| 24 | + </el-col> | ||
| 25 | + <el-col :span="4"> | ||
| 26 | + <el-form-item> | ||
| 27 | + <el-input v-model="conditions.applyPersonLink" :placeholder="$t('parkingSpaceApplyManage.applicantPhone')" | ||
| 28 | + clearable /> | ||
| 29 | + </el-form-item> | ||
| 30 | + </el-col> | ||
| 31 | + <el-col :span="4"> | ||
| 32 | + <el-form-item> | ||
| 33 | + <el-select v-model="conditions.state" :placeholder="$t('parkingSpaceApplyManage.selectStatus')" | ||
| 34 | + style="width: 100%"> | ||
| 35 | + <el-option :label="$t('parkingSpaceApplyManage.selectStatus')" value="" /> | ||
| 36 | + <el-option :label="$t('parkingSpaceApplyManage.pendingReview')" value="1001" /> | ||
| 37 | + <el-option :label="$t('parkingSpaceApplyManage.pendingPayment')" value="2002" /> | ||
| 38 | + <el-option :label="$t('parkingSpaceApplyManage.completed')" value="3003" /> | ||
| 39 | + <el-option :label="$t('parkingSpaceApplyManage.applicationFailed')" value="4004" /> | ||
| 40 | + </el-select> | ||
| 41 | + </el-form-item> | ||
| 42 | + </el-col> | ||
| 43 | + <el-col :span="4"> | ||
| 44 | + <el-button type="primary" @click="_queryParkingSpaceApplyMethod"> | ||
| 45 | + {{ $t('parkingSpaceApplyManage.search') }} | ||
| 46 | + </el-button> | ||
| 47 | + <el-button @click="_resetParkingSpaceApplyMethod"> | ||
| 48 | + {{ $t('parkingSpaceApplyManage.reset') }} | ||
| 49 | + </el-button> | ||
| 50 | + </el-col> | ||
| 51 | + </el-row> | ||
| 52 | + </el-form> | ||
| 53 | + </el-card> | ||
| 54 | + | ||
| 55 | + <el-card class="list-card"> | ||
| 56 | + <div slot="header" class="flex justify-between"> | ||
| 57 | + <span>{{ $t('parkingSpaceApplyManage.parkingSpaceApplication') }}</span> | ||
| 58 | + <el-button type="primary" size="small" style="float: right;" @click="_openAddParkingSpaceApplyModal"> | ||
| 59 | + {{ $t('parkingSpaceApplyManage.applyForSpace') }} | ||
| 60 | + </el-button> | ||
| 61 | + </div> | ||
| 62 | + | ||
| 63 | + <el-table :data="parkingSpaceApplys" border v-loading="loading"> | ||
| 64 | + <el-table-column prop="applyId" :label="$t('parkingSpaceApplyManage.applicationId')" align="center" /> | ||
| 65 | + <el-table-column prop="carNum" :label="$t('parkingSpaceApplyManage.licensePlate')" align="center" /> | ||
| 66 | + <el-table-column :label="$t('parkingSpaceApplyManage.parkingSpace')" align="center"> | ||
| 67 | + <template slot-scope="scope"> | ||
| 68 | + <span v-if="scope.row.psId"> | ||
| 69 | + {{ scope.row.areaNum }} - {{ scope.row.num }} | ||
| 70 | + </span> | ||
| 71 | + <span v-else>-</span> | ||
| 72 | + </template> | ||
| 73 | + </el-table-column> | ||
| 74 | + <el-table-column prop="carBrand" :label="$t('parkingSpaceApplyManage.carBrand')" align="center" /> | ||
| 75 | + <el-table-column :label="$t('parkingSpaceApplyManage.vehicleType')" align="center"> | ||
| 76 | + <template slot-scope="scope"> | ||
| 77 | + {{ _getCatType(scope.row.carType) }} | ||
| 78 | + </template> | ||
| 79 | + </el-table-column> | ||
| 80 | + <el-table-column prop="carColor" :label="$t('parkingSpaceApplyManage.color')" align="center" /> | ||
| 81 | + <el-table-column prop="startTime" :label="$t('parkingSpaceApplyManage.startTime')" align="center" /> | ||
| 82 | + <el-table-column prop="endTime" :label="$t('parkingSpaceApplyManage.endTime')" align="center" /> | ||
| 83 | + <el-table-column prop="applyPersonName" :label="$t('parkingSpaceApplyManage.applicant')" align="center" /> | ||
| 84 | + <el-table-column prop="applyPersonLink" :label="$t('parkingSpaceApplyManage.phoneNumber')" align="center" /> | ||
| 85 | + <el-table-column :label="$t('parkingSpaceApplyManage.reviewResult')" align="center"> | ||
| 86 | + <template slot-scope="scope"> | ||
| 87 | + <el-tag :type="getStatusTagType(scope.row.state)" size="small"> | ||
| 88 | + {{ _getState(scope.row.state) }} | ||
| 89 | + </el-tag> | ||
| 90 | + </template> | ||
| 91 | + </el-table-column> | ||
| 92 | + <el-table-column :label="$t('parkingSpaceApplyManage.operation')" align="center" width="250"> | ||
| 93 | + <template slot-scope="scope"> | ||
| 94 | + <el-button v-if="scope.row.state === '1001'" size="mini" type="primary" | ||
| 95 | + @click="_openAuditParkingSpaceApplyModal(scope.row)"> | ||
| 96 | + {{ $t('parkingSpaceApplyManage.audit') }} | ||
| 97 | + </el-button> | ||
| 98 | + <el-button v-if="scope.row.state === '1001'" size="mini" type="warning" | ||
| 99 | + @click="_openEditParkingSpaceApplyModel(scope.row)"> | ||
| 100 | + {{ $t('parkingSpaceApplyManage.edit') }} | ||
| 101 | + </el-button> | ||
| 102 | + <el-button size="mini" type="danger" @click="_openDeleteParkingSpaceApplyModel(scope.row)"> | ||
| 103 | + {{ $t('parkingSpaceApplyManage.delete') }} | ||
| 104 | + </el-button> | ||
| 105 | + </template> | ||
| 106 | + </el-table-column> | ||
| 107 | + </el-table> | ||
| 108 | + | ||
| 109 | + <el-pagination :current-page="page.current" :page-sizes="[10, 20, 30, 50]" :page-size="page.size" | ||
| 110 | + :total="page.total" layout="total, sizes, prev, pager, next, jumper" @size-change="handleSizeChange" | ||
| 111 | + @current-change="handleCurrentChange" style="margin-top: 20px;" /> | ||
| 112 | + </el-card> | ||
| 113 | + | ||
| 114 | + <edit-parking-space-apply ref="editComponent" @success="handleSuccess" /> | ||
| 115 | + <delete-parking-space-apply ref="deleteComponent" @success="handleSuccess" /> | ||
| 116 | + </div> | ||
| 117 | +</template> | ||
| 118 | + | ||
| 119 | +<script> | ||
| 120 | +import { listParkingSpaceApply } from '@/api/car/parkingSpaceApplyManageApi' | ||
| 121 | +import EditParkingSpaceApply from '@/components/car/editParkingSpaceApply' | ||
| 122 | +import DeleteParkingSpaceApply from '@/components/car/deleteParkingSpaceApply' | ||
| 123 | + | ||
| 124 | +export default { | ||
| 125 | + name: 'ParkingSpaceApplyManageList', | ||
| 126 | + components: { | ||
| 127 | + EditParkingSpaceApply, | ||
| 128 | + DeleteParkingSpaceApply | ||
| 129 | + }, | ||
| 130 | + data() { | ||
| 131 | + return { | ||
| 132 | + loading: false, | ||
| 133 | + page: { | ||
| 134 | + current: 1, | ||
| 135 | + size: 10, | ||
| 136 | + total: 0 | ||
| 137 | + }, | ||
| 138 | + conditions: { | ||
| 139 | + state: '', | ||
| 140 | + carNum: '', | ||
| 141 | + carBrand: '', | ||
| 142 | + applyPersonName: '', | ||
| 143 | + applyPersonLink: '', | ||
| 144 | + communityId: '' | ||
| 145 | + }, | ||
| 146 | + parkingSpaceApplys: [] | ||
| 147 | + } | ||
| 148 | + }, | ||
| 149 | + created() { | ||
| 150 | + this._listParkingSpaceApplys(1, this.page.size) | ||
| 151 | + }, | ||
| 152 | + methods: { | ||
| 153 | + async _listParkingSpaceApplys(page, size) { | ||
| 154 | + this.loading = true | ||
| 155 | + try { | ||
| 156 | + const params = { | ||
| 157 | + ...this.conditions, | ||
| 158 | + page: page, | ||
| 159 | + row: size | ||
| 160 | + } | ||
| 161 | + const response = await listParkingSpaceApply(params) | ||
| 162 | + if (response.code === 0) { | ||
| 163 | + this.parkingSpaceApplys = response.data | ||
| 164 | + this.page.total = response.total | ||
| 165 | + this.page.current = page | ||
| 166 | + } else { | ||
| 167 | + this.$message.error(response.msg || this.$t('common.requestFailed')) | ||
| 168 | + } | ||
| 169 | + } catch (error) { | ||
| 170 | + console.error('Error fetching parking space applications:', error) | ||
| 171 | + this.$message.error(this.$t('common.requestError')) | ||
| 172 | + } finally { | ||
| 173 | + this.loading = false | ||
| 174 | + } | ||
| 175 | + }, | ||
| 176 | + | ||
| 177 | + _queryParkingSpaceApplyMethod() { | ||
| 178 | + this._listParkingSpaceApplys(1, this.page.size) | ||
| 179 | + }, | ||
| 180 | + | ||
| 181 | + _resetParkingSpaceApplyMethod() { | ||
| 182 | + this.conditions = { | ||
| 183 | + state: '', | ||
| 184 | + carNum: '', | ||
| 185 | + carBrand: '', | ||
| 186 | + applyPersonName: '', | ||
| 187 | + applyPersonLink: '', | ||
| 188 | + communityId: '' | ||
| 189 | + } | ||
| 190 | + this._listParkingSpaceApplys(1, this.page.size) | ||
| 191 | + }, | ||
| 192 | + | ||
| 193 | + _openAddParkingSpaceApplyModal() { | ||
| 194 | + // 跳转到申请页面 | ||
| 195 | + this.$router.push('/views/car/addParkingSpaceApply') | ||
| 196 | + }, | ||
| 197 | + | ||
| 198 | + _openAuditParkingSpaceApplyModal(apply) { | ||
| 199 | + // 跳转到审核页面 | ||
| 200 | + this.$router.push(`/views/car/auditParkingSpaceApply?applyId=${apply.applyId}`) | ||
| 201 | + }, | ||
| 202 | + | ||
| 203 | + _openEditParkingSpaceApplyModel(apply) { | ||
| 204 | + this.$refs.editComponent.open(apply) | ||
| 205 | + }, | ||
| 206 | + | ||
| 207 | + _openDeleteParkingSpaceApplyModel(apply) { | ||
| 208 | + this.$refs.deleteComponent.open(apply) | ||
| 209 | + }, | ||
| 210 | + | ||
| 211 | + handleSizeChange(size) { | ||
| 212 | + this.page.size = size | ||
| 213 | + this._listParkingSpaceApplys(1, size) | ||
| 214 | + }, | ||
| 215 | + | ||
| 216 | + handleCurrentChange(page) { | ||
| 217 | + this._listParkingSpaceApplys(page, this.page.size) | ||
| 218 | + }, | ||
| 219 | + | ||
| 220 | + handleSuccess() { | ||
| 221 | + this._listParkingSpaceApplys(this.page.current, this.page.size) | ||
| 222 | + }, | ||
| 223 | + | ||
| 224 | + getStatusTagType(state) { | ||
| 225 | + switch (state) { | ||
| 226 | + case '1001': return 'warning' | ||
| 227 | + case '2002': return 'primary' | ||
| 228 | + case '3003': return 'success' | ||
| 229 | + case '4004': return 'danger' | ||
| 230 | + default: return 'info' | ||
| 231 | + } | ||
| 232 | + }, | ||
| 233 | + | ||
| 234 | + _getState(state) { | ||
| 235 | + switch (state) { | ||
| 236 | + case '1001': return this.$t('parkingSpaceApplyManage.pendingReview') | ||
| 237 | + case '2002': return this.$t('parkingSpaceApplyManage.pendingPayment') | ||
| 238 | + case '3003': return this.$t('parkingSpaceApplyManage.completed') | ||
| 239 | + case '4004': return this.$t('parkingSpaceApplyManage.applicationFailed') | ||
| 240 | + default: return this.$t('parkingSpaceApplyManage.statusAbnormal') | ||
| 241 | + } | ||
| 242 | + }, | ||
| 243 | + | ||
| 244 | + _getCatType(type) { | ||
| 245 | + switch (type) { | ||
| 246 | + case '9901': return this.$t('parkingSpaceApplyManage.homeCar') | ||
| 247 | + case '9902': return this.$t('parkingSpaceApplyManage.bus') | ||
| 248 | + case '9903': return this.$t('parkingSpaceApplyManage.truck') | ||
| 249 | + default: return this.$t('parkingSpaceApplyManage.abnormalVehicle') | ||
| 250 | + } | ||
| 251 | + } | ||
| 252 | + } | ||
| 253 | +} | ||
| 254 | +</script> | ||
| 255 | + | ||
| 256 | +<style scoped> | ||
| 257 | +.search-card { | ||
| 258 | + margin-bottom: 20px; | ||
| 259 | +} | ||
| 260 | + | ||
| 261 | +.list-card { | ||
| 262 | + margin-top: 20px; | ||
| 263 | +} | ||
| 264 | +</style> | ||
| 0 | \ No newline at end of file | 265 | \ No newline at end of file |
src/views/car/remainingParkingSpaceLang.js
0 → 100644
| 1 | +export const messages = { | ||
| 2 | + en: { | ||
| 3 | + remainingParkingSpace: { | ||
| 4 | + title: 'Remaining Parking Space', | ||
| 5 | + total: 'Total Parking Spaces', | ||
| 6 | + freeCount: 'Remaining Spaces', | ||
| 7 | + createTime: 'Collection Time', | ||
| 8 | + operation: 'Operation', | ||
| 9 | + refresh: 'Refresh', | ||
| 10 | + unit: 'units', | ||
| 11 | + fetchError: 'Failed to fetch parking space data' | ||
| 12 | + } | ||
| 13 | + }, | ||
| 14 | + zh: { | ||
| 15 | + remainingParkingSpace: { | ||
| 16 | + title: '剩余车位', | ||
| 17 | + total: '总车位数', | ||
| 18 | + freeCount: '剩余车位数', | ||
| 19 | + createTime: '采集时间', | ||
| 20 | + operation: '操作', | ||
| 21 | + refresh: '刷新', | ||
| 22 | + unit: '位', | ||
| 23 | + fetchError: '获取车位数据失败' | ||
| 24 | + } | ||
| 25 | + } | ||
| 26 | +} | ||
| 0 | \ No newline at end of file | 27 | \ No newline at end of file |
src/views/car/remainingParkingSpaceList.vue
0 → 100644
| 1 | +<template> | ||
| 2 | + <div class="remaining-parking-space-container"> | ||
| 3 | + <el-card class="box-card"> | ||
| 4 | + <div slot="header" class="flex justify-between"> | ||
| 5 | + <div>{{ $t('remainingParkingSpace.title') }}</div> | ||
| 6 | + </div> | ||
| 7 | + <div class="card-content"> | ||
| 8 | + <el-row> | ||
| 9 | + <el-col :span="24"> | ||
| 10 | + <el-table | ||
| 11 | + v-loading="loading" | ||
| 12 | + :data="tableData" | ||
| 13 | + style="width: 100%" | ||
| 14 | + border | ||
| 15 | + stripe | ||
| 16 | + > | ||
| 17 | + <el-table-column | ||
| 18 | + prop="total" | ||
| 19 | + :label="$t('remainingParkingSpace.total')" | ||
| 20 | + align="center" | ||
| 21 | + > | ||
| 22 | + <template slot-scope="scope"> | ||
| 23 | + {{ scope.row.total }} {{ $t('remainingParkingSpace.unit') }} | ||
| 24 | + </template> | ||
| 25 | + </el-table-column> | ||
| 26 | + <el-table-column | ||
| 27 | + prop="freeCount" | ||
| 28 | + :label="$t('remainingParkingSpace.freeCount')" | ||
| 29 | + align="center" | ||
| 30 | + > | ||
| 31 | + <template slot-scope="scope"> | ||
| 32 | + {{ scope.row.freeCount }} {{ $t('remainingParkingSpace.unit') }} | ||
| 33 | + </template> | ||
| 34 | + </el-table-column> | ||
| 35 | + <el-table-column | ||
| 36 | + prop="createTime" | ||
| 37 | + :label="$t('remainingParkingSpace.createTime')" | ||
| 38 | + align="center" | ||
| 39 | + /> | ||
| 40 | + <el-table-column | ||
| 41 | + :label="$t('remainingParkingSpace.operation')" | ||
| 42 | + align="center" | ||
| 43 | + width="150" | ||
| 44 | + > | ||
| 45 | + <template slot-scope="scope"> | ||
| 46 | + <el-button | ||
| 47 | + size="mini" | ||
| 48 | + type="primary" | ||
| 49 | + @click="handleRefresh(scope.row)" | ||
| 50 | + > | ||
| 51 | + {{ $t('remainingParkingSpace.refresh') }} | ||
| 52 | + </el-button> | ||
| 53 | + </template> | ||
| 54 | + </el-table-column> | ||
| 55 | + </el-table> | ||
| 56 | + </el-col> | ||
| 57 | + </el-row> | ||
| 58 | + </div> | ||
| 59 | + </el-card> | ||
| 60 | + </div> | ||
| 61 | +</template> | ||
| 62 | + | ||
| 63 | +<script> | ||
| 64 | +import { getRemainingParkingSpace } from '@/api/car/remainingParkingSpaceApi' | ||
| 65 | +import { getCommunityId } from '@/api/community/communityApi' | ||
| 66 | + | ||
| 67 | +export default { | ||
| 68 | + name: 'RemainingParkingSpaceList', | ||
| 69 | + data() { | ||
| 70 | + return { | ||
| 71 | + loading: false, | ||
| 72 | + tableData: [ | ||
| 73 | + { | ||
| 74 | + total: 0, | ||
| 75 | + freeCount: 0, | ||
| 76 | + createTime: this.formatDateTime(new Date().getTime()) | ||
| 77 | + } | ||
| 78 | + ], | ||
| 79 | + communityId: '' | ||
| 80 | + } | ||
| 81 | + }, | ||
| 82 | + created() { | ||
| 83 | + this.communityId = getCommunityId() | ||
| 84 | + this.getData() | ||
| 85 | + }, | ||
| 86 | + methods: { | ||
| 87 | + formatDateTime(timestamp) { | ||
| 88 | + const date = new Date(timestamp) | ||
| 89 | + return `${date.getFullYear()}-${(date.getMonth() + 1).toString().padStart(2, '0')}-${date.getDate().toString().padStart(2, '0')} ${date.getHours().toString().padStart(2, '0')}:${date.getMinutes().toString().padStart(2, '0')}:${date.getSeconds().toString().padStart(2, '0')}` | ||
| 90 | + }, | ||
| 91 | + async getData() { | ||
| 92 | + try { | ||
| 93 | + this.loading = true | ||
| 94 | + const params = { | ||
| 95 | + communityId: this.communityId, | ||
| 96 | + iotApiCode: 'getFreeParkingSpaceBmoImpl' | ||
| 97 | + } | ||
| 98 | + | ||
| 99 | + const res = await getRemainingParkingSpace(params) | ||
| 100 | + if (res.code === 0) { | ||
| 101 | + this.tableData = [{ | ||
| 102 | + total: res.data.total, | ||
| 103 | + freeCount: res.data.freeCount, | ||
| 104 | + createTime: this.formatDateTime(new Date().getTime()) | ||
| 105 | + }] | ||
| 106 | + } else { | ||
| 107 | + this.$message.error(res.msg || this.$t('remainingParkingSpace.fetchError')) | ||
| 108 | + } | ||
| 109 | + } catch (error) { | ||
| 110 | + this.$message.error(this.$t('remainingParkingSpace.fetchError')) | ||
| 111 | + console.error('Error fetching remaining parking space:', error) | ||
| 112 | + } finally { | ||
| 113 | + this.loading = false | ||
| 114 | + } | ||
| 115 | + }, | ||
| 116 | + handleRefresh() { | ||
| 117 | + this.getData() | ||
| 118 | + } | ||
| 119 | + } | ||
| 120 | +} | ||
| 121 | +</script> | ||
| 122 | + | ||
| 123 | +<style lang="scss" scoped> | ||
| 124 | +.remaining-parking-space-container { | ||
| 125 | + padding: 20px; | ||
| 126 | + | ||
| 127 | + .box-card { | ||
| 128 | + margin-bottom: 20px; | ||
| 129 | + | ||
| 130 | + .clearfix { | ||
| 131 | + display: flex; | ||
| 132 | + justify-content: space-between; | ||
| 133 | + align-items: center; | ||
| 134 | + } | ||
| 135 | + } | ||
| 136 | + | ||
| 137 | + .card-content { | ||
| 138 | + padding: 20px; | ||
| 139 | + } | ||
| 140 | +} | ||
| 141 | +</style> | ||
| 0 | \ No newline at end of file | 142 | \ No newline at end of file |
src/views/car/tempCarPaymentLang.js
0 → 100644
| 1 | +export const messages = { | ||
| 2 | + en: { | ||
| 3 | + tempCarPayment: { | ||
| 4 | + searchTitle: 'Search Conditions', | ||
| 5 | + inParkingTitle: 'Parking Vehicles', | ||
| 6 | + carNumPlaceholder: 'Please enter license plate number', | ||
| 7 | + carStatusPlaceholder: 'Please select vehicle status', | ||
| 8 | + selectCarStatus: 'Select vehicle status', | ||
| 9 | + inStatus: 'Entry Status', | ||
| 10 | + paidStatus: 'Payment Completed', | ||
| 11 | + outStatus: 'Exit Status', | ||
| 12 | + repayStatus: 'Re-payment due to timeout', | ||
| 13 | + entryStartTime: 'Entry start time', | ||
| 14 | + entryEndTime: 'Entry end time', | ||
| 15 | + search: 'Search', | ||
| 16 | + reset: 'Reset', | ||
| 17 | + inoutId: 'In/Out ID', | ||
| 18 | + carStatus: 'Vehicle Status', | ||
| 19 | + carNum: 'License Plate', | ||
| 20 | + inTime: 'Entry Time', | ||
| 21 | + payType: 'Payment Type', | ||
| 22 | + payableAmount: 'Payable Amount', | ||
| 23 | + paidAmount: 'Paid Amount', | ||
| 24 | + payTime: 'Payment Time', | ||
| 25 | + loadParkingAreaError: 'Failed to load parking areas', | ||
| 26 | + queryError: 'Query failed' | ||
| 27 | + } | ||
| 28 | + }, | ||
| 29 | + zh: { | ||
| 30 | + tempCarPayment: { | ||
| 31 | + searchTitle: '查询条件', | ||
| 32 | + inParkingTitle: '在场车辆', | ||
| 33 | + carNumPlaceholder: '请输入车牌号', | ||
| 34 | + carStatusPlaceholder: '请选择车辆状态', | ||
| 35 | + selectCarStatus: '请选择车辆状态', | ||
| 36 | + inStatus: '进场状态', | ||
| 37 | + paidStatus: '支付完成', | ||
| 38 | + outStatus: '离场状态', | ||
| 39 | + repayStatus: '支付超时重新支付', | ||
| 40 | + entryStartTime: '进场开始时间', | ||
| 41 | + entryEndTime: '进场结束时间', | ||
| 42 | + search: '查询', | ||
| 43 | + reset: '重置', | ||
| 44 | + inoutId: '进出场编号', | ||
| 45 | + carStatus: '车辆状态', | ||
| 46 | + carNum: '车牌号', | ||
| 47 | + inTime: '进场时间', | ||
| 48 | + payType: '收费类型', | ||
| 49 | + payableAmount: '应收金额', | ||
| 50 | + paidAmount: '实收金额', | ||
| 51 | + payTime: '支付时间', | ||
| 52 | + loadParkingAreaError: '加载停车区域失败', | ||
| 53 | + queryError: '查询失败' | ||
| 54 | + } | ||
| 55 | + } | ||
| 56 | +} | ||
| 0 | \ No newline at end of file | 57 | \ No newline at end of file |
src/views/car/tempCarPaymentList.vue
0 → 100644
| 1 | +<template> | ||
| 2 | + <div class="animated fadeInRight"> | ||
| 3 | + <el-row :gutter="20"> | ||
| 4 | + <el-col :span="3" class="left-panel"> | ||
| 5 | + <el-card class="box-card"> | ||
| 6 | + <div class="treeview"> | ||
| 7 | + <ul class="list-group"> | ||
| 8 | + <li v-for="(item, index) in parkingAreas" :key="index" class="list-group-item" | ||
| 9 | + :class="{ 'vc-node-selected': conditions.paId === item.paId }" @click="handleSwitchParkingArea(item)"> | ||
| 10 | + {{ item.num }} | ||
| 11 | + </li> | ||
| 12 | + </ul> | ||
| 13 | + </div> | ||
| 14 | + </el-card> | ||
| 15 | + </el-col> | ||
| 16 | + | ||
| 17 | + <el-col :span="21" class="right-panel"> | ||
| 18 | + <el-card class="box-card" > | ||
| 19 | + <div slot="header" class="flex justify-between"> | ||
| 20 | + <span>{{ $t('tempCarPayment.searchTitle') }}</span> | ||
| 21 | + </div> | ||
| 22 | + <el-form :inline="true" :model="conditions" class="demo-form-inline"> | ||
| 23 | + <el-row :gutter="20"> | ||
| 24 | + <el-col :span="4"> | ||
| 25 | + <el-form-item> | ||
| 26 | + <el-input v-model="conditions.carNum" :placeholder="$t('tempCarPayment.carNumPlaceholder')" /> | ||
| 27 | + </el-form-item> | ||
| 28 | + </el-col> | ||
| 29 | + | ||
| 30 | + <el-col :span="4"> | ||
| 31 | + <el-form-item> | ||
| 32 | + <el-select v-model="conditions.state" :placeholder="$t('tempCarPayment.carStatusPlaceholder')" | ||
| 33 | + style="width:100%"> | ||
| 34 | + <el-option label="" :value="null">{{ $t('tempCarPayment.selectCarStatus') }}</el-option> | ||
| 35 | + <el-option value="100300" :label="$t('tempCarPayment.inStatus')" /> | ||
| 36 | + <el-option value="100400" :label="$t('tempCarPayment.paidStatus')" /> | ||
| 37 | + <el-option value="100500" :label="$t('tempCarPayment.outStatus')" /> | ||
| 38 | + <el-option value="100600" :label="$t('tempCarPayment.repayStatus')" /> | ||
| 39 | + </el-select> | ||
| 40 | + </el-form-item> | ||
| 41 | + </el-col> | ||
| 42 | + | ||
| 43 | + <el-col :span="4"> | ||
| 44 | + <el-form-item> | ||
| 45 | + <el-date-picker v-model="conditions.startTime" type="datetime" | ||
| 46 | + :placeholder="$t('tempCarPayment.entryStartTime')" style="width:100%" /> | ||
| 47 | + </el-form-item> | ||
| 48 | + </el-col> | ||
| 49 | + | ||
| 50 | + <el-col :span="4"> | ||
| 51 | + <el-form-item> | ||
| 52 | + <el-date-picker v-model="conditions.endTime" type="datetime" | ||
| 53 | + :placeholder="$t('tempCarPayment.entryEndTime')" style="width:100%" /> | ||
| 54 | + </el-form-item> | ||
| 55 | + </el-col> | ||
| 56 | + | ||
| 57 | + <el-col :span="4" > | ||
| 58 | + <el-button type="primary" @click="queryCarInoutMethod">{{ $t('tempCarPayment.search') }}</el-button> | ||
| 59 | + <el-button @click="resetCarInoutMethod">{{ $t('tempCarPayment.reset') }}</el-button> | ||
| 60 | + </el-col> | ||
| 61 | + </el-row> | ||
| 62 | + </el-form> | ||
| 63 | + </el-card> | ||
| 64 | + | ||
| 65 | + <el-card class="box-card" style="margin-top:20px"> | ||
| 66 | + <div slot="header" class="flex justify-between"> | ||
| 67 | + <span>{{ $t('tempCarPayment.inParkingTitle') }}</span> | ||
| 68 | + </div> | ||
| 69 | + <el-table :data="payments" border style="width:100%"> | ||
| 70 | + <el-table-column prop="inoutId" :label="$t('tempCarPayment.inoutId')" align="center" /> | ||
| 71 | + <el-table-column :label="$t('tempCarPayment.carStatus')" align="center"> | ||
| 72 | + <template slot-scope="scope"> | ||
| 73 | + {{ getCarStatusText(scope.row.carInout) }} | ||
| 74 | + </template> | ||
| 75 | + </el-table-column> | ||
| 76 | + <el-table-column prop="carNum" :label="$t('tempCarPayment.carNum')" align="center" /> | ||
| 77 | + <el-table-column prop="inTime" :label="$t('tempCarPayment.inTime')" align="center" /> | ||
| 78 | + <el-table-column prop="payTypeName" :label="$t('tempCarPayment.payType')" align="center" /> | ||
| 79 | + <el-table-column prop="payCharge" :label="$t('tempCarPayment.payableAmount')" align="center" /> | ||
| 80 | + <el-table-column prop="realCharge" :label="$t('tempCarPayment.paidAmount')" align="center" /> | ||
| 81 | + <el-table-column prop="createTime" :label="$t('tempCarPayment.payTime')" align="center" /> | ||
| 82 | + </el-table> | ||
| 83 | + | ||
| 84 | + <el-pagination :current-page="pagination.current" :page-sizes="[10, 20, 30, 50]" :page-size="pagination.size" | ||
| 85 | + layout="total, sizes, prev, pager, next, jumper" :total="pagination.total" @size-change="handleSizeChange" | ||
| 86 | + @current-change="handleCurrentChange" style="margin-top:20px" /> | ||
| 87 | + </el-card> | ||
| 88 | + </el-col> | ||
| 89 | + </el-row> | ||
| 90 | + </div> | ||
| 91 | +</template> | ||
| 92 | + | ||
| 93 | +<script> | ||
| 94 | +import { listParkingAreas, getCarInoutPaymentList } from '@/api/car/tempCarPaymentApi' | ||
| 95 | +import { getCommunityId } from '@/api/community/communityApi' | ||
| 96 | + | ||
| 97 | +export default { | ||
| 98 | + name: 'TempCarPaymentList', | ||
| 99 | + data() { | ||
| 100 | + return { | ||
| 101 | + parkingAreas: [], | ||
| 102 | + payments: [], | ||
| 103 | + pagination: { | ||
| 104 | + current: 1, | ||
| 105 | + size: 10, | ||
| 106 | + total: 0 | ||
| 107 | + }, | ||
| 108 | + conditions: { | ||
| 109 | + paId: '', | ||
| 110 | + state: null, | ||
| 111 | + carNum: '', | ||
| 112 | + startTime: null, | ||
| 113 | + endTime: null, | ||
| 114 | + iotApiCode: 'listCarInoutPaymentBmoImpl' | ||
| 115 | + } | ||
| 116 | + } | ||
| 117 | + }, | ||
| 118 | + created() { | ||
| 119 | + this.communityId = getCommunityId() | ||
| 120 | + this.loadParkingAreas() | ||
| 121 | + }, | ||
| 122 | + methods: { | ||
| 123 | + async loadParkingAreas() { | ||
| 124 | + try { | ||
| 125 | + const params = { | ||
| 126 | + page: 1, | ||
| 127 | + row: 100, | ||
| 128 | + communityId: this.communityId | ||
| 129 | + } | ||
| 130 | + const res = await listParkingAreas(params) | ||
| 131 | + this.parkingAreas = res.parkingAreas | ||
| 132 | + if (this.parkingAreas.length > 0) { | ||
| 133 | + this.handleSwitchParkingArea(this.parkingAreas[0]) | ||
| 134 | + } | ||
| 135 | + } catch (error) { | ||
| 136 | + console.error('加载停车区域失败:', error) | ||
| 137 | + this.$message.error(this.$t('tempCarPayment.loadParkingAreaError')) | ||
| 138 | + } | ||
| 139 | + }, | ||
| 140 | + | ||
| 141 | + handleSwitchParkingArea(parkingArea) { | ||
| 142 | + this.conditions.paId = parkingArea.paId | ||
| 143 | + this.queryCarInoutMethod() | ||
| 144 | + }, | ||
| 145 | + | ||
| 146 | + async queryCarInoutMethod() { | ||
| 147 | + try { | ||
| 148 | + const params = { | ||
| 149 | + ...this.conditions, | ||
| 150 | + page: this.pagination.current, | ||
| 151 | + row: this.pagination.size, | ||
| 152 | + communityId: this.communityId | ||
| 153 | + } | ||
| 154 | + | ||
| 155 | + // 清理参数 | ||
| 156 | + if (params.carNum) params.carNum = params.carNum.trim() | ||
| 157 | + if (params.startTime) params.startTime = this.formatDate(params.startTime) | ||
| 158 | + if (params.endTime) params.endTime = this.formatDate(params.endTime) | ||
| 159 | + | ||
| 160 | + const res = await getCarInoutPaymentList(params) | ||
| 161 | + this.payments = res.data | ||
| 162 | + this.pagination.total = res.total | ||
| 163 | + } catch (error) { | ||
| 164 | + console.error('查询失败:', error) | ||
| 165 | + this.$message.error(this.$t('tempCarPayment.queryError')) | ||
| 166 | + } | ||
| 167 | + }, | ||
| 168 | + | ||
| 169 | + resetCarInoutMethod() { | ||
| 170 | + this.conditions = { | ||
| 171 | + ...this.conditions, | ||
| 172 | + state: null, | ||
| 173 | + carNum: '', | ||
| 174 | + startTime: null, | ||
| 175 | + endTime: null | ||
| 176 | + } | ||
| 177 | + this.queryCarInoutMethod() | ||
| 178 | + }, | ||
| 179 | + | ||
| 180 | + handleSizeChange(size) { | ||
| 181 | + this.pagination.size = size | ||
| 182 | + this.queryCarInoutMethod() | ||
| 183 | + }, | ||
| 184 | + | ||
| 185 | + handleCurrentChange(current) { | ||
| 186 | + this.pagination.current = current | ||
| 187 | + this.queryCarInoutMethod() | ||
| 188 | + }, | ||
| 189 | + | ||
| 190 | + formatDate(date) { | ||
| 191 | + if (!date) return null | ||
| 192 | + const d = new Date(date) | ||
| 193 | + return `${d.getFullYear()}-${(d.getMonth() + 1).toString().padStart(2, '0')}-${d.getDate().toString().padStart(2, '0')} ${d.getHours().toString().padStart(2, '0')}:${d.getMinutes().toString().padStart(2, '0')}:${d.getSeconds().toString().padStart(2, '0')}` | ||
| 194 | + }, | ||
| 195 | + | ||
| 196 | + getCarStatusText(status) { | ||
| 197 | + const statusMap = { | ||
| 198 | + '3306': this.$t('tempCarPayment.inStatus'), | ||
| 199 | + '100400': this.$t('tempCarPayment.paidStatus'), | ||
| 200 | + '100500': this.$t('tempCarPayment.outStatus'), | ||
| 201 | + '100600': this.$t('tempCarPayment.repayStatus') | ||
| 202 | + } | ||
| 203 | + return statusMap[status] || status | ||
| 204 | + } | ||
| 205 | + } | ||
| 206 | +} | ||
| 207 | +</script> | ||
| 208 | + | ||
| 209 | +<style scoped> | ||
| 210 | +.left-panel { | ||
| 211 | + padding-right: 0; | ||
| 212 | +} | ||
| 213 | + | ||
| 214 | +.treeview { | ||
| 215 | + overflow-y: auto; | ||
| 216 | +} | ||
| 217 | + | ||
| 218 | +.list-group { | ||
| 219 | + list-style: none; | ||
| 220 | + padding: 0; | ||
| 221 | + margin: 0; | ||
| 222 | +} | ||
| 223 | + | ||
| 224 | +.list-group-item { | ||
| 225 | + padding: 10px 15px; | ||
| 226 | + margin-bottom: 5px; | ||
| 227 | + border-radius: 4px; | ||
| 228 | + text-align: center; | ||
| 229 | + cursor: pointer; | ||
| 230 | + transition: all 0.3s; | ||
| 231 | +} | ||
| 232 | + | ||
| 233 | +.list-group-item:hover { | ||
| 234 | + background-color: #f5f7fa; | ||
| 235 | +} | ||
| 236 | + | ||
| 237 | +.vc-node-selected { | ||
| 238 | + background-color: #409EFF; | ||
| 239 | + color: white; | ||
| 240 | +} | ||
| 241 | + | ||
| 242 | +.button-group { | ||
| 243 | + margin-top: 10px; | ||
| 244 | + text-align: center; | ||
| 245 | +} | ||
| 246 | + | ||
| 247 | +.box-card { | ||
| 248 | + margin-bottom: 20px; | ||
| 249 | +} | ||
| 250 | +</style> | ||
| 0 | \ No newline at end of file | 251 | \ No newline at end of file |