Commit 2e0fd29c4bee2d330d3f72a09922c2b446bf70f3
1 parent
2c760b97
开发报修
Showing
29 changed files
with
3536 additions
and
18 deletions
src/api/fee/carCreateFeeApi.js
0 → 100644
| 1 | +import request from '@/utils/request' | ||
| 2 | +import { getCommunityId } from '@/api/community/communityApi' | ||
| 3 | + | ||
| 4 | +// 查询车辆收费信息 | ||
| 5 | +export function listCarCreateFees(params) { | ||
| 6 | + return new Promise((resolve, reject) => { | ||
| 7 | + const communityId = getCommunityId() | ||
| 8 | + request({ | ||
| 9 | + url: '/owner.queryOwnerCars', | ||
| 10 | + method: 'get', | ||
| 11 | + params: { | ||
| 12 | + ...params, | ||
| 13 | + communityId | ||
| 14 | + } | ||
| 15 | + }).then(response => { | ||
| 16 | + const res = response.data | ||
| 17 | + if (res.code === 0) { | ||
| 18 | + resolve(res) | ||
| 19 | + } else { | ||
| 20 | + reject(new Error(res.msg || '查询车辆收费信息失败')) | ||
| 21 | + } | ||
| 22 | + }).catch(error => { | ||
| 23 | + reject(error) | ||
| 24 | + }) | ||
| 25 | + }) | ||
| 26 | +} | ||
| 27 | + | ||
| 28 | +// 保存停车位收费信息 | ||
| 29 | +export function saveParkingSpaceCreateFee(data) { | ||
| 30 | + return new Promise((resolve, reject) => { | ||
| 31 | + const communityId = getCommunityId() | ||
| 32 | + request({ | ||
| 33 | + url: '/fee.saveParkingSpaceCreateFee', | ||
| 34 | + method: 'post', | ||
| 35 | + data: { | ||
| 36 | + ...data, | ||
| 37 | + communityId | ||
| 38 | + } | ||
| 39 | + }).then(response => { | ||
| 40 | + const res = response.data | ||
| 41 | + | ||
| 42 | + resolve(res) | ||
| 43 | + }).catch(error => { | ||
| 44 | + reject(error) | ||
| 45 | + }) | ||
| 46 | + }) | ||
| 47 | +} | ||
| 48 | + | ||
| 49 | +// 查询费用配置列表 | ||
| 50 | +export function listFeeConfigs(params) { | ||
| 51 | + return new Promise((resolve, reject) => { | ||
| 52 | + const communityId = getCommunityId() | ||
| 53 | + request({ | ||
| 54 | + url: '/feeConfig.listFeeConfigs', | ||
| 55 | + method: 'get', | ||
| 56 | + params: { | ||
| 57 | + ...params, | ||
| 58 | + communityId | ||
| 59 | + } | ||
| 60 | + }).then(response => { | ||
| 61 | + const res = response.data | ||
| 62 | + resolve(res) | ||
| 63 | + }).catch(error => { | ||
| 64 | + reject(error) | ||
| 65 | + }) | ||
| 66 | + }) | ||
| 67 | +} | ||
| 68 | + | ||
| 69 | +// 查询停车场列表 | ||
| 70 | +export function listParkingAreas(params) { | ||
| 71 | + return new Promise((resolve, reject) => { | ||
| 72 | + const communityId = getCommunityId() | ||
| 73 | + request({ | ||
| 74 | + url: '/parkingArea.listParkingAreas', | ||
| 75 | + method: 'get', | ||
| 76 | + params: { | ||
| 77 | + ...params, | ||
| 78 | + communityId | ||
| 79 | + } | ||
| 80 | + }).then(response => { | ||
| 81 | + const res = response.data | ||
| 82 | + resolve(res) | ||
| 83 | + }).catch(error => { | ||
| 84 | + reject(error) | ||
| 85 | + }) | ||
| 86 | + }) | ||
| 87 | +} | ||
| 88 | + | ||
| 89 | +// 导出车辆收费Excel | ||
| 90 | +export function exportCarFeeExcel(params) { | ||
| 91 | + return new Promise((resolve, reject) => { | ||
| 92 | + const communityId = getCommunityId() | ||
| 93 | + request({ | ||
| 94 | + url: '/callComponent/importAndExportFee/exportData', | ||
| 95 | + method: 'get', | ||
| 96 | + params: { | ||
| 97 | + ...params, | ||
| 98 | + communityId, | ||
| 99 | + type: '2002' | ||
| 100 | + } | ||
| 101 | + }).then(response => { | ||
| 102 | + resolve(response) | ||
| 103 | + }).catch(error => { | ||
| 104 | + reject(error) | ||
| 105 | + }) | ||
| 106 | + }) | ||
| 107 | +} | ||
| 108 | + | ||
| 109 | +// 导入自定义费用 | ||
| 110 | +export function importCustomFee(data) { | ||
| 111 | + return new Promise((resolve, reject) => { | ||
| 112 | + const communityId = getCommunityId() | ||
| 113 | + const formData = new FormData() | ||
| 114 | + formData.append('uploadFile', data.file) | ||
| 115 | + formData.append('communityId', communityId) | ||
| 116 | + formData.append('importAdapt', 'importCustomFee') | ||
| 117 | + | ||
| 118 | + request({ | ||
| 119 | + url: '/callComponent/upload/assetImport/importData', | ||
| 120 | + method: 'post', | ||
| 121 | + data: formData, | ||
| 122 | + headers: { | ||
| 123 | + 'Content-Type': 'multipart/form-data' | ||
| 124 | + } | ||
| 125 | + }).then(response => { | ||
| 126 | + const res = response.data | ||
| 127 | + if (res.code === 0) { | ||
| 128 | + resolve(res) | ||
| 129 | + } else { | ||
| 130 | + reject(new Error(res.msg || '导入自定义费用失败')) | ||
| 131 | + } | ||
| 132 | + }).catch(error => { | ||
| 133 | + reject(error) | ||
| 134 | + }) | ||
| 135 | + }) | ||
| 136 | +} | ||
| 0 | \ No newline at end of file | 137 | \ No newline at end of file |
src/api/fee/listCarFeeApi.js
0 → 100644
| 1 | +import request from '@/utils/request' | ||
| 2 | + | ||
| 3 | +// 查询费用列表 | ||
| 4 | +export function listFee(params) { | ||
| 5 | + return new Promise((resolve, reject) => { | ||
| 6 | + request({ | ||
| 7 | + url: '/fee.listFee', | ||
| 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 deleteFee(data) { | ||
| 21 | + return new Promise((resolve, reject) => { | ||
| 22 | + request({ | ||
| 23 | + url: '/fee.deleteFee', | ||
| 24 | + method: 'post', | ||
| 25 | + data | ||
| 26 | + }).then(response => { | ||
| 27 | + const res = response.data | ||
| 28 | + | ||
| 29 | + resolve(res) | ||
| 30 | + }).catch(error => { | ||
| 31 | + reject(error) | ||
| 32 | + }) | ||
| 33 | + }) | ||
| 34 | +} | ||
| 35 | + | ||
| 36 | +// 更新费用 | ||
| 37 | +export function updateFee(data) { | ||
| 38 | + return new Promise((resolve, reject) => { | ||
| 39 | + request({ | ||
| 40 | + url: '/fee.updateFee', | ||
| 41 | + method: 'post', | ||
| 42 | + data | ||
| 43 | + }).then(response => { | ||
| 44 | + const res = response.data | ||
| 45 | + | ||
| 46 | + resolve(res) | ||
| 47 | + }).catch(error => { | ||
| 48 | + reject(error) | ||
| 49 | + }) | ||
| 50 | + }) | ||
| 51 | +} | ||
| 52 | + | ||
| 53 | +// 拆分费用 | ||
| 54 | +export function splitFee(data) { | ||
| 55 | + return new Promise((resolve, reject) => { | ||
| 56 | + request({ | ||
| 57 | + url: '/feeSub.splitPayFee', | ||
| 58 | + method: 'post', | ||
| 59 | + data | ||
| 60 | + }).then(response => { | ||
| 61 | + const res = response.data | ||
| 62 | + | ||
| 63 | + resolve(res) | ||
| 64 | + }).catch(error => { | ||
| 65 | + reject(error) | ||
| 66 | + }) | ||
| 67 | + }) | ||
| 68 | +} | ||
| 69 | + | ||
| 70 | +// 保存车位费用 | ||
| 71 | +export function saveParkingSpaceCreateFee(data) { | ||
| 72 | + return new Promise((resolve, reject) => { | ||
| 73 | + request({ | ||
| 74 | + url: '/fee.saveParkingSpaceCreateFee', | ||
| 75 | + method: 'post', | ||
| 76 | + data | ||
| 77 | + }).then(response => { | ||
| 78 | + const res = response.data | ||
| 79 | + | ||
| 80 | + resolve(res) | ||
| 81 | + }).catch(error => { | ||
| 82 | + reject(error) | ||
| 83 | + }) | ||
| 84 | + }) | ||
| 85 | +} | ||
| 86 | + | ||
| 87 | +// 保存抄表 | ||
| 88 | +export function saveMeterWater(data) { | ||
| 89 | + return new Promise((resolve, reject) => { | ||
| 90 | + request({ | ||
| 91 | + url: '/meterWater.saveMeterWater', | ||
| 92 | + method: 'post', | ||
| 93 | + data | ||
| 94 | + }).then(response => { | ||
| 95 | + const res = response.data | ||
| 96 | + | ||
| 97 | + resolve(res) | ||
| 98 | + }).catch(error => { | ||
| 99 | + reject(error) | ||
| 100 | + }) | ||
| 101 | + }) | ||
| 102 | +} | ||
| 103 | + | ||
| 104 | +// 查询抄表 | ||
| 105 | +export function queryPreMeterWater(params) { | ||
| 106 | + return new Promise((resolve, reject) => { | ||
| 107 | + request({ | ||
| 108 | + url: '/meterWater/queryPreMeterWater', | ||
| 109 | + method: 'get', | ||
| 110 | + params | ||
| 111 | + }).then(response => { | ||
| 112 | + const res = response.data | ||
| 113 | + | ||
| 114 | + resolve(res) | ||
| 115 | + }).catch(error => { | ||
| 116 | + reject(error) | ||
| 117 | + }) | ||
| 118 | + }) | ||
| 119 | +} | ||
| 120 | + | ||
| 121 | +// 查询费用配置 | ||
| 122 | +export function listFeeConfigs(params) { | ||
| 123 | + return new Promise((resolve, reject) => { | ||
| 124 | + request({ | ||
| 125 | + url: '/feeConfig.listFeeConfigs', | ||
| 126 | + method: 'get', | ||
| 127 | + params | ||
| 128 | + }).then(response => { | ||
| 129 | + const res = response.data | ||
| 130 | + resolve(res) | ||
| 131 | + }).catch(error => { | ||
| 132 | + reject(error) | ||
| 133 | + }) | ||
| 134 | + }) | ||
| 135 | +} | ||
| 136 | + | ||
| 137 | +// 查询停车场 | ||
| 138 | +export function listParkingAreas(params) { | ||
| 139 | + return new Promise((resolve, reject) => { | ||
| 140 | + request({ | ||
| 141 | + url: '/parkingArea.listParkingAreas', | ||
| 142 | + method: 'get', | ||
| 143 | + params | ||
| 144 | + }).then(response => { | ||
| 145 | + const res = response.data | ||
| 146 | + resolve(res) | ||
| 147 | + }).catch(error => { | ||
| 148 | + reject(error) | ||
| 149 | + }) | ||
| 150 | + }) | ||
| 151 | +} | ||
| 152 | + | ||
| 153 | +// 查询楼栋 | ||
| 154 | +export function queryFloors(params) { | ||
| 155 | + return new Promise((resolve, reject) => { | ||
| 156 | + request({ | ||
| 157 | + url: '/floor.queryFloors', | ||
| 158 | + method: 'get', | ||
| 159 | + params | ||
| 160 | + }).then(response => { | ||
| 161 | + const res = response.data | ||
| 162 | + resolve(res) | ||
| 163 | + }).catch(error => { | ||
| 164 | + reject(error) | ||
| 165 | + }) | ||
| 166 | + }) | ||
| 167 | +} | ||
| 168 | + | ||
| 169 | +// 查询单元 | ||
| 170 | +export function queryUnits(params) { | ||
| 171 | + return new Promise((resolve, reject) => { | ||
| 172 | + request({ | ||
| 173 | + url: '/unit.queryUnits', | ||
| 174 | + method: 'get', | ||
| 175 | + params | ||
| 176 | + }).then(response => { | ||
| 177 | + const res = response.data | ||
| 178 | + resolve(res) | ||
| 179 | + }).catch(error => { | ||
| 180 | + reject(error) | ||
| 181 | + }) | ||
| 182 | + }) | ||
| 183 | +} | ||
| 184 | + | ||
| 185 | +// 查询房屋 | ||
| 186 | +export function queryRooms(params) { | ||
| 187 | + return new Promise((resolve, reject) => { | ||
| 188 | + request({ | ||
| 189 | + url: '/room.queryRooms', | ||
| 190 | + method: 'get', | ||
| 191 | + params | ||
| 192 | + }).then(response => { | ||
| 193 | + const res = response.data | ||
| 194 | + resolve(res) | ||
| 195 | + }).catch(error => { | ||
| 196 | + reject(error) | ||
| 197 | + }) | ||
| 198 | + }) | ||
| 199 | +} | ||
| 200 | + | ||
| 201 | +// 查询抄表类型 | ||
| 202 | +export function listMeterType(params) { | ||
| 203 | + return new Promise((resolve, reject) => { | ||
| 204 | + request({ | ||
| 205 | + url: '/meterType.listMeterType', | ||
| 206 | + method: 'get', | ||
| 207 | + params | ||
| 208 | + }).then(response => { | ||
| 209 | + const res = response.data | ||
| 210 | + resolve(res) | ||
| 211 | + }).catch(error => { | ||
| 212 | + reject(error) | ||
| 213 | + }) | ||
| 214 | + }) | ||
| 215 | +} | ||
| 0 | \ No newline at end of file | 216 | \ No newline at end of file |
src/api/work/repairSettingApi.js
0 → 100644
| 1 | +import request from '@/utils/request' | ||
| 2 | +import { getCommunityId } from '@/api/community/communityApi' | ||
| 3 | + | ||
| 4 | +// 获取报修设置列表 | ||
| 5 | +export function listRepairSettings(params) { | ||
| 6 | + return new Promise((resolve, reject) => { | ||
| 7 | + params.communityId = getCommunityId() | ||
| 8 | + request({ | ||
| 9 | + url: '/repair.listRepairSettings', | ||
| 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 saveRepairSetting(data) { | ||
| 27 | + return new Promise((resolve, reject) => { | ||
| 28 | + data.communityId = getCommunityId() | ||
| 29 | + request({ | ||
| 30 | + url: '/repair.saveRepairSetting', | ||
| 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 updateRepairSetting(data) { | ||
| 48 | + return new Promise((resolve, reject) => { | ||
| 49 | + data.communityId = getCommunityId() | ||
| 50 | + request({ | ||
| 51 | + url: '/repair.updateRepairSetting', | ||
| 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 | +} | ||
| 66 | + | ||
| 67 | +// 删除报修设置 | ||
| 68 | +export function deleteRepairSetting(settingId) { | ||
| 69 | + return new Promise((resolve, reject) => { | ||
| 70 | + const data = { | ||
| 71 | + settingId, | ||
| 72 | + communityId: getCommunityId() | ||
| 73 | + } | ||
| 74 | + request({ | ||
| 75 | + url: '/repair.deleteRepairSetting', | ||
| 76 | + method: 'post', | ||
| 77 | + data | ||
| 78 | + }).then(response => { | ||
| 79 | + const res = response.data | ||
| 80 | + if (res.code === 0) { | ||
| 81 | + resolve(res) | ||
| 82 | + } else { | ||
| 83 | + reject(new Error(res.msg || '删除报修设置失败')) | ||
| 84 | + } | ||
| 85 | + }).catch(error => { | ||
| 86 | + reject(error) | ||
| 87 | + }) | ||
| 88 | + }) | ||
| 89 | +} | ||
| 90 | + | ||
| 91 | +// 获取字典数据 | ||
| 92 | +export function getDict(dictType, state) { | ||
| 93 | + return new Promise((resolve, reject) => { | ||
| 94 | + request({ | ||
| 95 | + url: '/dict.getDict', | ||
| 96 | + method: 'get', | ||
| 97 | + params: { | ||
| 98 | + dictType, | ||
| 99 | + state, | ||
| 100 | + communityId: getCommunityId() | ||
| 101 | + } | ||
| 102 | + }).then(response => { | ||
| 103 | + const res = response.data | ||
| 104 | + if (res.code === 0) { | ||
| 105 | + resolve(res.data) | ||
| 106 | + } else { | ||
| 107 | + reject(new Error(res.msg || '获取字典数据失败')) | ||
| 108 | + } | ||
| 109 | + }).catch(error => { | ||
| 110 | + reject(error) | ||
| 111 | + }) | ||
| 112 | + }) | ||
| 113 | +} | ||
| 0 | \ No newline at end of file | 114 | \ No newline at end of file |
src/api/work/repairTypeUserApi.js
0 → 100644
| 1 | +import request from '@/utils/request' | ||
| 2 | +import { getCommunityId } from '@/api/community/communityApi' | ||
| 3 | + | ||
| 4 | +// 获取报修师傅列表 | ||
| 5 | +export function listRepairTypeUsers(params) { | ||
| 6 | + return new Promise((resolve, reject) => { | ||
| 7 | + request({ | ||
| 8 | + url: '/repair.listRepairTypeUsers', | ||
| 9 | + method: 'get', | ||
| 10 | + params | ||
| 11 | + }).then(response => { | ||
| 12 | + resolve(response.data) | ||
| 13 | + }).catch(error => { | ||
| 14 | + reject(error) | ||
| 15 | + }) | ||
| 16 | + }) | ||
| 17 | +} | ||
| 18 | + | ||
| 19 | +// 保存报修师傅 | ||
| 20 | +export function saveRepairTypeUser(data) { | ||
| 21 | + data.communityId = getCommunityId() | ||
| 22 | + return new Promise((resolve, reject) => { | ||
| 23 | + request({ | ||
| 24 | + url: '/repair.saveRepairTypeUser', | ||
| 25 | + method: 'post', | ||
| 26 | + data | ||
| 27 | + }).then(response => { | ||
| 28 | + resolve(response.data) | ||
| 29 | + }).catch(error => { | ||
| 30 | + reject(error) | ||
| 31 | + }) | ||
| 32 | + }) | ||
| 33 | +} | ||
| 34 | + | ||
| 35 | +// 更新报修师傅 | ||
| 36 | +export function updateRepairTypeUser(data) { | ||
| 37 | + data.communityId = getCommunityId() | ||
| 38 | + | ||
| 39 | + return new Promise((resolve, reject) => { | ||
| 40 | + request({ | ||
| 41 | + url: '/repair/updateRepairTypeUser', | ||
| 42 | + method: 'post', | ||
| 43 | + data | ||
| 44 | + }).then(response => { | ||
| 45 | + resolve(response.data) | ||
| 46 | + }).catch(error => { | ||
| 47 | + reject(error) | ||
| 48 | + }) | ||
| 49 | + }) | ||
| 50 | +} | ||
| 51 | + | ||
| 52 | +// 删除报修师傅 | ||
| 53 | +export function deleteRepairTypeUser(data) { | ||
| 54 | + data.communityId = getCommunityId() | ||
| 55 | + | ||
| 56 | + return new Promise((resolve, reject) => { | ||
| 57 | + request({ | ||
| 58 | + url: '/repair/deleteRepairTypeUser', | ||
| 59 | + method: 'post', | ||
| 60 | + data | ||
| 61 | + }).then(response => { | ||
| 62 | + resolve(response.data) | ||
| 63 | + }).catch(error => { | ||
| 64 | + reject(error) | ||
| 65 | + }) | ||
| 66 | + }) | ||
| 67 | +} | ||
| 68 | + | ||
| 69 | +// 获取组织树 | ||
| 70 | +export function listOrgTree(params) { | ||
| 71 | + | ||
| 72 | + return new Promise((resolve, reject) => { | ||
| 73 | + request({ | ||
| 74 | + url: '/org/listOrgTree', | ||
| 75 | + method: 'get', | ||
| 76 | + params | ||
| 77 | + }).then(response => { | ||
| 78 | + resolve(response.data) | ||
| 79 | + }).catch(error => { | ||
| 80 | + reject(error) | ||
| 81 | + }) | ||
| 82 | + }) | ||
| 83 | +} | ||
| 84 | + | ||
| 85 | +// 获取员工信息 | ||
| 86 | +export function getStaffInfos(params) { | ||
| 87 | + return new Promise((resolve, reject) => { | ||
| 88 | + request({ | ||
| 89 | + url: '/query.staff.infos', | ||
| 90 | + method: 'get', | ||
| 91 | + params | ||
| 92 | + }).then(response => { | ||
| 93 | + resolve(response.data) | ||
| 94 | + }).catch(error => { | ||
| 95 | + reject(error) | ||
| 96 | + }) | ||
| 97 | + }) | ||
| 98 | +} | ||
| 0 | \ No newline at end of file | 99 | \ No newline at end of file |
src/components/fee/carCreateFeeAdd.vue
0 → 100644
| 1 | +<template> | ||
| 2 | + <el-dialog :title="$t('carCreateFeeAdd.createFee')" :visible.sync="visible" width="50%" @close="handleClose"> | ||
| 3 | + <el-form :model="form" label-width="150px" ref="form"> | ||
| 4 | + <el-form-item v-if="isMore" :label="$t('carCreateFeeAdd.chargeScope')" prop="locationTypeCd" | ||
| 5 | + :rules="[{ required: true, message: $t('carCreateFeeAdd.requiredChargeScope') }]"> | ||
| 6 | + <el-select v-model="form.locationTypeCd" style="width:100%"> | ||
| 7 | + <el-option :label="$t('carCreateFeeAdd.community')" value="1000" /> | ||
| 8 | + <el-option :label="$t('carCreateFeeAdd.parkingLot')" value="3000" /> | ||
| 9 | + </el-select> | ||
| 10 | + </el-form-item> | ||
| 11 | + | ||
| 12 | + <el-form-item v-else :label="$t('carCreateFeeAdd.vehicle')" prop="locationTypeCdName"> | ||
| 13 | + <el-input v-model="form.locationTypeCdName" disabled :placeholder="$t('carCreateFeeAdd.requiredChargeScope')" /> | ||
| 14 | + </el-form-item> | ||
| 15 | + | ||
| 16 | + <el-form-item v-if="form.locationTypeCd === '3000' && isMore" :label="$t('carCreateFeeAdd.parkingLot')" prop="paId"> | ||
| 17 | + <parking-area-select2 @change="handleParkingAreaChange" /> | ||
| 18 | + </el-form-item> | ||
| 19 | + | ||
| 20 | + <el-form-item :label="$t('carCreateFeeAdd.feeType')" prop="feeTypeCd" | ||
| 21 | + :rules="[{ required: true, message: $t('carCreateFeeAdd.requiredFeeType') }]"> | ||
| 22 | + <el-select v-model="form.feeTypeCd" @change="handleFeeTypeChange" style="width:100%"> | ||
| 23 | + <template v-for="item in feeTypeCds"> | ||
| 24 | + <el-option :key="item.statusCd" :label="item.name" :value="item.statusCd" | ||
| 25 | + v-if="item.statusCd !== '888800010001' && item.statusCd !== '888800010009' && item.statusCd !== '888800010011'" /> | ||
| 26 | + </template> | ||
| 27 | + </el-select> | ||
| 28 | + </el-form-item> | ||
| 29 | + | ||
| 30 | + <el-form-item :label="$t('carCreateFeeAdd.feeItem')" prop="configId" | ||
| 31 | + :rules="[{ required: true, message: $t('carCreateFeeAdd.requiredFeeItem') }]"> | ||
| 32 | + <el-select v-model="form.configId" @change="handleConfigChange" style="width:100%"> | ||
| 33 | + <el-option v-for="item in feeConfigs" :key="item.configId" :label="item.feeName" :value="item.configId" /> | ||
| 34 | + </el-select> | ||
| 35 | + </el-form-item> | ||
| 36 | + | ||
| 37 | + <el-form-item v-if="form.computingFormula === '4004'" :label="$t('carCreateFeeAdd.chargeAmount')" prop="amount" | ||
| 38 | + :rules="[{ required: true, message: $t('carCreateFeeAdd.requiredChargeAmount') }]"> | ||
| 39 | + <el-input v-model="form.amount" /> | ||
| 40 | + </el-form-item> | ||
| 41 | + | ||
| 42 | + <el-form-item v-if="isMore" :label="$t('carCreateFeeAdd.parkingSpaceStatus')" prop="carState"> | ||
| 43 | + <el-checkbox-group v-model="form.carState"> | ||
| 44 | + <el-checkbox label="S">{{ $t('carCreateFeeAdd.sold') }}</el-checkbox> | ||
| 45 | + <el-checkbox label="H">{{ $t('carCreateFeeAdd.rented') }}</el-checkbox> | ||
| 46 | + </el-checkbox-group> | ||
| 47 | + </el-form-item> | ||
| 48 | + | ||
| 49 | + <el-form-item :label="$t('carCreateFeeAdd.startTime')" prop="startTime" | ||
| 50 | + :rules="[{ required: true, message: $t('carCreateFeeAdd.requiredStartTime') }]"> | ||
| 51 | + <el-date-picker v-model="form.startTime" type="date" value-format="yyyy-MM-dd" style="width:100%" | ||
| 52 | + :placeholder="$t('carCreateFeeAdd.requiredStartTime')" /> | ||
| 53 | + </el-form-item> | ||
| 54 | + | ||
| 55 | + <el-form-item :label="$t('carCreateFeeAdd.endTime')" prop="endTime" | ||
| 56 | + :rules="[{ required: true, message: $t('carCreateFeeAdd.requiredEndTime') }]"> | ||
| 57 | + <el-date-picker v-model="form.endTime" type="date" value-format="yyyy-MM-dd" style="width:100%" | ||
| 58 | + :placeholder="$t('carCreateFeeAdd.requiredEndTime')" /> | ||
| 59 | + </el-form-item> | ||
| 60 | + </el-form> | ||
| 61 | + | ||
| 62 | + <div slot="footer" class="dialog-footer"> | ||
| 63 | + <el-button @click="visible = false">{{ $t('carCreateFeeAdd.cancel') }}</el-button> | ||
| 64 | + <el-button type="primary" @click="handleSubmit">{{ $t('carCreateFeeAdd.submit') }}</el-button> | ||
| 65 | + </div> | ||
| 66 | + </el-dialog> | ||
| 67 | +</template> | ||
| 68 | + | ||
| 69 | +<script> | ||
| 70 | +import { saveParkingSpaceCreateFee, listFeeConfigs } from '@/api/fee/carCreateFeeApi' | ||
| 71 | +import { getCommunityId, getDict } from '@/api/community/communityApi' | ||
| 72 | + | ||
| 73 | +export default { | ||
| 74 | + name: 'CarCreateFeeAdd', | ||
| 75 | + data() { | ||
| 76 | + return { | ||
| 77 | + visible: false, | ||
| 78 | + isMore: false, | ||
| 79 | + form: { | ||
| 80 | + feeTypeCds: [], | ||
| 81 | + feeConfigs: [], | ||
| 82 | + parkingAreas: [], | ||
| 83 | + locationTypeCd: '', | ||
| 84 | + locationObjId: '', | ||
| 85 | + carId: '', | ||
| 86 | + feeTypeCd: '', | ||
| 87 | + configId: '', | ||
| 88 | + carState: ['H', 'S'], | ||
| 89 | + locationTypeCdName: '', | ||
| 90 | + startTime: '', | ||
| 91 | + paId: '', | ||
| 92 | + feeFlag: '', | ||
| 93 | + computingFormula: '', | ||
| 94 | + amount: '', | ||
| 95 | + endTime: '' | ||
| 96 | + }, | ||
| 97 | + feeTypeCds: [], | ||
| 98 | + feeConfigs: [] | ||
| 99 | + } | ||
| 100 | + }, | ||
| 101 | + created() { | ||
| 102 | + this.getDictData() | ||
| 103 | + }, | ||
| 104 | + methods: { | ||
| 105 | + async getDictData() { | ||
| 106 | + try { | ||
| 107 | + this.feeTypeCds = await getDict('pay_fee_config', 'fee_type_cd') | ||
| 108 | + } catch (error) { | ||
| 109 | + console.error('获取字典数据失败:', error) | ||
| 110 | + } | ||
| 111 | + }, | ||
| 112 | + open(params) { | ||
| 113 | + this.isMore = params.isMore || false | ||
| 114 | + | ||
| 115 | + if (!this.isMore && params.car) { | ||
| 116 | + this.form.locationTypeCd = '2000' | ||
| 117 | + this.form.locationObjId = params.car.carId | ||
| 118 | + this.form.carId = params.car.carId | ||
| 119 | + this.form.locationTypeCdName = params.car.carNum | ||
| 120 | + } | ||
| 121 | + | ||
| 122 | + this.visible = true | ||
| 123 | + }, | ||
| 124 | + handleClose() { | ||
| 125 | + this.resetForm() | ||
| 126 | + }, | ||
| 127 | + resetForm() { | ||
| 128 | + this.form = { | ||
| 129 | + ...this.form, | ||
| 130 | + locationTypeCd: '', | ||
| 131 | + locationObjId: '', | ||
| 132 | + carId: '', | ||
| 133 | + feeTypeCd: '', | ||
| 134 | + configId: '', | ||
| 135 | + startTime: '', | ||
| 136 | + paId: '', | ||
| 137 | + feeFlag: '', | ||
| 138 | + computingFormula: '', | ||
| 139 | + amount: '', | ||
| 140 | + endTime: '' | ||
| 141 | + } | ||
| 142 | + }, | ||
| 143 | + async handleFeeTypeChange(feeTypeCd) { | ||
| 144 | + try { | ||
| 145 | + const res = await listFeeConfigs({ | ||
| 146 | + feeTypeCd: feeTypeCd, | ||
| 147 | + isDefault: 'F', | ||
| 148 | + valid: '1', | ||
| 149 | + page: 1, | ||
| 150 | + row: 100 | ||
| 151 | + }) | ||
| 152 | + this.feeConfigs = res.feeConfigs || [] | ||
| 153 | + } catch (error) { | ||
| 154 | + this.$message.error(this.$t('common.fetchError')) | ||
| 155 | + } | ||
| 156 | + }, | ||
| 157 | + handleConfigChange(configId) { | ||
| 158 | + const config = this.feeConfigs.find(item => item.configId === configId) | ||
| 159 | + if (config) { | ||
| 160 | + this.form.feeFlag = config.feeFlag | ||
| 161 | + this.form.computingFormula = config.computingFormula | ||
| 162 | + this.form.endTime = '' | ||
| 163 | + } | ||
| 164 | + }, | ||
| 165 | + handleParkingAreaChange(paId) { | ||
| 166 | + this.form.paId = paId | ||
| 167 | + }, | ||
| 168 | + async handleSubmit() { | ||
| 169 | + try { | ||
| 170 | + await this.$refs.form.validate() | ||
| 171 | + | ||
| 172 | + // 设置收费对象ID | ||
| 173 | + if (this.form.locationTypeCd === '1000') { | ||
| 174 | + this.form.locationObjId = getCommunityId() | ||
| 175 | + } else if (this.form.locationTypeCd === '2000') { | ||
| 176 | + this.form.locationObjId = this.form.carId | ||
| 177 | + } else if (this.form.locationTypeCd === '3000') { | ||
| 178 | + this.form.locationObjId = this.form.paId | ||
| 179 | + } else { | ||
| 180 | + this.$message.error(this.$t('common.invalidScope')) | ||
| 181 | + return | ||
| 182 | + } | ||
| 183 | + | ||
| 184 | + // 提交表单 | ||
| 185 | + //const res = ; | ||
| 186 | + await saveParkingSpaceCreateFee(this.form) | ||
| 187 | + this.$message.success(this.$t('common.saveSuccess')) | ||
| 188 | + this.visible = false | ||
| 189 | + this.$emit('success') | ||
| 190 | + | ||
| 191 | + } catch (error) { | ||
| 192 | + console.error('提交失败:', error) | ||
| 193 | + } | ||
| 194 | + } | ||
| 195 | + } | ||
| 196 | +} | ||
| 197 | +</script> | ||
| 0 | \ No newline at end of file | 198 | \ No newline at end of file |
src/components/fee/deleteFee.vue
0 → 100644
| 1 | +<template> | ||
| 2 | + <el-dialog :title="$t('deleteFee.title')" :visible.sync="visible" width="30%"> | ||
| 3 | + <div> | ||
| 4 | + <p>{{ $t('deleteFee.confirmDelete') }}</p> | ||
| 5 | + </div> | ||
| 6 | + <span slot="footer" class="dialog-footer"> | ||
| 7 | + <el-button @click="close">{{ $t('common.cancel') }}</el-button> | ||
| 8 | + <el-button type="primary" @click="deleteFee">{{ $t('common.confirm') }}</el-button> | ||
| 9 | + </span> | ||
| 10 | + </el-dialog> | ||
| 11 | +</template> | ||
| 12 | + | ||
| 13 | +<script> | ||
| 14 | +import { deleteFee } from '@/api/fee/listCarFeeApi' | ||
| 15 | + | ||
| 16 | +export default { | ||
| 17 | + name: 'DeleteFee', | ||
| 18 | + data() { | ||
| 19 | + return { | ||
| 20 | + visible: false, | ||
| 21 | + deleteFeeInfo: {} | ||
| 22 | + } | ||
| 23 | + }, | ||
| 24 | + methods: { | ||
| 25 | + open(info) { | ||
| 26 | + this.deleteFeeInfo = info | ||
| 27 | + this.visible = true | ||
| 28 | + }, | ||
| 29 | + close() { | ||
| 30 | + this.visible = false | ||
| 31 | + }, | ||
| 32 | + deleteFee() { | ||
| 33 | + deleteFee(this.deleteFeeInfo).then(response => { | ||
| 34 | + if (response.data.code === 0) { | ||
| 35 | + this.$message.success(this.$t('common.deleteSuccess')) | ||
| 36 | + this.$emit('success') | ||
| 37 | + this.close() | ||
| 38 | + } else { | ||
| 39 | + this.$message.error(response.data.msg) | ||
| 40 | + } | ||
| 41 | + }).catch(error => { | ||
| 42 | + this.$message.error(error.message) | ||
| 43 | + }) | ||
| 44 | + } | ||
| 45 | + } | ||
| 46 | +} | ||
| 47 | +</script> | ||
| 0 | \ No newline at end of file | 48 | \ No newline at end of file |
src/components/fee/doImportCreateFee.vue
0 → 100644
| 1 | +<template> | ||
| 2 | + <el-dialog | ||
| 3 | + :title="$t('doImportCreateFee.customCreateFee')" | ||
| 4 | + :visible.sync="visible" | ||
| 5 | + width="50%" | ||
| 6 | + > | ||
| 7 | + <el-form label-width="150px"> | ||
| 8 | + <el-form-item :label="$t('doImportCreateFee.selectFile')"> | ||
| 9 | + <el-upload | ||
| 10 | + class="upload-demo" | ||
| 11 | + :before-upload="beforeUpload" | ||
| 12 | + :show-file-list="false" | ||
| 13 | + > | ||
| 14 | + <el-button size="small" type="primary"> | ||
| 15 | + <i class="el-icon-upload"></i> | ||
| 16 | + {{ $t('common.selectFile') }} | ||
| 17 | + </el-button> | ||
| 18 | + <div slot="tip" class="el-upload__tip" style="margin-top:10px"> | ||
| 19 | + {{ fileName || $t('doImportCreateFee.requiredFile') }} | ||
| 20 | + </div> | ||
| 21 | + </el-upload> | ||
| 22 | + </el-form-item> | ||
| 23 | + </el-form> | ||
| 24 | + | ||
| 25 | + <div slot="footer" class="dialog-footer"> | ||
| 26 | + <el-button @click="visible = false">{{ $t('doImportCreateFee.cancel') }}</el-button> | ||
| 27 | + <el-button type="primary" @click="handleImport" :disabled="!file"> | ||
| 28 | + {{ $t('doImportCreateFee.import') }} | ||
| 29 | + </el-button> | ||
| 30 | + </div> | ||
| 31 | + </el-dialog> | ||
| 32 | +</template> | ||
| 33 | + | ||
| 34 | +<script> | ||
| 35 | +import { importCustomFee } from '@/api/fee/carCreateFeeApi' | ||
| 36 | + | ||
| 37 | +export default { | ||
| 38 | + name: 'DoImportCreateFee', | ||
| 39 | + data() { | ||
| 40 | + return { | ||
| 41 | + visible: false, | ||
| 42 | + file: null, | ||
| 43 | + fileName: '' | ||
| 44 | + } | ||
| 45 | + }, | ||
| 46 | + methods: { | ||
| 47 | + open() { | ||
| 48 | + this.visible = true | ||
| 49 | + this.file = null | ||
| 50 | + this.fileName = '' | ||
| 51 | + }, | ||
| 52 | + beforeUpload(file) { | ||
| 53 | + const validTypes = ['xlsx', 'xls'] | ||
| 54 | + const fileType = file.name.split('.').pop().toLowerCase() | ||
| 55 | + const isExcel = validTypes.includes(fileType) | ||
| 56 | + const isLt2M = file.size / 1024 / 1024 < 2 | ||
| 57 | + | ||
| 58 | + if (!isExcel) { | ||
| 59 | + this.$message.error(this.$t('common.invalidExcelType')) | ||
| 60 | + return false | ||
| 61 | + } | ||
| 62 | + if (!isLt2M) { | ||
| 63 | + this.$message.error(this.$t('common.fileSizeExceed')) | ||
| 64 | + return false | ||
| 65 | + } | ||
| 66 | + | ||
| 67 | + this.file = file | ||
| 68 | + this.fileName = file.name | ||
| 69 | + return false // 阻止自动上传 | ||
| 70 | + }, | ||
| 71 | + async handleImport() { | ||
| 72 | + if (!this.file) { | ||
| 73 | + this.$message.warning(this.$t('doImportCreateFee.requiredFile')) | ||
| 74 | + return | ||
| 75 | + } | ||
| 76 | + | ||
| 77 | + try { | ||
| 78 | + const res = await importCustomFee({ | ||
| 79 | + file: this.file | ||
| 80 | + }) | ||
| 81 | + | ||
| 82 | + if (res.code === 0) { | ||
| 83 | + this.$message.success(this.$t('common.importSuccess')) | ||
| 84 | + this.visible = false | ||
| 85 | + this.$emit('success') | ||
| 86 | + } else { | ||
| 87 | + this.$message.error(res.msg || this.$t('common.importError')) | ||
| 88 | + } | ||
| 89 | + } catch (error) { | ||
| 90 | + this.$message.error(this.$t('common.importError')) | ||
| 91 | + } | ||
| 92 | + } | ||
| 93 | + } | ||
| 94 | +} | ||
| 95 | +</script> | ||
| 0 | \ No newline at end of file | 96 | \ No newline at end of file |
src/components/fee/editFee.vue
0 → 100644
| 1 | +<template> | ||
| 2 | + <el-dialog :title="$t('editFee.title')" :visible.sync="visible" width="50%"> | ||
| 3 | + <el-form :model="editFeeInfo" label-width="120px"> | ||
| 4 | + <el-form-item :label="$t('editFee.startTime')" required> | ||
| 5 | + <el-date-picker v-model="editFeeInfo.startTime" type="datetime" :placeholder="$t('editFee.startTimePlaceholder')" | ||
| 6 | + value-format="yyyy-MM-dd HH:mm:ss" style="width:100%"> | ||
| 7 | + </el-date-picker> | ||
| 8 | + </el-form-item> | ||
| 9 | + <el-form-item :label="$t('editFee.endTime')" required> | ||
| 10 | + <el-date-picker v-model="editFeeInfo.endTime" type="datetime" :placeholder="$t('editFee.endTimePlaceholder')" | ||
| 11 | + value-format="yyyy-MM-dd HH:mm:ss" style="width:100%"> | ||
| 12 | + </el-date-picker> | ||
| 13 | + </el-form-item> | ||
| 14 | + <el-form-item :label="$t('editFee.maxEndTime')" required> | ||
| 15 | + <el-date-picker v-model="editFeeInfo.maxEndTime" type="datetime" | ||
| 16 | + :placeholder="$t('editFee.maxEndTimePlaceholder')" value-format="yyyy-MM-dd HH:mm:ss" style="width:100%"> | ||
| 17 | + </el-date-picker> | ||
| 18 | + </el-form-item> | ||
| 19 | + <template v-if="editFeeInfo.computingFormula == '1102'"> | ||
| 20 | + <el-form-item :label="$t('editFee.rateCycle')" required> | ||
| 21 | + <el-input v-model="editFeeInfo.rateCycle" :placeholder="$t('editFee.rateCyclePlaceholder')"></el-input> | ||
| 22 | + </el-form-item> | ||
| 23 | + <el-form-item :label="$t('editFee.rate')" required> | ||
| 24 | + <el-input v-model="editFeeInfo.rate" :placeholder="$t('editFee.ratePlaceholder')"></el-input> | ||
| 25 | + </el-form-item> | ||
| 26 | + <el-form-item :label="$t('editFee.rateStartTime')" required> | ||
| 27 | + <el-date-picker v-model="editFeeInfo.rateStartTime" type="datetime" | ||
| 28 | + :placeholder="$t('editFee.rateStartTimePlaceholder')" value-format="yyyy-MM-dd HH:mm:ss" style="width:100%"> | ||
| 29 | + </el-date-picker> | ||
| 30 | + </el-form-item> | ||
| 31 | + </template> | ||
| 32 | + </el-form> | ||
| 33 | + <span slot="footer" class="dialog-footer"> | ||
| 34 | + <el-button @click="close">{{ $t('common.cancel') }}</el-button> | ||
| 35 | + <el-button type="primary" @click="_doEidtFee">{{ $t('common.submit') }}</el-button> | ||
| 36 | + </span> | ||
| 37 | + </el-dialog> | ||
| 38 | +</template> | ||
| 39 | + | ||
| 40 | +<script> | ||
| 41 | +import { updateFee } from '@/api/fee/listCarFeeApi' | ||
| 42 | + | ||
| 43 | +export default { | ||
| 44 | + name: 'EditFee', | ||
| 45 | + data() { | ||
| 46 | + return { | ||
| 47 | + visible: false, | ||
| 48 | + editFeeInfo: { | ||
| 49 | + feeId: '', | ||
| 50 | + startTime: '', | ||
| 51 | + endTime: '', | ||
| 52 | + feeFlag: '', | ||
| 53 | + maxEndTime: '', | ||
| 54 | + computingFormula: '', | ||
| 55 | + rateCycle: '', | ||
| 56 | + rate: '', | ||
| 57 | + rateStartTime: '' | ||
| 58 | + } | ||
| 59 | + } | ||
| 60 | + }, | ||
| 61 | + methods: { | ||
| 62 | + open(fee) { | ||
| 63 | + this.editFeeInfo = { ...fee } | ||
| 64 | + this.visible = true | ||
| 65 | + }, | ||
| 66 | + close() { | ||
| 67 | + this.visible = false | ||
| 68 | + }, | ||
| 69 | + _doEidtFee() { | ||
| 70 | + // 验证逻辑 | ||
| 71 | + updateFee(this.editFeeInfo).then(response => { | ||
| 72 | + if (response.data.code === 0) { | ||
| 73 | + this.$message.success(this.$t('common.updateSuccess')) | ||
| 74 | + this.$emit('success') | ||
| 75 | + this.close() | ||
| 76 | + } else { | ||
| 77 | + this.$message.error(response.data.msg) | ||
| 78 | + } | ||
| 79 | + }).catch(error => { | ||
| 80 | + this.$message.error(error.message) | ||
| 81 | + }) | ||
| 82 | + } | ||
| 83 | + } | ||
| 84 | +} | ||
| 85 | +</script> | ||
| 0 | \ No newline at end of file | 86 | \ No newline at end of file |
src/components/fee/exportCarFeeImportExcel.vue
0 → 100644
| 1 | +<template> | ||
| 2 | + <el-dialog :title="$t('exportCarFeeImportExcel.templateExport')" :visible.sync="visible" width="50%"> | ||
| 3 | + <el-form label-width="150px"> | ||
| 4 | + <el-form-item :label="$t('exportCarFeeImportExcel.parkingLot')"> | ||
| 5 | + <div> | ||
| 6 | + <el-checkbox v-model="isParkingAreaAll" @change="changeAllParkingAreas"> | ||
| 7 | + {{ $t('exportCarFeeImportExcel.all') }} | ||
| 8 | + </el-checkbox> | ||
| 9 | + <el-checkbox-group v-model="selectedParkingAreas" @change="changeItemParkingArea"> | ||
| 10 | + <el-checkbox v-for="item in parkingAreas" :key="item.paId" :label="item.paId" style="margin-left:15px"> | ||
| 11 | + {{ item.num }}{{ $t('exportCarFeeImportExcel.parkingLotPlaceholder') }} | ||
| 12 | + </el-checkbox> | ||
| 13 | + </el-checkbox-group> | ||
| 14 | + </div> | ||
| 15 | + </el-form-item> | ||
| 16 | + | ||
| 17 | + <el-form-item :label="$t('exportCarFeeImportExcel.feeItem')"> | ||
| 18 | + <div> | ||
| 19 | + <el-checkbox v-model="isConfigAll" @change="changeAllConfigs"> | ||
| 20 | + {{ $t('exportCarFeeImportExcel.all') }} | ||
| 21 | + </el-checkbox> | ||
| 22 | + <el-checkbox-group v-model="selectedConfigs" @change="changeItemConfig"> | ||
| 23 | + <template v-for="item in configs"> | ||
| 24 | + <el-checkbox :key="item.configId" :label="item.configId" style="margin-left:15px" | ||
| 25 | + v-if="item.feeTypeCd !== '888800010001' && item.feeTypeCd !== '888800010009' && item.feeTypeCd !== '888800010011'"> | ||
| 26 | + {{ item.feeName }} | ||
| 27 | + </el-checkbox> | ||
| 28 | + </template> | ||
| 29 | + </el-checkbox-group> | ||
| 30 | + </div> | ||
| 31 | + </el-form-item> | ||
| 32 | + </el-form> | ||
| 33 | + | ||
| 34 | + <div slot="footer" class="dialog-footer"> | ||
| 35 | + <el-button @click="visible = false">{{ $t('exportCarFeeImportExcel.cancel') }}</el-button> | ||
| 36 | + <el-button type="primary" @click="handleExport">{{ $t('exportCarFeeImportExcel.export') }}</el-button> | ||
| 37 | + </div> | ||
| 38 | + </el-dialog> | ||
| 39 | +</template> | ||
| 40 | + | ||
| 41 | +<script> | ||
| 42 | +import { listParkingAreas, listFeeConfigs, exportCarFeeExcel } from '@/api/fee/carCreateFeeApi' | ||
| 43 | + | ||
| 44 | +export default { | ||
| 45 | + name: 'ExportCarFeeImportExcel', | ||
| 46 | + data() { | ||
| 47 | + return { | ||
| 48 | + visible: false, | ||
| 49 | + isParkingAreaAll: true, | ||
| 50 | + isConfigAll: true, | ||
| 51 | + selectedParkingAreas: [], | ||
| 52 | + selectedConfigs: [], | ||
| 53 | + parkingAreas: [], | ||
| 54 | + configs: [] | ||
| 55 | + } | ||
| 56 | + }, | ||
| 57 | + created() { | ||
| 58 | + this.fetchData() | ||
| 59 | + }, | ||
| 60 | + methods: { | ||
| 61 | + async fetchData() { | ||
| 62 | + try { | ||
| 63 | + // 获取停车场 | ||
| 64 | + const parkingRes = await listParkingAreas({ | ||
| 65 | + page: 1, | ||
| 66 | + row: 150 | ||
| 67 | + }) | ||
| 68 | + this.parkingAreas = parkingRes.parkingAreas || [] | ||
| 69 | + this.selectedParkingAreas = this.parkingAreas.map(item => item.paId) | ||
| 70 | + | ||
| 71 | + // 获取费用配置 | ||
| 72 | + const configRes = await listFeeConfigs({ | ||
| 73 | + page: 1, | ||
| 74 | + row: 100, | ||
| 75 | + isDefault: 'F' | ||
| 76 | + }) | ||
| 77 | + this.configs = configRes.feeConfigs || [] | ||
| 78 | + this.selectedConfigs = this.configs | ||
| 79 | + .filter(item => item.feeTypeCd !== '888800010001' && item.feeTypeCd !== '888800010009' && item.feeTypeCd !== '888800010011') | ||
| 80 | + .map(item => item.configId) | ||
| 81 | + | ||
| 82 | + } catch (error) { | ||
| 83 | + console.error('获取数据失败:', error) | ||
| 84 | + } | ||
| 85 | + }, | ||
| 86 | + open() { | ||
| 87 | + this.visible = true | ||
| 88 | + }, | ||
| 89 | + changeAllParkingAreas() { | ||
| 90 | + if (this.isParkingAreaAll) { | ||
| 91 | + this.selectedParkingAreas = this.parkingAreas.map(item => item.paId) | ||
| 92 | + } else { | ||
| 93 | + this.selectedParkingAreas = [] | ||
| 94 | + } | ||
| 95 | + }, | ||
| 96 | + changeItemParkingArea() { | ||
| 97 | + this.isParkingAreaAll = this.selectedParkingAreas.length === this.parkingAreas.length | ||
| 98 | + }, | ||
| 99 | + changeAllConfigs() { | ||
| 100 | + if (this.isConfigAll) { | ||
| 101 | + this.selectedConfigs = this.configs | ||
| 102 | + .filter(item => item.feeTypeCd !== '888800010001' && item.feeTypeCd !== '888800010009' && item.feeTypeCd !== '888800010011') | ||
| 103 | + .map(item => item.configId) | ||
| 104 | + } else { | ||
| 105 | + this.selectedConfigs = [] | ||
| 106 | + } | ||
| 107 | + }, | ||
| 108 | + changeItemConfig() { | ||
| 109 | + this.isConfigAll = this.selectedConfigs.length === this.configs | ||
| 110 | + .filter(item => item.feeTypeCd !== '888800010001' && item.feeTypeCd !== '888800010009' && item.feeTypeCd !== '888800010011') | ||
| 111 | + .length | ||
| 112 | + }, | ||
| 113 | + async handleExport() { | ||
| 114 | + try { | ||
| 115 | + const paIds = this.selectedParkingAreas.join(',') | ||
| 116 | + const configIds = this.selectedConfigs.join(',') | ||
| 117 | + | ||
| 118 | + await exportCarFeeExcel({ | ||
| 119 | + paIds, | ||
| 120 | + configIds | ||
| 121 | + }) | ||
| 122 | + | ||
| 123 | + this.$message.success(this.$t('common.exportSuccess')) | ||
| 124 | + this.visible = false | ||
| 125 | + } catch (error) { | ||
| 126 | + this.$message.error(this.$t('common.exportError')) | ||
| 127 | + } | ||
| 128 | + } | ||
| 129 | + } | ||
| 130 | +} | ||
| 131 | +</script> | ||
| 0 | \ No newline at end of file | 132 | \ No newline at end of file |
src/components/fee/parkingAreaSelect2.vue
0 → 100644
| 1 | +<template> | ||
| 2 | + <el-select | ||
| 3 | + v-model="value" | ||
| 4 | + filterable | ||
| 5 | + remote | ||
| 6 | + :remote-method="remoteMethod" | ||
| 7 | + :loading="loading" | ||
| 8 | + :placeholder="$t('parkingAreaSelect2.parkingLotPlaceholder')" | ||
| 9 | + style="width:100%" | ||
| 10 | + @change="handleChange" | ||
| 11 | + > | ||
| 12 | + <el-option | ||
| 13 | + v-for="item in options" | ||
| 14 | + :key="item.paId" | ||
| 15 | + :label="item.num" | ||
| 16 | + :value="item.paId" | ||
| 17 | + /> | ||
| 18 | + </el-select> | ||
| 19 | +</template> | ||
| 20 | + | ||
| 21 | +<script> | ||
| 22 | +import { listParkingAreas } from '@/api/fee/carCreateFeeApi' | ||
| 23 | + | ||
| 24 | +export default { | ||
| 25 | + name: 'ParkingAreaSelect2', | ||
| 26 | + props: { | ||
| 27 | + value: { | ||
| 28 | + type: String, | ||
| 29 | + default: '' | ||
| 30 | + } | ||
| 31 | + }, | ||
| 32 | + data() { | ||
| 33 | + return { | ||
| 34 | + options: [], | ||
| 35 | + loading: false | ||
| 36 | + } | ||
| 37 | + }, | ||
| 38 | + methods: { | ||
| 39 | + async remoteMethod(query) { | ||
| 40 | + if (query) { | ||
| 41 | + this.loading = true | ||
| 42 | + try { | ||
| 43 | + const res = await listParkingAreas({ | ||
| 44 | + num: query, | ||
| 45 | + page: 1, | ||
| 46 | + row: 50 | ||
| 47 | + }) | ||
| 48 | + this.options = res.parkingAreas || [] | ||
| 49 | + } catch (error) { | ||
| 50 | + console.error('获取停车场失败:', error) | ||
| 51 | + } finally { | ||
| 52 | + this.loading = false | ||
| 53 | + } | ||
| 54 | + } else { | ||
| 55 | + this.options = [] | ||
| 56 | + } | ||
| 57 | + }, | ||
| 58 | + handleChange(value) { | ||
| 59 | + this.$emit('change', value) | ||
| 60 | + } | ||
| 61 | + } | ||
| 62 | +} | ||
| 63 | +</script> | ||
| 0 | \ No newline at end of file | 64 | \ No newline at end of file |
src/components/fee/splitFee.vue
0 → 100644
| 1 | +<template> | ||
| 2 | + <el-dialog :title="$t('splitFee.title')" :visible.sync="visible" width="50%"> | ||
| 3 | + <el-form :model="splitFeeInfo" label-width="120px"> | ||
| 4 | + <el-form-item :label="$t('splitFee.timePeriod')"> | ||
| 5 | + <div>{{ splitFeeInfo.endTime }} ~ {{ splitFeeInfo.deadlineTime }}</div> | ||
| 6 | + </el-form-item> | ||
| 7 | + <el-form-item :label="$t('splitFee.splitTime')" required> | ||
| 8 | + <el-date-picker | ||
| 9 | + v-model="splitFeeInfo.splitTime" | ||
| 10 | + type="date" | ||
| 11 | + :placeholder="$t('splitFee.splitTimePlaceholder')" | ||
| 12 | + value-format="yyyy-MM-dd" | ||
| 13 | + style="width:100%"> | ||
| 14 | + </el-date-picker> | ||
| 15 | + <span style="color: red;">{{ $t('splitFee.note') }}</span> | ||
| 16 | + </el-form-item> | ||
| 17 | + <el-form-item :label="$t('splitFee.remark')" required> | ||
| 18 | + <el-input | ||
| 19 | + type="textarea" | ||
| 20 | + v-model="splitFeeInfo.remark" | ||
| 21 | + :placeholder="$t('splitFee.remarkPlaceholder')" | ||
| 22 | + :rows="3" | ||
| 23 | + style="width:100%"> | ||
| 24 | + </el-input> | ||
| 25 | + </el-form-item> | ||
| 26 | + </el-form> | ||
| 27 | + <span slot="footer" class="dialog-footer"> | ||
| 28 | + <el-button @click="close">{{ $t('common.cancel') }}</el-button> | ||
| 29 | + <el-button type="primary" @click="_doSplitFee">{{ $t('common.submit') }}</el-button> | ||
| 30 | + </span> | ||
| 31 | + </el-dialog> | ||
| 32 | +</template> | ||
| 33 | + | ||
| 34 | +<script> | ||
| 35 | +import { splitFee } from '@/api/fee/listCarFeeApi' | ||
| 36 | + | ||
| 37 | +export default { | ||
| 38 | + name: 'SplitFee', | ||
| 39 | + data() { | ||
| 40 | + return { | ||
| 41 | + visible: false, | ||
| 42 | + splitFeeInfo: { | ||
| 43 | + feeId: '', | ||
| 44 | + splitTime: '', | ||
| 45 | + remark: '', | ||
| 46 | + endTime: '', | ||
| 47 | + deadlineTime: '' | ||
| 48 | + } | ||
| 49 | + } | ||
| 50 | + }, | ||
| 51 | + methods: { | ||
| 52 | + open(fee) { | ||
| 53 | + this.splitFeeInfo = { | ||
| 54 | + feeId: fee.feeId, | ||
| 55 | + endTime: this.$formatDate(fee.endTime), | ||
| 56 | + deadlineTime: this._computeSplitDeadLineTime(fee), | ||
| 57 | + splitTime: '', | ||
| 58 | + remark: '' | ||
| 59 | + } | ||
| 60 | + this.visible = true | ||
| 61 | + }, | ||
| 62 | + close() { | ||
| 63 | + this.visible = false | ||
| 64 | + }, | ||
| 65 | + _doSplitFee() { | ||
| 66 | + if (!this.splitFeeInfo.splitTime) { | ||
| 67 | + this.$message.error(this.$t('splitFee.splitTimeRequired')) | ||
| 68 | + return | ||
| 69 | + } | ||
| 70 | + | ||
| 71 | + const data = { | ||
| 72 | + preFeeId: this.splitFeeInfo.feeId, | ||
| 73 | + splitTime: this.splitFeeInfo.splitTime, | ||
| 74 | + remark: this.splitFeeInfo.remark | ||
| 75 | + } | ||
| 76 | + | ||
| 77 | + splitFee(data).then(response => { | ||
| 78 | + if (response.data.code === 0) { | ||
| 79 | + this.$message.success(this.$t('common.operateSuccess')) | ||
| 80 | + this.$emit('success') | ||
| 81 | + this.close() | ||
| 82 | + } else { | ||
| 83 | + this.$message.error(response.data.msg) | ||
| 84 | + } | ||
| 85 | + }).catch(error => { | ||
| 86 | + this.$message.error(error.message) | ||
| 87 | + }) | ||
| 88 | + }, | ||
| 89 | + _computeSplitDeadLineTime(fee) { | ||
| 90 | + if (fee.amountOwed == 0 && fee.endTime == fee.deadlineTime) { | ||
| 91 | + return "-" | ||
| 92 | + } | ||
| 93 | + if (fee.state == '2009001') { | ||
| 94 | + return "-" | ||
| 95 | + } | ||
| 96 | + return this.$formatDate(fee.deadlineTime) | ||
| 97 | + } | ||
| 98 | + } | ||
| 99 | +} | ||
| 100 | +</script> | ||
| 0 | \ No newline at end of file | 101 | \ No newline at end of file |
src/components/work/AddRepairSetting.vue
0 → 100644
| 1 | +<template> | ||
| 2 | + <el-dialog :title="$t('repairSetting.addTitle')" :visible.sync="visible" width="50%" @close="closeDialog"> | ||
| 3 | + <el-form ref="form" :model="formData" :rules="rules" label-width="150px"> | ||
| 4 | + <el-row> | ||
| 5 | + <el-col :span="12"> | ||
| 6 | + <el-form-item :label="$t('repairSetting.typeName')" prop="repairTypeName"> | ||
| 7 | + <el-input v-model="formData.repairTypeName" :placeholder="$t('repairSetting.repairTypeNamePlaceholder')" /> | ||
| 8 | + </el-form-item> | ||
| 9 | + </el-col> | ||
| 10 | + <el-col :span="12"> | ||
| 11 | + <el-form-item :label="$t('repairSetting.settingType')" prop="repairSettingType"> | ||
| 12 | + <el-select v-model="formData.repairSettingType" | ||
| 13 | + :placeholder="$t('repairSetting.required') + $t('repairSetting.repairSettingTypePlaceholder')" | ||
| 14 | + style="width:100%"> | ||
| 15 | + <el-option :label="$t('repairSetting.cleaningOrder')" value="100" /> | ||
| 16 | + <el-option :label="$t('repairSetting.repairOrder')" value="200" /> | ||
| 17 | + </el-select> | ||
| 18 | + </el-form-item> | ||
| 19 | + </el-col> | ||
| 20 | + </el-row> | ||
| 21 | + | ||
| 22 | + <el-row> | ||
| 23 | + <el-col :span="12"> | ||
| 24 | + <el-form-item :label="$t('repairSetting.dispatchMethod')" prop="repairWay"> | ||
| 25 | + <el-select v-model="formData.repairWay" | ||
| 26 | + :placeholder="$t('repairSetting.required') + $t('repairSetting.repairWayPlaceholder')" style="width:100%"> | ||
| 27 | + <el-option :label="$t('repairSetting.grabOrder')" value="100" /> | ||
| 28 | + <el-option :label="$t('repairSetting.assign')" value="200" /> | ||
| 29 | + <el-option :label="$t('repairSetting.polling')" value="300" /> | ||
| 30 | + </el-select> | ||
| 31 | + </el-form-item> | ||
| 32 | + </el-col> | ||
| 33 | + <el-col :span="12"> | ||
| 34 | + <el-form-item :label="$t('repairSetting.publicArea')" prop="publicArea"> | ||
| 35 | + <el-select v-model="formData.publicArea" | ||
| 36 | + :placeholder="$t('repairSetting.required') + $t('repairSetting.publicAreaPlaceholder')" style="width:100%"> | ||
| 37 | + <el-option :label="$t('repairSetting.nonHouse')" value="T" /> | ||
| 38 | + <el-option :label="$t('repairSetting.house')" value="F" /> | ||
| 39 | + </el-select> | ||
| 40 | + </el-form-item> | ||
| 41 | + </el-col> | ||
| 42 | + </el-row> | ||
| 43 | + | ||
| 44 | + <el-row> | ||
| 45 | + <el-col :span="12"> | ||
| 46 | + <el-form-item :label="$t('repairSetting.ownerDisplay')" prop="isShow"> | ||
| 47 | + <el-select v-model="formData.isShow" :placeholder="$t('repairSetting.ownerDisplayPlaceholder')" | ||
| 48 | + style="width:100%"> | ||
| 49 | + <el-option :label="$t('repairSetting.yes')" value="Y" /> | ||
| 50 | + <el-option :label="$t('repairSetting.no')" value="N" /> | ||
| 51 | + </el-select> | ||
| 52 | + </el-form-item> | ||
| 53 | + </el-col> | ||
| 54 | + <el-col :span="12"> | ||
| 55 | + <el-form-item :label="$t('repairSetting.notificationMethod')" prop="notifyWay"> | ||
| 56 | + <el-select v-model="formData.notifyWay" :placeholder="$t('repairSetting.notificationMethodPlaceholder')" | ||
| 57 | + style="width:100%"> | ||
| 58 | + <el-option :label="$t('repairSetting.sms')" value="SMS" /> | ||
| 59 | + <el-option :label="$t('repairSetting.wechat')" value="WECHAT" /> | ||
| 60 | + <el-option :label="$t('repairSetting.wechatWorkLicense')" value="WORK_LICENSE" /> | ||
| 61 | + </el-select> | ||
| 62 | + </el-form-item> | ||
| 63 | + </el-col> | ||
| 64 | + </el-row> | ||
| 65 | + | ||
| 66 | + <el-row> | ||
| 67 | + <el-col :span="12"> | ||
| 68 | + <el-form-item :label="$t('repairSetting.processingTime')" prop="doTime"> | ||
| 69 | + <el-input v-model.number="formData.doTime" type="number" | ||
| 70 | + :placeholder="$t('repairSetting.required') + $t('repairSetting.processingTimePlaceholder')"> | ||
| 71 | + <template slot="append">{{ $t('repairSetting.processingTimeUnit') }}</template> | ||
| 72 | + </el-input> | ||
| 73 | + </el-form-item> | ||
| 74 | + </el-col> | ||
| 75 | + <el-col :span="12"> | ||
| 76 | + <el-form-item :label="$t('repairSetting.timeoutWarning')" prop="warningTime"> | ||
| 77 | + <el-input v-model.number="formData.warningTime" type="number" | ||
| 78 | + :placeholder="$t('repairSetting.required') + $t('repairSetting.timeoutWarningPlaceholder')"> | ||
| 79 | + <template slot="append">{{ $t('repairSetting.timeoutWarningUnit') }}</template> | ||
| 80 | + </el-input> | ||
| 81 | + </el-form-item> | ||
| 82 | + </el-col> | ||
| 83 | + </el-row> | ||
| 84 | + | ||
| 85 | + <el-row> | ||
| 86 | + <el-col :span="12"> | ||
| 87 | + <el-form-item :label="$t('repairSetting.returnVisitSetting')" prop="returnVisitFlag"> | ||
| 88 | + <el-select v-model="formData.returnVisitFlag" | ||
| 89 | + :placeholder="$t('repairSetting.required') + $t('repairSetting.returnVisitFlagPlaceholder')" | ||
| 90 | + style="width:100%"> | ||
| 91 | + <el-option :label="$t('repairSetting.noFollowUp')" value="001" /> | ||
| 92 | + <el-option :label="$t('repairSetting.followUpAfterEvaluation')" value="002" /> | ||
| 93 | + <el-option :label="$t('repairSetting.followUp')" value="003" /> | ||
| 94 | + </el-select> | ||
| 95 | + </el-form-item> | ||
| 96 | + </el-col> | ||
| 97 | + </el-row> | ||
| 98 | + | ||
| 99 | + <el-row> | ||
| 100 | + <el-col :span="24"> | ||
| 101 | + <el-form-item :label="$t('repairSetting.explanation')" prop="remark"> | ||
| 102 | + <el-input v-model="formData.remark" type="textarea" :rows="3" | ||
| 103 | + :placeholder="$t('repairSetting.remarkPlaceholder')" /> | ||
| 104 | + </el-form-item> | ||
| 105 | + </el-col> | ||
| 106 | + </el-row> | ||
| 107 | + </el-form> | ||
| 108 | + | ||
| 109 | + <div slot="footer" class="dialog-footer"> | ||
| 110 | + <el-button @click="closeDialog">{{ $t('repairSetting.cancel') }}</el-button> | ||
| 111 | + <el-button type="primary" @click="submitForm">{{ $t('repairSetting.save') }}</el-button> | ||
| 112 | + </div> | ||
| 113 | + </el-dialog> | ||
| 114 | +</template> | ||
| 115 | + | ||
| 116 | +<script> | ||
| 117 | +import { saveRepairSetting } from '@/api/work/repairSettingApi' | ||
| 118 | + | ||
| 119 | +export default { | ||
| 120 | + name: 'AddRepairSetting', | ||
| 121 | + data() { | ||
| 122 | + return { | ||
| 123 | + visible: false, | ||
| 124 | + formData: { | ||
| 125 | + repairTypeName: '', | ||
| 126 | + repairWay: '200', | ||
| 127 | + repairSettingType: '200', | ||
| 128 | + remark: '', | ||
| 129 | + publicArea: 'F', | ||
| 130 | + payFeeFlag: 'F', | ||
| 131 | + returnVisitFlag: '003', | ||
| 132 | + isShow: 'Y', | ||
| 133 | + doTime: 24, | ||
| 134 | + warningTime: 30, | ||
| 135 | + notifyWay: 'WECHAT' | ||
| 136 | + }, | ||
| 137 | + rules: { | ||
| 138 | + repairTypeName: [ | ||
| 139 | + { required: true, message: this.$t('repairSetting.typeNamePlaceholder'), trigger: 'blur' }, | ||
| 140 | + { max: 200, message: this.$t('repairSetting.typeNameMaxLength'), trigger: 'blur' } | ||
| 141 | + ], | ||
| 142 | + repairSettingType: [ | ||
| 143 | + { required: true, message: this.$t('repairSetting.settingTypeRequired'), trigger: 'change' } | ||
| 144 | + ], | ||
| 145 | + repairWay: [ | ||
| 146 | + { required: true, message: this.$t('repairSetting.dispatchMethodRequired'), trigger: 'change' } | ||
| 147 | + ], | ||
| 148 | + publicArea: [ | ||
| 149 | + { required: true, message: this.$t('repairSetting.publicAreaRequired'), trigger: 'change' } | ||
| 150 | + ], | ||
| 151 | + isShow: [ | ||
| 152 | + { required: true, message: this.$t('repairSetting.ownerDisplayRequired'), trigger: 'change' } | ||
| 153 | + ], | ||
| 154 | + notifyWay: [ | ||
| 155 | + { required: true, message: this.$t('repairSetting.notificationMethodRequired'), trigger: 'change' } | ||
| 156 | + ], | ||
| 157 | + returnVisitFlag: [ | ||
| 158 | + { required: true, message: this.$t('repairSetting.returnVisitRequired'), trigger: 'change' } | ||
| 159 | + ], | ||
| 160 | + doTime: [ | ||
| 161 | + { required: true, message: this.$t('repairSetting.processingTimeRequired'), trigger: 'blur' }, | ||
| 162 | + { type: 'number', min: 1, message: this.$t('repairSetting.processingTimeMin'), trigger: 'blur' } | ||
| 163 | + ], | ||
| 164 | + warningTime: [ | ||
| 165 | + { required: true, message: this.$t('repairSetting.timeoutWarningRequired'), trigger: 'blur' }, | ||
| 166 | + { type: 'number', min: 1, message: this.$t('repairSetting.timeoutWarningMin'), trigger: 'blur' } | ||
| 167 | + ], | ||
| 168 | + remark: [ | ||
| 169 | + { max: 500, message: this.$t('repairSetting.remarkMaxLength'), trigger: 'blur' } | ||
| 170 | + ] | ||
| 171 | + } | ||
| 172 | + } | ||
| 173 | + }, | ||
| 174 | + methods: { | ||
| 175 | + open() { | ||
| 176 | + this.visible = true | ||
| 177 | + }, | ||
| 178 | + | ||
| 179 | + closeDialog() { | ||
| 180 | + this.visible = false | ||
| 181 | + this.resetForm() | ||
| 182 | + }, | ||
| 183 | + | ||
| 184 | + resetForm() { | ||
| 185 | + this.$refs.form.resetFields() | ||
| 186 | + this.formData = { | ||
| 187 | + repairTypeName: '', | ||
| 188 | + repairWay: '200', | ||
| 189 | + repairSettingType: '200', | ||
| 190 | + remark: '', | ||
| 191 | + publicArea: 'F', | ||
| 192 | + payFeeFlag: 'F', | ||
| 193 | + returnVisitFlag: '003', | ||
| 194 | + isShow: 'Y', | ||
| 195 | + doTime: 24, | ||
| 196 | + warningTime: 30, | ||
| 197 | + notifyWay: 'WECHAT' | ||
| 198 | + } | ||
| 199 | + }, | ||
| 200 | + | ||
| 201 | + submitForm() { | ||
| 202 | + this.$refs.form.validate(async valid => { | ||
| 203 | + if (valid) { | ||
| 204 | + try { | ||
| 205 | + await saveRepairSetting(this.formData) | ||
| 206 | + this.$message.success(this.$t('repairSetting.addSuccess')) | ||
| 207 | + this.$emit('success') | ||
| 208 | + this.closeDialog() | ||
| 209 | + } catch (error) { | ||
| 210 | + console.error('添加报修设置失败:', error) | ||
| 211 | + this.$message.error(this.$t('repairSetting.addFailed')) | ||
| 212 | + } | ||
| 213 | + } | ||
| 214 | + }) | ||
| 215 | + } | ||
| 216 | + } | ||
| 217 | +} | ||
| 218 | +</script> | ||
| 0 | \ No newline at end of file | 219 | \ No newline at end of file |
src/components/work/DeleteRepairSetting.vue
0 → 100644
| 1 | +<template> | ||
| 2 | + <el-dialog | ||
| 3 | + :title="$t('repairSetting.confirmDeleteTitle')" | ||
| 4 | + :visible.sync="visible" | ||
| 5 | + width="30%" | ||
| 6 | + center | ||
| 7 | + > | ||
| 8 | + <div style="text-align: center"> | ||
| 9 | + <p>{{ $t('repairSetting.confirmDeleteContent') }} [{{ currentRow.repairTypeName }}]?</p> | ||
| 10 | + </div> | ||
| 11 | + <div slot="footer" class="dialog-footer"> | ||
| 12 | + <el-button @click="closeDialog">{{ $t('repairSetting.cancelDelete') }}</el-button> | ||
| 13 | + <el-button type="danger" @click="confirmDelete">{{ $t('repairSetting.confirmDelete') }}</el-button> | ||
| 14 | + </div> | ||
| 15 | + </el-dialog> | ||
| 16 | +</template> | ||
| 17 | + | ||
| 18 | +<script> | ||
| 19 | +import { deleteRepairSetting } from '@/api/work/repairSettingApi' | ||
| 20 | + | ||
| 21 | +export default { | ||
| 22 | + name: 'DeleteRepairSetting', | ||
| 23 | + data() { | ||
| 24 | + return { | ||
| 25 | + visible: false, | ||
| 26 | + currentRow: {} | ||
| 27 | + } | ||
| 28 | + }, | ||
| 29 | + methods: { | ||
| 30 | + open(row) { | ||
| 31 | + this.currentRow = { ...row } | ||
| 32 | + this.visible = true | ||
| 33 | + }, | ||
| 34 | + | ||
| 35 | + closeDialog() { | ||
| 36 | + this.visible = false | ||
| 37 | + this.currentRow = {} | ||
| 38 | + }, | ||
| 39 | + | ||
| 40 | + async confirmDelete() { | ||
| 41 | + try { | ||
| 42 | + await deleteRepairSetting(this.currentRow.settingId) | ||
| 43 | + this.$message.success(this.$t('repairSetting.deleteSuccess')) | ||
| 44 | + this.$emit('success') | ||
| 45 | + this.closeDialog() | ||
| 46 | + } catch (error) { | ||
| 47 | + console.error('删除报修设置失败:', error) | ||
| 48 | + this.$message.error(this.$t('repairSetting.deleteFailed')) | ||
| 49 | + } | ||
| 50 | + } | ||
| 51 | + } | ||
| 52 | +} | ||
| 53 | +</script> | ||
| 0 | \ No newline at end of file | 54 | \ No newline at end of file |
src/components/work/DeleteRepairTypeUser.vue
0 → 100644
| 1 | +<template> | ||
| 2 | + <el-dialog | ||
| 3 | + :visible="visible" | ||
| 4 | + :title="$t('deleteRepairTypeUser.title')" | ||
| 5 | + width="30%" | ||
| 6 | + @close="handleClose" | ||
| 7 | + > | ||
| 8 | + <div class="text-center"> | ||
| 9 | + <p>{{ $t('deleteRepairTypeUser.confirmDelete') }}</p> | ||
| 10 | + </div> | ||
| 11 | + <div slot="footer" class="dialog-footer"> | ||
| 12 | + <el-button @click="handleClose">{{ $t('common.cancel') }}</el-button> | ||
| 13 | + <el-button type="danger" @click="confirmDelete">{{ $t('common.confirmDelete') }}</el-button> | ||
| 14 | + </div> | ||
| 15 | + </el-dialog> | ||
| 16 | +</template> | ||
| 17 | + | ||
| 18 | +<script> | ||
| 19 | +import { deleteRepairTypeUser } from '@/api/work/repairTypeUserApi' | ||
| 20 | +import { getCommunityId } from '@/api/community/communityApi' | ||
| 21 | + | ||
| 22 | +export default { | ||
| 23 | + name: 'DeleteRepairTypeUser', | ||
| 24 | + data() { | ||
| 25 | + return { | ||
| 26 | + visible: false, | ||
| 27 | + repairTypeUser: {} | ||
| 28 | + } | ||
| 29 | + }, | ||
| 30 | + methods: { | ||
| 31 | + open(repairTypeUser) { | ||
| 32 | + this.repairTypeUser = repairTypeUser | ||
| 33 | + this.visible = true | ||
| 34 | + }, | ||
| 35 | + handleClose() { | ||
| 36 | + this.visible = false | ||
| 37 | + this.repairTypeUser = {} | ||
| 38 | + }, | ||
| 39 | + async confirmDelete() { | ||
| 40 | + try { | ||
| 41 | + const communityId = await getCommunityId() | ||
| 42 | + const data = { | ||
| 43 | + communityId: communityId, | ||
| 44 | + typeUserId: this.repairTypeUser.typeUserId | ||
| 45 | + } | ||
| 46 | + | ||
| 47 | + const response = await deleteRepairTypeUser(data) | ||
| 48 | + if (response.code === 0) { | ||
| 49 | + this.$message.success(this.$t('common.deleteSuccess')) | ||
| 50 | + this.$emit('success') | ||
| 51 | + this.handleClose() | ||
| 52 | + } else { | ||
| 53 | + this.$message.error(response.msg || this.$t('common.deleteFailed')) | ||
| 54 | + } | ||
| 55 | + } catch (error) { | ||
| 56 | + console.error('Error deleting repair type user:', error) | ||
| 57 | + this.$message.error(this.$t('common.deleteFailed')) | ||
| 58 | + } | ||
| 59 | + } | ||
| 60 | + } | ||
| 61 | +} | ||
| 62 | +</script> | ||
| 0 | \ No newline at end of file | 63 | \ No newline at end of file |
src/components/work/EditRepairSetting.vue
0 → 100644
| 1 | +<template> | ||
| 2 | + <el-dialog | ||
| 3 | + :title="$t('repairSetting.editTitle')" | ||
| 4 | + :visible.sync="visible" | ||
| 5 | + width="50%" | ||
| 6 | + @close="closeDialog" | ||
| 7 | + > | ||
| 8 | + <el-form ref="form" :model="formData" :rules="rules" label-width="150px"> | ||
| 9 | + <el-row> | ||
| 10 | + <el-col :span="12"> | ||
| 11 | + <el-form-item :label="$t('repairSetting.typeName')" prop="repairTypeName"> | ||
| 12 | + <el-input | ||
| 13 | + v-model="formData.repairTypeName" | ||
| 14 | + :placeholder="$t('repairSetting.repairTypeNamePlaceholder')" | ||
| 15 | + /> | ||
| 16 | + </el-form-item> | ||
| 17 | + </el-col> | ||
| 18 | + <el-col :span="12"> | ||
| 19 | + <el-form-item :label="$t('repairSetting.settingType')" prop="repairSettingType"> | ||
| 20 | + <el-select | ||
| 21 | + v-model="formData.repairSettingType" | ||
| 22 | + :placeholder="$t('repairSetting.required') + $t('repairSetting.repairSettingTypePlaceholder')" | ||
| 23 | + style="width:100%" | ||
| 24 | + > | ||
| 25 | + <el-option :label="$t('repairSetting.cleaningOrder')" value="100" /> | ||
| 26 | + <el-option :label="$t('repairSetting.repairOrder')" value="200" /> | ||
| 27 | + </el-select> | ||
| 28 | + </el-form-item> | ||
| 29 | + </el-col> | ||
| 30 | + </el-row> | ||
| 31 | + | ||
| 32 | + <el-row> | ||
| 33 | + <el-col :span="12"> | ||
| 34 | + <el-form-item :label="$t('repairSetting.dispatchMethod')" prop="repairWay"> | ||
| 35 | + <el-select | ||
| 36 | + v-model="formData.repairWay" | ||
| 37 | + :placeholder="$t('repairSetting.required') + $t('repairSetting.repairWayPlaceholder')" | ||
| 38 | + style="width:100%" | ||
| 39 | + > | ||
| 40 | + <el-option :label="$t('repairSetting.grabOrder')" value="100" /> | ||
| 41 | + <el-option :label="$t('repairSetting.assign')" value="200" /> | ||
| 42 | + <el-option :label="$t('repairSetting.polling')" value="300" /> | ||
| 43 | + </el-select> | ||
| 44 | + </el-form-item> | ||
| 45 | + </el-col> | ||
| 46 | + <el-col :span="12"> | ||
| 47 | + <el-form-item :label="$t('repairSetting.publicArea')" prop="publicArea"> | ||
| 48 | + <el-select | ||
| 49 | + v-model="formData.publicArea" | ||
| 50 | + :placeholder="$t('repairSetting.required') + $t('repairSetting.publicAreaPlaceholder')" | ||
| 51 | + style="width:100%" | ||
| 52 | + > | ||
| 53 | + <el-option :label="$t('repairSetting.nonHouse')" value="T" /> | ||
| 54 | + <el-option :label="$t('repairSetting.house')" value="F" /> | ||
| 55 | + </el-select> | ||
| 56 | + </el-form-item> | ||
| 57 | + </el-col> | ||
| 58 | + </el-row> | ||
| 59 | + | ||
| 60 | + <el-row> | ||
| 61 | + <el-col :span="12"> | ||
| 62 | + <el-form-item :label="$t('repairSetting.ownerDisplay')" prop="isShow"> | ||
| 63 | + <el-select | ||
| 64 | + v-model="formData.isShow" | ||
| 65 | + :placeholder="$t('repairSetting.ownerDisplayPlaceholder')" | ||
| 66 | + style="width:100%" | ||
| 67 | + > | ||
| 68 | + <el-option :label="$t('repairSetting.yes')" value="Y" /> | ||
| 69 | + <el-option :label="$t('repairSetting.no')" value="N" /> | ||
| 70 | + </el-select> | ||
| 71 | + </el-form-item> | ||
| 72 | + </el-col> | ||
| 73 | + <el-col :span="12"> | ||
| 74 | + <el-form-item :label="$t('repairSetting.notificationMethod')" prop="notifyWay"> | ||
| 75 | + <el-select | ||
| 76 | + v-model="formData.notifyWay" | ||
| 77 | + :placeholder="$t('repairSetting.notificationMethodPlaceholder')" | ||
| 78 | + style="width:100%" | ||
| 79 | + > | ||
| 80 | + <el-option :label="$t('repairSetting.sms')" value="SMS" /> | ||
| 81 | + <el-option :label="$t('repairSetting.wechat')" value="WECHAT" /> | ||
| 82 | + <el-option :label="$t('repairSetting.wechatWorkLicense')" value="WORK_LICENSE" /> | ||
| 83 | + </el-select> | ||
| 84 | + </el-form-item> | ||
| 85 | + </el-col> | ||
| 86 | + </el-row> | ||
| 87 | + | ||
| 88 | + <el-row> | ||
| 89 | + <el-col :span="12"> | ||
| 90 | + <el-form-item :label="$t('repairSetting.processingTime')" prop="doTime"> | ||
| 91 | + <el-input | ||
| 92 | + v-model.number="formData.doTime" | ||
| 93 | + type="number" | ||
| 94 | + :placeholder="$t('repairSetting.required') + $t('repairSetting.processingTimePlaceholder')" | ||
| 95 | + > | ||
| 96 | + <template slot="append">{{ $t('repairSetting.processingTimeUnit') }}</template> | ||
| 97 | + </el-input> | ||
| 98 | + </el-form-item> | ||
| 99 | + </el-col> | ||
| 100 | + <el-col :span="12"> | ||
| 101 | + <el-form-item :label="$t('repairSetting.timeoutWarning')" prop="warningTime"> | ||
| 102 | + <el-input | ||
| 103 | + v-model.number="formData.warningTime" | ||
| 104 | + type="number" | ||
| 105 | + :placeholder="$t('repairSetting.required') + $t('repairSetting.timeoutWarningPlaceholder')" | ||
| 106 | + > | ||
| 107 | + <template slot="append">{{ $t('repairSetting.timeoutWarningUnit') }}</template> | ||
| 108 | + </el-input> | ||
| 109 | + </el-form-item> | ||
| 110 | + </el-col> | ||
| 111 | + </el-row> | ||
| 112 | + | ||
| 113 | + <el-row> | ||
| 114 | + <el-col :span="12"> | ||
| 115 | + <el-form-item :label="$t('repairSetting.returnVisitSetting')" prop="returnVisitFlag"> | ||
| 116 | + <el-select | ||
| 117 | + v-model="formData.returnVisitFlag" | ||
| 118 | + :placeholder="$t('repairSetting.required') + $t('repairSetting.returnVisitFlagPlaceholder')" | ||
| 119 | + style="width:100%" | ||
| 120 | + > | ||
| 121 | + <el-option :label="$t('repairSetting.noFollowUp')" value="001" /> | ||
| 122 | + <el-option :label="$t('repairSetting.followUpAfterEvaluation')" value="002" /> | ||
| 123 | + <el-option :label="$t('repairSetting.followUp')" value="003" /> | ||
| 124 | + </el-select> | ||
| 125 | + </el-form-item> | ||
| 126 | + </el-col> | ||
| 127 | + </el-row> | ||
| 128 | + | ||
| 129 | + <el-row> | ||
| 130 | + <el-col :span="24"> | ||
| 131 | + <el-form-item :label="$t('repairSetting.explanation')" prop="remark"> | ||
| 132 | + <el-input | ||
| 133 | + v-model="formData.remark" | ||
| 134 | + type="textarea" | ||
| 135 | + :rows="3" | ||
| 136 | + :placeholder="$t('repairSetting.remarkPlaceholder')" | ||
| 137 | + /> | ||
| 138 | + </el-form-item> | ||
| 139 | + </el-col> | ||
| 140 | + </el-row> | ||
| 141 | + </el-form> | ||
| 142 | + | ||
| 143 | + <div slot="footer" class="dialog-footer"> | ||
| 144 | + <el-button @click="closeDialog">{{ $t('repairSetting.cancel') }}</el-button> | ||
| 145 | + <el-button type="primary" @click="submitForm">{{ $t('repairSetting.save') }}</el-button> | ||
| 146 | + </div> | ||
| 147 | + </el-dialog> | ||
| 148 | +</template> | ||
| 149 | + | ||
| 150 | +<script> | ||
| 151 | +import { updateRepairSetting } from '@/api/work/repairSettingApi' | ||
| 152 | + | ||
| 153 | +export default { | ||
| 154 | + name: 'EditRepairSetting', | ||
| 155 | + data() { | ||
| 156 | + return { | ||
| 157 | + visible: false, | ||
| 158 | + formData: { | ||
| 159 | + settingId: '', | ||
| 160 | + repairTypeName: '', | ||
| 161 | + repairWay: '', | ||
| 162 | + repairSettingType: '', | ||
| 163 | + remark: '', | ||
| 164 | + publicArea: '', | ||
| 165 | + returnVisitFlag: '', | ||
| 166 | + isShow: '', | ||
| 167 | + doTime: 24, | ||
| 168 | + warningTime: 30, | ||
| 169 | + notifyWay: '' | ||
| 170 | + }, | ||
| 171 | + rules: { | ||
| 172 | + repairTypeName: [ | ||
| 173 | + { required: true, message: this.$t('repairSetting.typeNamePlaceholder'), trigger: 'blur' }, | ||
| 174 | + { max: 200, message: this.$t('repairSetting.typeNameMaxLength'), trigger: 'blur' } | ||
| 175 | + ], | ||
| 176 | + repairSettingType: [ | ||
| 177 | + { required: true, message: this.$t('repairSetting.settingTypeRequired'), trigger: 'change' } | ||
| 178 | + ], | ||
| 179 | + repairWay: [ | ||
| 180 | + { required: true, message: this.$t('repairSetting.dispatchMethodRequired'), trigger: 'change' } | ||
| 181 | + ], | ||
| 182 | + publicArea: [ | ||
| 183 | + { required: true, message: this.$t('repairSetting.publicAreaRequired'), trigger: 'change' } | ||
| 184 | + ], | ||
| 185 | + isShow: [ | ||
| 186 | + { required: true, message: this.$t('repairSetting.ownerDisplayRequired'), trigger: 'change' } | ||
| 187 | + ], | ||
| 188 | + notifyWay: [ | ||
| 189 | + { required: true, message: this.$t('repairSetting.notificationMethodRequired'), trigger: 'change' } | ||
| 190 | + ], | ||
| 191 | + returnVisitFlag: [ | ||
| 192 | + { required: true, message: this.$t('repairSetting.returnVisitRequired'), trigger: 'change' } | ||
| 193 | + ], | ||
| 194 | + doTime: [ | ||
| 195 | + { required: true, message: this.$t('repairSetting.processingTimeRequired'), trigger: 'blur' }, | ||
| 196 | + { type: 'number', min: 1, message: this.$t('repairSetting.processingTimeMin'), trigger: 'blur' } | ||
| 197 | + ], | ||
| 198 | + warningTime: [ | ||
| 199 | + { required: true, message: this.$t('repairSetting.timeoutWarningRequired'), trigger: 'blur' }, | ||
| 200 | + { type: 'number', min: 1, message: this.$t('repairSetting.timeoutWarningMin'), trigger: 'blur' } | ||
| 201 | + ], | ||
| 202 | + remark: [ | ||
| 203 | + { max: 500, message: this.$t('repairSetting.remarkMaxLength'), trigger: 'blur' } | ||
| 204 | + ], | ||
| 205 | + settingId: [ | ||
| 206 | + { required: true, message: this.$t('repairSetting.settingIdRequired'), trigger: 'blur' } | ||
| 207 | + ] | ||
| 208 | + } | ||
| 209 | + } | ||
| 210 | + }, | ||
| 211 | + methods: { | ||
| 212 | + open(row) { | ||
| 213 | + this.formData = { ...row } | ||
| 214 | + this.visible = true | ||
| 215 | + }, | ||
| 216 | + | ||
| 217 | + closeDialog() { | ||
| 218 | + this.visible = false | ||
| 219 | + this.$refs.form.resetFields() | ||
| 220 | + }, | ||
| 221 | + | ||
| 222 | + submitForm() { | ||
| 223 | + this.$refs.form.validate(async valid => { | ||
| 224 | + if (valid) { | ||
| 225 | + try { | ||
| 226 | + await updateRepairSetting(this.formData) | ||
| 227 | + this.$message.success(this.$t('repairSetting.updateSuccess')) | ||
| 228 | + this.$emit('success') | ||
| 229 | + this.closeDialog() | ||
| 230 | + } catch (error) { | ||
| 231 | + console.error('更新报修设置失败:', error) | ||
| 232 | + this.$message.error(this.$t('repairSetting.updateFailed')) | ||
| 233 | + } | ||
| 234 | + } | ||
| 235 | + }) | ||
| 236 | + } | ||
| 237 | + } | ||
| 238 | +} | ||
| 239 | +</script> | ||
| 0 | \ No newline at end of file | 240 | \ No newline at end of file |
src/components/work/EditRepairTypeUser.vue
0 → 100644
| 1 | +<template> | ||
| 2 | + <el-dialog | ||
| 3 | + :visible="visible" | ||
| 4 | + :title="$t('editRepairTypeUser.title')" | ||
| 5 | + width="50%" | ||
| 6 | + @close="handleClose" | ||
| 7 | + > | ||
| 8 | + <el-form ref="form" :model="form" label-width="120px"> | ||
| 9 | + <el-form-item :label="$t('editRepairTypeUser.status')" prop="state" required> | ||
| 10 | + <el-select v-model="form.state" style="width: 100%"> | ||
| 11 | + <el-option :value="9999" :label="$t('editRepairTypeUser.online')"></el-option> | ||
| 12 | + <el-option :value="8888" :label="$t('editRepairTypeUser.offline')"></el-option> | ||
| 13 | + </el-select> | ||
| 14 | + </el-form-item> | ||
| 15 | + <el-form-item :label="$t('editRepairTypeUser.description')" prop="remark"> | ||
| 16 | + <el-input v-model="form.remark" :placeholder="$t('editRepairTypeUser.descriptionPlaceholder')"></el-input> | ||
| 17 | + </el-form-item> | ||
| 18 | + </el-form> | ||
| 19 | + <div slot="footer" class="dialog-footer"> | ||
| 20 | + <el-button @click="handleClose">{{ $t('common.cancel') }}</el-button> | ||
| 21 | + <el-button type="primary" @click="saveChanges">{{ $t('common.save') }}</el-button> | ||
| 22 | + </div> | ||
| 23 | + </el-dialog> | ||
| 24 | +</template> | ||
| 25 | + | ||
| 26 | +<script> | ||
| 27 | +import { updateRepairTypeUser } from '@/api/work/repairTypeUserApi' | ||
| 28 | +import { getCommunityId } from '@/api/community/communityApi' | ||
| 29 | + | ||
| 30 | +export default { | ||
| 31 | + name: 'EditRepairTypeUser', | ||
| 32 | + data() { | ||
| 33 | + return { | ||
| 34 | + visible: false, | ||
| 35 | + form: { | ||
| 36 | + typeUserId: '', | ||
| 37 | + state: '', | ||
| 38 | + remark: '' | ||
| 39 | + } | ||
| 40 | + } | ||
| 41 | + }, | ||
| 42 | + methods: { | ||
| 43 | + open(repairTypeUser) { | ||
| 44 | + this.form = { | ||
| 45 | + typeUserId: repairTypeUser.typeUserId, | ||
| 46 | + state: repairTypeUser.state, | ||
| 47 | + remark: repairTypeUser.remark | ||
| 48 | + } | ||
| 49 | + this.visible = true | ||
| 50 | + }, | ||
| 51 | + handleClose() { | ||
| 52 | + this.visible = false | ||
| 53 | + this.form = { | ||
| 54 | + typeUserId: '', | ||
| 55 | + state: '', | ||
| 56 | + remark: '' | ||
| 57 | + } | ||
| 58 | + }, | ||
| 59 | + async saveChanges() { | ||
| 60 | + try { | ||
| 61 | + if (!this.form.state) { | ||
| 62 | + this.$message.warning(this.$t('editRepairTypeUser.statusRequired')) | ||
| 63 | + return | ||
| 64 | + } | ||
| 65 | + | ||
| 66 | + const communityId = await getCommunityId() | ||
| 67 | + const data = { | ||
| 68 | + ...this.form, | ||
| 69 | + communityId: communityId | ||
| 70 | + } | ||
| 71 | + | ||
| 72 | + const response = await updateRepairTypeUser(data) | ||
| 73 | + if (response.code === 0) { | ||
| 74 | + this.$message.success(this.$t('common.saveSuccess')) | ||
| 75 | + this.$emit('success') | ||
| 76 | + this.handleClose() | ||
| 77 | + } else { | ||
| 78 | + this.$message.error(response.msg || this.$t('common.saveFailed')) | ||
| 79 | + } | ||
| 80 | + } catch (error) { | ||
| 81 | + console.error('Error updating repair type user:', error) | ||
| 82 | + this.$message.error(this.$t('common.saveFailed')) | ||
| 83 | + } | ||
| 84 | + } | ||
| 85 | + } | ||
| 86 | +} | ||
| 87 | +</script> | ||
| 0 | \ No newline at end of file | 88 | \ No newline at end of file |
src/components/work/OrgTreeShow.vue
0 → 100644
| 1 | +<template> | ||
| 2 | + <div> | ||
| 3 | + <el-tree | ||
| 4 | + ref="orgTree" | ||
| 5 | + :data="orgs" | ||
| 6 | + node-key="id" | ||
| 7 | + :props="defaultProps" | ||
| 8 | + default-expand-all | ||
| 9 | + :expand-on-click-node="false" | ||
| 10 | + @node-click="handleNodeClick" | ||
| 11 | + ></el-tree> | ||
| 12 | + </div> | ||
| 13 | +</template> | ||
| 14 | + | ||
| 15 | +<script> | ||
| 16 | +import { listOrgTree } from '@/api/work/repairTypeUserApi' | ||
| 17 | +import { getCommunityId } from '@/api/community/communityApi' | ||
| 18 | + | ||
| 19 | +export default { | ||
| 20 | + name: 'OrgTreeShow', | ||
| 21 | + data() { | ||
| 22 | + return { | ||
| 23 | + orgs: [], | ||
| 24 | + defaultProps: { | ||
| 25 | + children: 'children', | ||
| 26 | + label: 'text' | ||
| 27 | + } | ||
| 28 | + } | ||
| 29 | + }, | ||
| 30 | + methods: { | ||
| 31 | + async refreshTree() { | ||
| 32 | + try { | ||
| 33 | + const communityId = await getCommunityId() | ||
| 34 | + const params = { | ||
| 35 | + communityId: communityId | ||
| 36 | + } | ||
| 37 | + const response = await listOrgTree(params) | ||
| 38 | + if (response.code === 0) { | ||
| 39 | + this.orgs = response.data | ||
| 40 | + } else { | ||
| 41 | + this.$message.error(response.msg || this.$t('common.requestFailed')) | ||
| 42 | + } | ||
| 43 | + } catch (error) { | ||
| 44 | + console.error('Error loading org tree:', error) | ||
| 45 | + this.$message.error(this.$t('common.requestFailed')) | ||
| 46 | + } | ||
| 47 | + }, | ||
| 48 | + handleNodeClick(data) { | ||
| 49 | + this.$emit('org-selected', { | ||
| 50 | + orgId: data.id, | ||
| 51 | + orgName: data.text | ||
| 52 | + }) | ||
| 53 | + } | ||
| 54 | + }, | ||
| 55 | + mounted() { | ||
| 56 | + this.refreshTree() | ||
| 57 | + } | ||
| 58 | +} | ||
| 59 | +</script> | ||
| 0 | \ No newline at end of file | 60 | \ No newline at end of file |
src/components/work/SelectStaff.vue
0 → 100644
| 1 | +<template> | ||
| 2 | + <el-dialog | ||
| 3 | + :visible="visible" | ||
| 4 | + :title="$t('selectStaff.title')" | ||
| 5 | + width="80%" | ||
| 6 | + @close="handleClose" | ||
| 7 | + > | ||
| 8 | + <el-row :gutter="20"> | ||
| 9 | + <el-col :span="12" class="border-right"> | ||
| 10 | + <div class="text-center"> | ||
| 11 | + <h4>{{ $t('selectStaff.orgInfo') }}</h4> | ||
| 12 | + </div> | ||
| 13 | + <div class="staff padding"> | ||
| 14 | + <OrgTreeShow ref="orgTree" @org-selected="handleOrgSelected" /> | ||
| 15 | + </div> | ||
| 16 | + </el-col> | ||
| 17 | + <el-col :span="12"> | ||
| 18 | + <div class="text-center"> | ||
| 19 | + <h4>{{ $t('selectStaff.staffInfo') }}</h4> | ||
| 20 | + </div> | ||
| 21 | + <div class="padding-left staff padding padding-top-xs"> | ||
| 22 | + <div | ||
| 23 | + v-for="(item, index) in staffs" | ||
| 24 | + :key="index" | ||
| 25 | + class="staff-item" | ||
| 26 | + :class="{'selected': curStaffId === item.staffId}" | ||
| 27 | + @click="selectStaff(item)" | ||
| 28 | + > | ||
| 29 | + <div> | ||
| 30 | + <i class="el-icon-user margin-right-xs"></i> | ||
| 31 | + {{ item.name }} | ||
| 32 | + </div> | ||
| 33 | + <div>{{ item.tel }}</div> | ||
| 34 | + </div> | ||
| 35 | + </div> | ||
| 36 | + </el-col> | ||
| 37 | + </el-row> | ||
| 38 | + <div slot="footer" class="dialog-footer"> | ||
| 39 | + <el-button @click="handleClose">{{ $t('common.cancel') }}</el-button> | ||
| 40 | + <el-button type="primary" @click="handleSubmit">{{ $t('common.confirm') }}</el-button> | ||
| 41 | + </div> | ||
| 42 | + </el-dialog> | ||
| 43 | +</template> | ||
| 44 | + | ||
| 45 | +<script> | ||
| 46 | +import OrgTreeShow from '@/components/work/OrgTreeShow' | ||
| 47 | +import { getStaffInfos } from '@/api/work/repairTypeUserApi' | ||
| 48 | + | ||
| 49 | +export default { | ||
| 50 | + name: 'SelectStaff', | ||
| 51 | + components: { | ||
| 52 | + OrgTreeShow | ||
| 53 | + }, | ||
| 54 | + data() { | ||
| 55 | + return { | ||
| 56 | + visible: false, | ||
| 57 | + staffs: [], | ||
| 58 | + curStaffId: '', | ||
| 59 | + selectedStaff: null, | ||
| 60 | + staffConfig: {}, | ||
| 61 | + currentOrgId: '' | ||
| 62 | + } | ||
| 63 | + }, | ||
| 64 | + methods: { | ||
| 65 | + open(staffConfig) { | ||
| 66 | + this.staffConfig = staffConfig || {} | ||
| 67 | + this.visible = true | ||
| 68 | + this.$nextTick(() => { | ||
| 69 | + this.$refs.orgTree.refreshTree() | ||
| 70 | + }) | ||
| 71 | + }, | ||
| 72 | + handleClose() { | ||
| 73 | + this.visible = false | ||
| 74 | + this.staffs = [] | ||
| 75 | + this.curStaffId = '' | ||
| 76 | + this.selectedStaff = null | ||
| 77 | + }, | ||
| 78 | + handleOrgSelected(org) { | ||
| 79 | + this.currentOrgId = org.orgId | ||
| 80 | + this.loadStaff(org.orgId) | ||
| 81 | + }, | ||
| 82 | + async loadStaff(orgId) { | ||
| 83 | + try { | ||
| 84 | + const params = { | ||
| 85 | + orgId: orgId, | ||
| 86 | + row: 50 | ||
| 87 | + } | ||
| 88 | + const response = await getStaffInfos(params) | ||
| 89 | + if (response.code === 0) { | ||
| 90 | + this.staffs = response.data | ||
| 91 | + if (this.staffs.length > 0) { | ||
| 92 | + this.curStaffId = this.staffs[0].staffId | ||
| 93 | + } | ||
| 94 | + } else { | ||
| 95 | + this.$message.error(response.msg || this.$t('common.requestFailed')) | ||
| 96 | + } | ||
| 97 | + } catch (error) { | ||
| 98 | + console.error('Error loading staff:', error) | ||
| 99 | + this.$message.error(this.$t('common.requestFailed')) | ||
| 100 | + } | ||
| 101 | + }, | ||
| 102 | + selectStaff(staff) { | ||
| 103 | + this.curStaffId = staff.staffId | ||
| 104 | + this.selectedStaff = staff | ||
| 105 | + }, | ||
| 106 | + handleSubmit() { | ||
| 107 | + if (this.selectedStaff) { | ||
| 108 | + if (this.staffConfig.call) { | ||
| 109 | + this.staffConfig.call({ | ||
| 110 | + staffId: this.selectedStaff.staffId, | ||
| 111 | + staffName: this.selectedStaff.name | ||
| 112 | + }) | ||
| 113 | + } | ||
| 114 | + this.handleClose() | ||
| 115 | + } else { | ||
| 116 | + this.$message.warning(this.$t('selectStaff.selectStaffFirst')) | ||
| 117 | + } | ||
| 118 | + } | ||
| 119 | + } | ||
| 120 | +} | ||
| 121 | +</script> | ||
| 122 | + | ||
| 123 | +<style scoped> | ||
| 124 | +.border-right { | ||
| 125 | + border-right: 1px solid #ebeef5; | ||
| 126 | +} | ||
| 127 | +.padding { | ||
| 128 | + padding: 15px; | ||
| 129 | +} | ||
| 130 | +.staff-item { | ||
| 131 | + padding: 10px; | ||
| 132 | + margin-bottom: 10px; | ||
| 133 | + border: 1px solid #ebeef5; | ||
| 134 | + border-radius: 4px; | ||
| 135 | + cursor: pointer; | ||
| 136 | +} | ||
| 137 | +.staff-item:hover { | ||
| 138 | + background-color: #f5f7fa; | ||
| 139 | +} | ||
| 140 | +.staff-item.selected { | ||
| 141 | + background-color: #ecf5ff; | ||
| 142 | + border-color: #409eff; | ||
| 143 | +} | ||
| 144 | +.text-center { | ||
| 145 | + text-align: center; | ||
| 146 | + margin-bottom: 15px; | ||
| 147 | +} | ||
| 148 | +</style> | ||
| 0 | \ No newline at end of file | 149 | \ No newline at end of file |
src/i18n/commonLang.js
| @@ -44,6 +44,7 @@ export const messages = { | @@ -44,6 +44,7 @@ export const messages = { | ||
| 44 | hour:'hour', | 44 | hour:'hour', |
| 45 | more:'More', | 45 | more:'More', |
| 46 | tip:'Tip', | 46 | tip:'Tip', |
| 47 | + selectFile:'Select File' | ||
| 47 | } | 48 | } |
| 48 | }, | 49 | }, |
| 49 | zh: { | 50 | zh: { |
| @@ -91,7 +92,7 @@ export const messages = { | @@ -91,7 +92,7 @@ export const messages = { | ||
| 91 | hour:'时', | 92 | hour:'时', |
| 92 | more:'更多', | 93 | more:'更多', |
| 93 | tip:'提示', | 94 | tip:'提示', |
| 94 | - | 95 | + selectFile:'选择文件' |
| 95 | } | 96 | } |
| 96 | } | 97 | } |
| 97 | } | 98 | } |
| 98 | \ No newline at end of file | 99 | \ No newline at end of file |
src/i18n/index.js
| @@ -158,6 +158,10 @@ import { messages as tempCarPaymentMessages } from '../views/car/tempCarPaymentL | @@ -158,6 +158,10 @@ import { messages as tempCarPaymentMessages } from '../views/car/tempCarPaymentL | ||
| 158 | import { messages as parkingSpaceApplyManageMessages } from '../views/car/parkingSpaceApplyManageLang' | 158 | import { messages as parkingSpaceApplyManageMessages } from '../views/car/parkingSpaceApplyManageLang' |
| 159 | import { messages as addParkingSpaceApplyMessages } from '../views/car/addParkingSpaceApplyLang' | 159 | import { messages as addParkingSpaceApplyMessages } from '../views/car/addParkingSpaceApplyLang' |
| 160 | import { messages as auditParkingSpaceApplyMessages } from '../views/car/auditParkingSpaceApplyLang' | 160 | import { messages as auditParkingSpaceApplyMessages } from '../views/car/auditParkingSpaceApplyLang' |
| 161 | +import { messages as carCreateFeeMessages } from '../views/fee/carCreateFeeLang' | ||
| 162 | +import { messages as listCarFeeMessages } from '../views/fee/listCarFeeLang' | ||
| 163 | +import { messages as repairSettingMessages } from '../views/work/repairSettingLang' | ||
| 164 | +import { messages as repairTypeUserMessages } from '../views/work/repairTypeUserLang' | ||
| 161 | 165 | ||
| 162 | Vue.use(VueI18n) | 166 | Vue.use(VueI18n) |
| 163 | 167 | ||
| @@ -320,6 +324,10 @@ const messages = { | @@ -320,6 +324,10 @@ const messages = { | ||
| 320 | ...parkingSpaceApplyManageMessages.en, | 324 | ...parkingSpaceApplyManageMessages.en, |
| 321 | ...addParkingSpaceApplyMessages.en, | 325 | ...addParkingSpaceApplyMessages.en, |
| 322 | ...auditParkingSpaceApplyMessages.en, | 326 | ...auditParkingSpaceApplyMessages.en, |
| 327 | + ...carCreateFeeMessages.en, | ||
| 328 | + ...listCarFeeMessages.en, | ||
| 329 | + ...repairSettingMessages.en, | ||
| 330 | + ...repairTypeUserMessages.en, | ||
| 323 | }, | 331 | }, |
| 324 | zh: { | 332 | zh: { |
| 325 | ...loginMessages.zh, | 333 | ...loginMessages.zh, |
| @@ -478,6 +486,10 @@ const messages = { | @@ -478,6 +486,10 @@ const messages = { | ||
| 478 | ...parkingSpaceApplyManageMessages.zh, | 486 | ...parkingSpaceApplyManageMessages.zh, |
| 479 | ...addParkingSpaceApplyMessages.zh, | 487 | ...addParkingSpaceApplyMessages.zh, |
| 480 | ...auditParkingSpaceApplyMessages.zh, | 488 | ...auditParkingSpaceApplyMessages.zh, |
| 489 | + ...carCreateFeeMessages.zh, | ||
| 490 | + ...listCarFeeMessages.zh, | ||
| 491 | + ...repairSettingMessages.zh, | ||
| 492 | + ...repairTypeUserMessages.zh, | ||
| 481 | } | 493 | } |
| 482 | } | 494 | } |
| 483 | 495 |
src/router/index.js
| @@ -767,25 +767,45 @@ const routes = [ | @@ -767,25 +767,45 @@ const routes = [ | ||
| 767 | component: () => import('@/views/car/remainingParkingSpaceList.vue') | 767 | component: () => import('@/views/car/remainingParkingSpaceList.vue') |
| 768 | }, | 768 | }, |
| 769 | { | 769 | { |
| 770 | - path:'/pages/car/tempCarPayment', | ||
| 771 | - name:'/pages/car/tempCarPayment', | 770 | + path: '/pages/car/tempCarPayment', |
| 771 | + name: '/pages/car/tempCarPayment', | ||
| 772 | component: () => import('@/views/car/tempCarPaymentList.vue') | 772 | component: () => import('@/views/car/tempCarPaymentList.vue') |
| 773 | + }, | ||
| 774 | + { | ||
| 775 | + path: '/pages/property/parkingSpaceApplyManage', | ||
| 776 | + name: '/pages/property/parkingSpaceApplyManage', | ||
| 777 | + component: () => import('@/views/car/parkingSpaceApplyManageList.vue') | ||
| 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 | + }, | ||
| 789 | + { | ||
| 790 | + path: '/pages/property/carCreateFee', | ||
| 791 | + name: '/pages/property/carCreateFee', | ||
| 792 | + component: () => import('@/views/fee/carCreateFeeList.vue') | ||
| 793 | + }, | ||
| 794 | + { | ||
| 795 | + path: '/views/fee/listCarFee', | ||
| 796 | + name: '/views/fee/listCarFee', | ||
| 797 | + component: () => import('@/views/fee/listCarFeeList.vue') | ||
| 798 | + }, | ||
| 799 | + { | ||
| 800 | + path: '/pages/work/repairSetting', | ||
| 801 | + name: '/pages/work/repairSetting', | ||
| 802 | + component: () => import('@/views/work/repairSettingList.vue') | ||
| 803 | + }, | ||
| 804 | + { | ||
| 805 | + path:'/views/work/repairTypeUser', | ||
| 806 | + name:'/views/work/repairTypeUser', | ||
| 807 | + component: () => import('@/views/work/repairTypeUserList.vue') | ||
| 773 | }, | 808 | }, |
| 774 | - { | ||
| 775 | - path:'/pages/property/parkingSpaceApplyManage', | ||
| 776 | - name:'/pages/property/parkingSpaceApplyManage', | ||
| 777 | - component: () => import('@/views/car/parkingSpaceApplyManageList.vue') | ||
| 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 | - }, | ||
| 789 | // 其他子路由可以在这里添加 | 809 | // 其他子路由可以在这里添加 |
| 790 | ] | 810 | ] |
| 791 | }, | 811 | }, |
src/views/fee/carCreateFeeLang.js
0 → 100644
| 1 | +export const messages = { | ||
| 2 | + en: { | ||
| 3 | + carCreateFee: { | ||
| 4 | + queryCondition: "Query Conditions", | ||
| 5 | + parkingSpacePlaceholder: "Please fill in parking lot-space, e.g. 1-101", | ||
| 6 | + carNumPlaceholder: "Please fill in license plate number", | ||
| 7 | + ownerNamePlaceholder: "Please fill in owner name", | ||
| 8 | + parkingSpaceStatus: "Parking space status", | ||
| 9 | + query: "Query", | ||
| 10 | + reset: "Reset", | ||
| 11 | + vehicleCharging: "Vehicle Charging", | ||
| 12 | + customTemplate: "Custom Template", | ||
| 13 | + customCreate: "Custom Create", | ||
| 14 | + batchCreate: "Batch Create", | ||
| 15 | + buyMonthlyCard: "Buy Monthly Card", | ||
| 16 | + licensePlate: "License Plate", | ||
| 17 | + parkingLot: "Parking Lot (Unit: No.)", | ||
| 18 | + parkingSpace: "Parking Space (Unit: No.)", | ||
| 19 | + ownerName: "Owner Name", | ||
| 20 | + contact: "Contact", | ||
| 21 | + status: "Status", | ||
| 22 | + operation: "Operation", | ||
| 23 | + viewCharges: "View Charges" | ||
| 24 | + }, | ||
| 25 | + carCreateFeeAdd: { | ||
| 26 | + createFee: "Create Fee", | ||
| 27 | + chargeScope: "Charge Scope", | ||
| 28 | + requiredChargeScope: "Required, please select charge scope", | ||
| 29 | + community: "Community", | ||
| 30 | + parkingLot: "Parking Lot", | ||
| 31 | + vehicle: "Vehicle", | ||
| 32 | + feeType: "Fee Type", | ||
| 33 | + requiredFeeType: "Required, please select fee type", | ||
| 34 | + feeItem: "Fee Item", | ||
| 35 | + requiredFeeItem: "Required, please select fee item", | ||
| 36 | + chargeAmount: "Charge Amount", | ||
| 37 | + requiredChargeAmount: "Required, please fill in charge amount", | ||
| 38 | + parkingSpaceStatus: "Parking Space Status", | ||
| 39 | + sold: "Sold", | ||
| 40 | + rented: "Rented", | ||
| 41 | + startTime: "Billing Start Time", | ||
| 42 | + requiredStartTime: "Required, please fill in billing start time", | ||
| 43 | + endTime: "Billing End Time", | ||
| 44 | + requiredEndTime: "Required, please fill in billing end time", | ||
| 45 | + submit: "Submit", | ||
| 46 | + cancel: "Cancel" | ||
| 47 | + }, | ||
| 48 | + exportCarFeeImportExcel: { | ||
| 49 | + templateExport: "Template Export", | ||
| 50 | + parkingLot: "Parking Lot", | ||
| 51 | + all: "All", | ||
| 52 | + parkingLotPlaceholder: "Parking Lot", | ||
| 53 | + feeItem: "Fee Item", | ||
| 54 | + export: "Export", | ||
| 55 | + cancel: "Cancel" | ||
| 56 | + }, | ||
| 57 | + doImportCreateFee: { | ||
| 58 | + customCreateFee: "Custom Create Fee", | ||
| 59 | + selectFile: "Select File", | ||
| 60 | + requiredFile: "Required, please select data file", | ||
| 61 | + import: "Import", | ||
| 62 | + cancel: "Cancel" | ||
| 63 | + }, | ||
| 64 | + parkingAreaSelect2: { | ||
| 65 | + parkingLotPlaceholder: "Required, please select parking lot" | ||
| 66 | + } | ||
| 67 | + }, | ||
| 68 | + zh: { | ||
| 69 | + carCreateFee: { | ||
| 70 | + queryCondition: "查询条件", | ||
| 71 | + parkingSpacePlaceholder: "请填写停车场-车位,如 1-101", | ||
| 72 | + carNumPlaceholder: "请填写车牌号", | ||
| 73 | + ownerNamePlaceholder: "请填写业主名称", | ||
| 74 | + parkingSpaceStatus: "请选择车位状态", | ||
| 75 | + query: "查询", | ||
| 76 | + reset: "重置", | ||
| 77 | + vehicleCharging: "车辆收费", | ||
| 78 | + customTemplate: "自定义模板", | ||
| 79 | + customCreate: "自定义创建", | ||
| 80 | + batchCreate: "批量创建", | ||
| 81 | + buyMonthlyCard: "购买月卡", | ||
| 82 | + licensePlate: "车牌号", | ||
| 83 | + parkingLot: "停车场(单位:号)", | ||
| 84 | + parkingSpace: "车位(单位:号)", | ||
| 85 | + ownerName: "业主名称", | ||
| 86 | + contact: "联系方式", | ||
| 87 | + status: "车位状态", | ||
| 88 | + operation: "操作", | ||
| 89 | + viewCharges: "查看收费" | ||
| 90 | + }, | ||
| 91 | + carCreateFeeAdd: { | ||
| 92 | + createFee: "创建费用", | ||
| 93 | + chargeScope: "收费范围", | ||
| 94 | + requiredChargeScope: "必填,请选择收费范围", | ||
| 95 | + community: "小区", | ||
| 96 | + parkingLot: "停车场", | ||
| 97 | + vehicle: "车辆", | ||
| 98 | + feeType: "费用类型", | ||
| 99 | + requiredFeeType: "必填,请选择费用类型", | ||
| 100 | + feeItem: "收费项目", | ||
| 101 | + requiredFeeItem: "必填,请选择收费项目", | ||
| 102 | + chargeAmount: "收费金额", | ||
| 103 | + requiredChargeAmount: "必填,请填写收费金额", | ||
| 104 | + parkingSpaceStatus: "车位状态", | ||
| 105 | + sold: "已出售", | ||
| 106 | + rented: "已出租", | ||
| 107 | + startTime: "计费起始时间", | ||
| 108 | + requiredStartTime: "必填,请填写计费起始时间", | ||
| 109 | + endTime: "计费结束时间", | ||
| 110 | + requiredEndTime: "必填,请填写计费结束时间", | ||
| 111 | + submit: "提交", | ||
| 112 | + cancel: "取消" | ||
| 113 | + }, | ||
| 114 | + exportCarFeeImportExcel: { | ||
| 115 | + templateExport: "模板导出", | ||
| 116 | + parkingLot: "停车场", | ||
| 117 | + all: "全部", | ||
| 118 | + parkingLotPlaceholder: "停车场", | ||
| 119 | + feeItem: "费用项", | ||
| 120 | + export: "导出", | ||
| 121 | + cancel: "取消" | ||
| 122 | + }, | ||
| 123 | + doImportCreateFee: { | ||
| 124 | + customCreateFee: "自定义创建费用", | ||
| 125 | + selectFile: "选择文件", | ||
| 126 | + requiredFile: "必填,请选择数据文件", | ||
| 127 | + import: "导入", | ||
| 128 | + cancel: "取消" | ||
| 129 | + }, | ||
| 130 | + parkingAreaSelect2: { | ||
| 131 | + parkingLotPlaceholder: "必填,请选择停车场" | ||
| 132 | + } | ||
| 133 | + } | ||
| 134 | +} | ||
| 0 | \ No newline at end of file | 135 | \ No newline at end of file |
src/views/fee/carCreateFeeList.vue
0 → 100644
| 1 | +<template> | ||
| 2 | + <div class="car-create-fee-container"> | ||
| 3 | + <el-card class="box-card"> | ||
| 4 | + <div slot="header" class="clearfix"> | ||
| 5 | + <h5>{{ $t('carCreateFee.queryCondition') }}</h5> | ||
| 6 | + </div> | ||
| 7 | + <el-row :gutter="20"> | ||
| 8 | + <el-col :span="4"> | ||
| 9 | + <el-input v-model.trim="queryParams.allNum" :placeholder="$t('carCreateFee.parkingSpacePlaceholder')" | ||
| 10 | + @keyup.enter.native="handleQuery" /> | ||
| 11 | + </el-col> | ||
| 12 | + <el-col :span="4"> | ||
| 13 | + <el-input v-model.trim="queryParams.carNumLike" :placeholder="$t('carCreateFee.carNumPlaceholder')" | ||
| 14 | + @keyup.enter.native="handleQuery" /> | ||
| 15 | + </el-col> | ||
| 16 | + <el-col :span="4"> | ||
| 17 | + <el-input v-model.trim="queryParams.ownerName" :placeholder="$t('carCreateFee.ownerNamePlaceholder')" | ||
| 18 | + @keyup.enter.native="handleQuery" /> | ||
| 19 | + </el-col> | ||
| 20 | + <el-col :span="4"> | ||
| 21 | + <el-select v-model="queryParams.state" :placeholder="$t('carCreateFee.parkingSpaceStatus')" style="width:100%"> | ||
| 22 | + <el-option v-for="item in states" :key="item.statusCd" :label="item.name" :value="item.statusCd" /> | ||
| 23 | + </el-select> | ||
| 24 | + </el-col> | ||
| 25 | + <el-col :span="4" style="text-align:right"> | ||
| 26 | + <el-button type="primary" @click="handleQuery"> | ||
| 27 | + <i class="el-icon-search"></i> | ||
| 28 | + {{ $t('carCreateFee.query') }} | ||
| 29 | + </el-button> | ||
| 30 | + <el-button @click="handleReset" style="margin-left:10px"> | ||
| 31 | + <i class="el-icon-refresh"></i> | ||
| 32 | + {{ $t('carCreateFee.reset') }} | ||
| 33 | + </el-button> | ||
| 34 | + </el-col> | ||
| 35 | + </el-row> | ||
| 36 | + </el-card> | ||
| 37 | + | ||
| 38 | + <el-card class="box-card" style="margin-top:20px"> | ||
| 39 | + <div slot="header" class="clearfix"> | ||
| 40 | + <h5>{{ $t('carCreateFee.vehicleCharging') }}</h5> | ||
| 41 | + <div style="float:right"> | ||
| 42 | + <el-button @click="handleOpenFeeImportExcel"> | ||
| 43 | + <i class="el-icon-plus"></i> | ||
| 44 | + {{ $t('carCreateFee.customTemplate') }} | ||
| 45 | + </el-button> | ||
| 46 | + <el-button @click="handleOpenDoCreateRoomFee" style="margin-left:10px"> | ||
| 47 | + <i class="el-icon-plus"></i> | ||
| 48 | + {{ $t('carCreateFee.customCreate') }} | ||
| 49 | + </el-button> | ||
| 50 | + <el-button type="primary" @click="handleBatchCreate" style="margin-left:10px"> | ||
| 51 | + {{ $t('carCreateFee.batchCreate') }} | ||
| 52 | + </el-button> | ||
| 53 | + <el-button type="primary" @click="handleBuyMonthlyCard" style="margin-left:10px"> | ||
| 54 | + {{ $t('carCreateFee.buyMonthlyCard') }} | ||
| 55 | + </el-button> | ||
| 56 | + </div> | ||
| 57 | + </div> | ||
| 58 | + | ||
| 59 | + <el-table :data="cars" border style="width:100%"> | ||
| 60 | + <el-table-column prop="carNum" :label="$t('carCreateFee.licensePlate')" align="center" /> | ||
| 61 | + <el-table-column prop="areaNum" :label="$t('carCreateFee.parkingLot')" align="center" /> | ||
| 62 | + <el-table-column prop="num" :label="$t('carCreateFee.parkingSpace')" align="center" /> | ||
| 63 | + <el-table-column prop="ownerName" :label="$t('carCreateFee.ownerName')" align="center" /> | ||
| 64 | + <el-table-column prop="link" :label="$t('carCreateFee.contact')" align="center" /> | ||
| 65 | + <el-table-column prop="stateName" :label="$t('carCreateFee.status')" align="center" /> | ||
| 66 | + <el-table-column :label="$t('carCreateFee.operation')" align="center" width="150"> | ||
| 67 | + <template slot-scope="scope"> | ||
| 68 | + <el-button size="mini" @click="handleViewCharges(scope.row)"> | ||
| 69 | + {{ $t('carCreateFee.viewCharges') }} | ||
| 70 | + </el-button> | ||
| 71 | + </template> | ||
| 72 | + </el-table-column> | ||
| 73 | + </el-table> | ||
| 74 | + | ||
| 75 | + <el-pagination style="margin-top:20px" :current-page.sync="pagination.current" :page-sizes="[10, 20, 30, 50]" | ||
| 76 | + :page-size="pagination.size" :total="pagination.total" layout="total, sizes, prev, pager, next, jumper" | ||
| 77 | + @size-change="handleSizeChange" @current-change="handleCurrentChange" /> | ||
| 78 | + </el-card> | ||
| 79 | + | ||
| 80 | + <!-- 子组件 --> | ||
| 81 | + <car-create-fee-add ref="carCreateFeeAdd" @success="handleSuccess" /> | ||
| 82 | + <export-car-fee-import-excel ref="exportCarFeeImportExcel" /> | ||
| 83 | + <do-import-create-fee ref="doImportCreateFee" /> | ||
| 84 | + </div> | ||
| 85 | +</template> | ||
| 86 | + | ||
| 87 | +<script> | ||
| 88 | +import { listCarCreateFees } from '@/api/fee/carCreateFeeApi' | ||
| 89 | +import { getDict } from '@/api/community/communityApi' | ||
| 90 | + | ||
| 91 | +export default { | ||
| 92 | + name: 'CarCreateFeeList', | ||
| 93 | + components: { | ||
| 94 | + 'car-create-fee-add': () => import('@/components/fee/carCreateFeeAdd'), | ||
| 95 | + 'export-car-fee-import-excel': () => import('@/components/fee/exportCarFeeImportExcel'), | ||
| 96 | + 'do-import-create-fee': () => import('@/components/fee/doImportCreateFee') | ||
| 97 | + }, | ||
| 98 | + data() { | ||
| 99 | + return { | ||
| 100 | + queryParams: { | ||
| 101 | + allNum: '', | ||
| 102 | + carNumLike: '', | ||
| 103 | + ownerName: '', | ||
| 104 | + state: '', | ||
| 105 | + carTypeCd: '1001', | ||
| 106 | + page: 1, | ||
| 107 | + row: 10 | ||
| 108 | + }, | ||
| 109 | + pagination: { | ||
| 110 | + current: 1, | ||
| 111 | + size: 10, | ||
| 112 | + total: 0 | ||
| 113 | + }, | ||
| 114 | + cars: [], | ||
| 115 | + states: [] | ||
| 116 | + } | ||
| 117 | + }, | ||
| 118 | + created() { | ||
| 119 | + this.getDictData() | ||
| 120 | + this.fetchData() | ||
| 121 | + }, | ||
| 122 | + methods: { | ||
| 123 | + async getDictData() { | ||
| 124 | + try { | ||
| 125 | + this.states = await getDict('owner_car', 'state') | ||
| 126 | + } catch (error) { | ||
| 127 | + console.error('获取字典数据失败:', error) | ||
| 128 | + } | ||
| 129 | + }, | ||
| 130 | + async fetchData() { | ||
| 131 | + try { | ||
| 132 | + const res = await listCarCreateFees(this.queryParams) | ||
| 133 | + this.cars = res.data || [] | ||
| 134 | + this.pagination.total = res.total || 0 | ||
| 135 | + } catch (error) { | ||
| 136 | + this.$message.error(this.$t('common.fetchError')) | ||
| 137 | + } | ||
| 138 | + }, | ||
| 139 | + handleQuery() { | ||
| 140 | + this.queryParams.page = 1 | ||
| 141 | + this.fetchData() | ||
| 142 | + }, | ||
| 143 | + handleReset() { | ||
| 144 | + this.queryParams = { | ||
| 145 | + allNum: '', | ||
| 146 | + carNumLike: '', | ||
| 147 | + ownerName: '', | ||
| 148 | + state: '', | ||
| 149 | + carTypeCd: '1001', | ||
| 150 | + page: 1, | ||
| 151 | + row: this.queryParams.row | ||
| 152 | + } | ||
| 153 | + this.fetchData() | ||
| 154 | + }, | ||
| 155 | + handleSizeChange(size) { | ||
| 156 | + this.queryParams.row = size | ||
| 157 | + this.fetchData() | ||
| 158 | + }, | ||
| 159 | + handleCurrentChange(current) { | ||
| 160 | + this.queryParams.page = current | ||
| 161 | + this.fetchData() | ||
| 162 | + }, | ||
| 163 | + handleBatchCreate() { | ||
| 164 | + this.$refs.carCreateFeeAdd.open({ isMore: true }) | ||
| 165 | + }, | ||
| 166 | + handleOpenFeeImportExcel() { | ||
| 167 | + this.$refs.exportCarFeeImportExcel.open() | ||
| 168 | + }, | ||
| 169 | + handleOpenDoCreateRoomFee() { | ||
| 170 | + this.$refs.doImportCreateFee.open() | ||
| 171 | + }, | ||
| 172 | + handleBuyMonthlyCard() { | ||
| 173 | + this.$router.push({ path: '/views/fee/buyCarMonthCard' }) | ||
| 174 | + }, | ||
| 175 | + handleViewCharges(row) { | ||
| 176 | + this.$router.push({ | ||
| 177 | + path: '/views/fee/listCarFee', | ||
| 178 | + query: { | ||
| 179 | + carId: row.carId, | ||
| 180 | + carNum: row.carNum, | ||
| 181 | + areaNum: row.areaNum, | ||
| 182 | + num: row.num | ||
| 183 | + } | ||
| 184 | + }) | ||
| 185 | + }, | ||
| 186 | + handleSuccess() { | ||
| 187 | + this.fetchData() | ||
| 188 | + } | ||
| 189 | + } | ||
| 190 | +} | ||
| 191 | +</script> | ||
| 192 | + | ||
| 193 | +<style lang="scss" scoped> | ||
| 194 | +.car-create-fee-container { | ||
| 195 | + padding: 20px; | ||
| 196 | + | ||
| 197 | + .box-card { | ||
| 198 | + margin-bottom: 20px; | ||
| 199 | + } | ||
| 200 | + | ||
| 201 | + .clearfix { | ||
| 202 | + display: flex; | ||
| 203 | + justify-content: space-between; | ||
| 204 | + align-items: center; | ||
| 205 | + | ||
| 206 | + h5 { | ||
| 207 | + margin: 0; | ||
| 208 | + font-size: 16px; | ||
| 209 | + } | ||
| 210 | + } | ||
| 211 | +} | ||
| 212 | +</style> | ||
| 0 | \ No newline at end of file | 213 | \ No newline at end of file |
src/views/fee/listCarFeeLang.js
0 → 100644
| 1 | +export const messages = { | ||
| 2 | + en: { | ||
| 3 | + listCarFee: { | ||
| 4 | + fee: 'Fee', | ||
| 5 | + createFee: 'Create Fee', | ||
| 6 | + feeItem: 'Fee Item', | ||
| 7 | + feeFlag: 'Fee Flag', | ||
| 8 | + feeType: 'Fee Type', | ||
| 9 | + amountOwed: 'Amount Owed', | ||
| 10 | + startTime: 'Start Time', | ||
| 11 | + endTime: 'End Time', | ||
| 12 | + remark: 'Remark', | ||
| 13 | + state: 'State', | ||
| 14 | + operation: 'Operation', | ||
| 15 | + pay: 'Pay', | ||
| 16 | + history: 'History', | ||
| 17 | + cancel: 'Cancel', | ||
| 18 | + change: 'Change', | ||
| 19 | + split: 'Split', | ||
| 20 | + detail: 'Detail', | ||
| 21 | + preDegrees: 'Pre Degrees', | ||
| 22 | + curDegrees: 'Cur Degrees', | ||
| 23 | + price: 'Price', | ||
| 24 | + additionalAmount: 'Additional Amount', | ||
| 25 | + algorithm: 'Algorithm', | ||
| 26 | + usage: 'Usage', | ||
| 27 | + note1: 'Note: The end time "-" means the fee is not due or the fee collection has ended.', | ||
| 28 | + note2: 'If the amount owed is -1, it is usually an error in the fee item formula setting, please check.' | ||
| 29 | + }, | ||
| 30 | + }, | ||
| 31 | + zh: { | ||
| 32 | + listCarFee: { | ||
| 33 | + fee: '费用', | ||
| 34 | + createFee: '创建费用', | ||
| 35 | + feeItem: '费用项目', | ||
| 36 | + feeFlag: '费用标识', | ||
| 37 | + feeType: '费用类型', | ||
| 38 | + amountOwed: '应收金额', | ||
| 39 | + startTime: '建账时间', | ||
| 40 | + endTime: '应收时间段', | ||
| 41 | + remark: '说明', | ||
| 42 | + state: '状态', | ||
| 43 | + operation: '操作', | ||
| 44 | + pay: '缴费', | ||
| 45 | + history: '历史', | ||
| 46 | + cancel: '取消', | ||
| 47 | + change: '变更', | ||
| 48 | + split: '拆分', | ||
| 49 | + detail: '详情', | ||
| 50 | + preDegrees: '上期度数', | ||
| 51 | + curDegrees: '本期度数', | ||
| 52 | + price: '单价', | ||
| 53 | + additionalAmount: '附加费', | ||
| 54 | + algorithm: '算法', | ||
| 55 | + usage: '用量', | ||
| 56 | + note1: '注意:应收结束时间“-”表示未到应收时间或收费已结束。', | ||
| 57 | + note2: '应收金额为-1一般为费用项公式设置出错请检查。' | ||
| 58 | + }, | ||
| 59 | + } | ||
| 60 | +} | ||
| 0 | \ No newline at end of file | 61 | \ No newline at end of file |
src/views/fee/listCarFeeList.vue
0 → 100644
| 1 | +<template> | ||
| 2 | + <div> | ||
| 3 | + <el-card class="box-card margin"> | ||
| 4 | + <div slot="header" class="flex justify-between"> | ||
| 5 | + <div>{{ listCarFeeInfo.carNum }} | ||
| 6 | + <span>{{ $t('listCarFee.fee') }}</span>({{ listCarFeeInfo.parkingName }}) | ||
| 7 | + </div> | ||
| 8 | + <div class="ibox-tools" style="top:10px;"> | ||
| 9 | + <el-button type="primary" size="small" style="margin-left:10px" @click="_openCarCreateFeeAddModal"> | ||
| 10 | + <i class="el-icon-plus"></i> | ||
| 11 | + <span>{{ $t('listCarFee.createFee') }}</span> | ||
| 12 | + </el-button> | ||
| 13 | + <el-button type="primary" size="small" style="margin-left:10px" @click="_goBack"> | ||
| 14 | + <i class="el-icon-close"></i> | ||
| 15 | + <span>{{ $t('common.back') }}</span> | ||
| 16 | + </el-button> | ||
| 17 | + </div> | ||
| 18 | + </div> | ||
| 19 | + <div class="ibox-content"> | ||
| 20 | + <el-table :data="listCarFeeInfo.fees" border style="width: 100%"> | ||
| 21 | + <el-table-column prop="feeName" :label="$t('listCarFee.feeItem')" align="center"> | ||
| 22 | + <template slot-scope="scope"> | ||
| 23 | + <span class="hand" @click="_viewCarFeeConfig(scope.row)">{{ scope.row.feeName }} | ||
| 24 | + <i class="el-icon-info"></i> | ||
| 25 | + </span> | ||
| 26 | + </template> | ||
| 27 | + </el-table-column> | ||
| 28 | + <el-table-column prop="feeFlagName" :label="$t('listCarFee.feeFlag')" align="center"></el-table-column> | ||
| 29 | + <el-table-column prop="feeTypeCdName" :label="$t('listCarFee.feeType')" align="center"></el-table-column> | ||
| 30 | + <el-table-column prop="amountOwed" :label="$t('listCarFee.amountOwed')" align="center"></el-table-column> | ||
| 31 | + <el-table-column prop="startTime" :label="$t('listCarFee.startTime')" align="center"></el-table-column> | ||
| 32 | + <el-table-column :label="$t('listCarFee.endTime')" align="center"> | ||
| 33 | + <template slot-scope="scope"> | ||
| 34 | + {{ _getEndTime(scope.row) }}~<br />{{ _getDeadlineTime(scope.row) }} | ||
| 35 | + </template> | ||
| 36 | + </el-table-column> | ||
| 37 | + <el-table-column :label="$t('listCarFee.remark')" align="center" width="150"> | ||
| 38 | + <template slot-scope="scope"> | ||
| 39 | + <div v-if="scope.row.feeTypeCd == '888800010015' || scope.row.feeTypeCd == '888800010016'"> | ||
| 40 | + <div> | ||
| 41 | + <span>{{ $t('listCarFee.preDegrees') }}:</span>{{ scope.row.preDegrees }} | ||
| 42 | + </div> | ||
| 43 | + <div> | ||
| 44 | + <span>{{ $t('listCarFee.curDegrees') }}:</span>{{ scope.row.curDegrees }} | ||
| 45 | + </div> | ||
| 46 | + <div> | ||
| 47 | + <span>{{ $t('listCarFee.price') }}:</span>{{ scope.row.mwPrice ? scope.row.mwPrice : | ||
| 48 | + scope.row.squarePrice | ||
| 49 | + }} | ||
| 50 | + </div> | ||
| 51 | + <div> | ||
| 52 | + <span>{{ $t('listCarFee.additionalAmount') }}:</span>{{ scope.row.additionalAmount }} | ||
| 53 | + </div> | ||
| 54 | + </div> | ||
| 55 | + <div v-else-if="scope.row.feeTypeCd == '888800010017'"> | ||
| 56 | + <div> | ||
| 57 | + <span>{{ $t('listCarFee.algorithm') }}:</span>{{ _getAttrValue(scope.row.feeAttrs, '390005') }} | ||
| 58 | + </div> | ||
| 59 | + <div> | ||
| 60 | + <span>{{ $t('listCarFee.usage') }}:</span>{{ _getAttrValue(scope.row.feeAttrs, '390003') }} | ||
| 61 | + </div> | ||
| 62 | + </div> | ||
| 63 | + <div v-else> | ||
| 64 | + <div> | ||
| 65 | + <span>{{ $t('listCarFee.price') }}:</span>{{ scope.row.squarePrice }} | ||
| 66 | + </div> | ||
| 67 | + <div> | ||
| 68 | + <span>{{ $t('listCarFee.additionalAmount') }}:</span>{{ scope.row.additionalAmount }} | ||
| 69 | + </div> | ||
| 70 | + </div> | ||
| 71 | + </template> | ||
| 72 | + </el-table-column> | ||
| 73 | + <el-table-column prop="stateName" :label="$t('listCarFee.state')" align="center"></el-table-column> | ||
| 74 | + <el-table-column :label="$t('listCarFee.operation')" align="center"> | ||
| 75 | + <template slot-scope="scope"> | ||
| 76 | + <el-button type="text" v-if="scope.row.state != '2009001' && hasPrivilege('502020082314267912')" | ||
| 77 | + @click="_payFee(scope.row)">{{ $t('listCarFee.pay') }}</el-button> | ||
| 78 | + <el-button type="text" @click="_payFeeHis(scope.row)">{{ $t('listCarFee.history') }}</el-button> | ||
| 79 | + <el-button type="text" v-if="hasPrivilege('502020090604200029')" @click="_deleteFee(scope.row)">{{ | ||
| 80 | + $t('listCarFee.cancel') }}</el-button> | ||
| 81 | + <el-button type="text" v-if="scope.row.state != '2009001' && hasPrivilege('502020090427190001')" | ||
| 82 | + @click="_editFee(scope.row)">{{ $t('listCarFee.change') }}</el-button> | ||
| 83 | + <el-button type="text" v-if="scope.row.feeFlag == '4012024' && scope.row.state == '2008001'" | ||
| 84 | + @click="_splitPayFee(scope.row)">{{ $t('listCarFee.split') }}</el-button> | ||
| 85 | + <el-button type="text" @click="_viewCarFee(scope.row)">{{ $t('listCarFee.detail') }}</el-button> | ||
| 86 | + </template> | ||
| 87 | + </el-table-column> | ||
| 88 | + </el-table> | ||
| 89 | + <el-row> | ||
| 90 | + <el-col :span="12"> | ||
| 91 | + <div> {{ $t('listCarFee.note1') }}</div> | ||
| 92 | + <div> {{ $t('listCarFee.note2') }}</div> | ||
| 93 | + </el-col> | ||
| 94 | + <el-col :span="12"> | ||
| 95 | + <el-pagination @size-change="handleSizeChange" @current-change="handleCurrentChange" | ||
| 96 | + :current-page="page.current" :page-sizes="[10, 20, 30, 50]" :page-size="page.size" | ||
| 97 | + layout="total, sizes, prev, pager, next, jumper" :total="page.total"> | ||
| 98 | + </el-pagination> | ||
| 99 | + </el-col> | ||
| 100 | + </el-row> | ||
| 101 | + </div> | ||
| 102 | + </el-card> | ||
| 103 | + | ||
| 104 | + <!-- 子组件 --> | ||
| 105 | + <delete-fee ref="deleteFee"></delete-fee> | ||
| 106 | + <edit-fee ref="editFee"></edit-fee> | ||
| 107 | + <split-fee ref="splitFee"></split-fee> | ||
| 108 | + <car-create-fee-add ref="carCreateFeeAdd" @success="handleSuccess"></car-create-fee-add> | ||
| 109 | + <!-- <add-meter-water ref="addMeterWater"></add-meter-water> --> | ||
| 110 | + </div> | ||
| 111 | +</template> | ||
| 112 | + | ||
| 113 | +<script> | ||
| 114 | +import { listFee } from '@/api/fee/listCarFeeApi' | ||
| 115 | +import DeleteFee from '@/components/fee/deleteFee' | ||
| 116 | +import EditFee from '@/components/fee/editFee' | ||
| 117 | +import SplitFee from '@/components/fee/splitFee' | ||
| 118 | +import CarCreateFeeAdd from '@/components/fee/carCreateFeeAdd' | ||
| 119 | +//import AddMeterWater from '@/components/fee/addMeterWater' | ||
| 120 | +import { getCommunityId } from '@/api/community/communityApi' | ||
| 121 | +import {dateFormat} from '@/utils/dateUtil' | ||
| 122 | + | ||
| 123 | +export default { | ||
| 124 | + name: 'ListCarFee', | ||
| 125 | + components: { | ||
| 126 | + DeleteFee, | ||
| 127 | + EditFee, | ||
| 128 | + SplitFee, | ||
| 129 | + CarCreateFeeAdd, | ||
| 130 | + // AddMeterWater | ||
| 131 | + }, | ||
| 132 | + data() { | ||
| 133 | + return { | ||
| 134 | + listCarFeeInfo: { | ||
| 135 | + fees: [], | ||
| 136 | + carNum: '', | ||
| 137 | + carId: '', | ||
| 138 | + total: 0, | ||
| 139 | + records: 1, | ||
| 140 | + areaNum: '', | ||
| 141 | + num: '', | ||
| 142 | + parkingName: '' | ||
| 143 | + }, | ||
| 144 | + page: { | ||
| 145 | + current: 1, | ||
| 146 | + size: 10, | ||
| 147 | + total: 0 | ||
| 148 | + }, | ||
| 149 | + communityId: '' | ||
| 150 | + } | ||
| 151 | + }, | ||
| 152 | + created() { | ||
| 153 | + this.communityId = getCommunityId() | ||
| 154 | + if (this.$route.query.carNum) { | ||
| 155 | + this.listCarFeeInfo.carNum = this.$route.query.carNum | ||
| 156 | + this.listCarFeeInfo.carId = this.$route.query.carId | ||
| 157 | + this.listCarFeeInfo.areaNum = this.$route.query.areaNum | ||
| 158 | + this.listCarFeeInfo.num = this.$route.query.num | ||
| 159 | + } | ||
| 160 | + let parkingName = this.listCarFeeInfo.areaNum ? `${this.listCarFeeInfo.areaNum}停车场${this.listCarFeeInfo.num}车位` : '无车位' | ||
| 161 | + this.listCarFeeInfo.parkingName = parkingName | ||
| 162 | + this._loadlistCarFeeInfo(1, 10) | ||
| 163 | + }, | ||
| 164 | + methods: { | ||
| 165 | + handleSuccess() { | ||
| 166 | + this._loadlistCarFeeInfo(1, 10) | ||
| 167 | + }, | ||
| 168 | + async _loadlistCarFeeInfo(page, row) { | ||
| 169 | + const params = { | ||
| 170 | + page: page, | ||
| 171 | + row: row, | ||
| 172 | + communityId: this.communityId, | ||
| 173 | + payerObjId: this.listCarFeeInfo.carId | ||
| 174 | + } | ||
| 175 | + const { fees,total,records } = await listFee(params) | ||
| 176 | + this.listCarFeeInfo.fees = fees | ||
| 177 | + this.page.total = total | ||
| 178 | + this.page.records = records | ||
| 179 | + | ||
| 180 | + }, | ||
| 181 | + handleSizeChange(val) { | ||
| 182 | + this.page.size = val | ||
| 183 | + this._loadlistCarFeeInfo(this.page.current, val) | ||
| 184 | + }, | ||
| 185 | + handleCurrentChange(val) { | ||
| 186 | + this.page.current = val | ||
| 187 | + this._loadlistCarFeeInfo(val, this.page.size) | ||
| 188 | + }, | ||
| 189 | + _payFee(fee) { | ||
| 190 | + fee.roomName = this.listCarFeeInfo.carNum | ||
| 191 | + this.$router.push({ path: '/fee/payFeeOrder', query: { feeId: fee.feeId } }) | ||
| 192 | + }, | ||
| 193 | + _payFeeHis(fee) { | ||
| 194 | + this.$router.push({ path: '/property/propertyFee', query: fee }) | ||
| 195 | + }, | ||
| 196 | + _editFee(fee) { | ||
| 197 | + this.$refs.editFee.open(fee) | ||
| 198 | + }, | ||
| 199 | + _deleteFee(fee) { | ||
| 200 | + this.$refs.deleteFee.open({ | ||
| 201 | + communityId: this.communityId, | ||
| 202 | + feeId: fee.feeId | ||
| 203 | + }) | ||
| 204 | + }, | ||
| 205 | + _openCarCreateFeeAddModal() { | ||
| 206 | + this.$refs.carCreateFeeAdd.open({ | ||
| 207 | + isMore: false, | ||
| 208 | + car: this.listCarFeeInfo | ||
| 209 | + }) | ||
| 210 | + }, | ||
| 211 | + _openAddMeterWaterModal() { | ||
| 212 | + this.$refs.addMeterWater.open({ | ||
| 213 | + roomId: this.listCarFeeInfo.carId, | ||
| 214 | + roomName: this.listCarFeeInfo.carNum, | ||
| 215 | + ownerName: this.listCarFeeInfo.parkingName, | ||
| 216 | + objType: '6666' | ||
| 217 | + }) | ||
| 218 | + }, | ||
| 219 | + _goBack() { | ||
| 220 | + this.$router.go(-1) | ||
| 221 | + }, | ||
| 222 | + _getDeadlineTime(fee) { | ||
| 223 | + if (fee.amountOwed == 0 && fee.endTime == fee.deadlineTime) { | ||
| 224 | + return "-" | ||
| 225 | + } | ||
| 226 | + if (fee.state == '2009001') { | ||
| 227 | + return "-" | ||
| 228 | + } | ||
| 229 | + return dateFormat(fee.deadlineTime) || fee.deadlineTime | ||
| 230 | + }, | ||
| 231 | + _getEndTime(fee) { | ||
| 232 | + if (fee.state == '2009001') { | ||
| 233 | + return "-" | ||
| 234 | + } | ||
| 235 | + return dateFormat(fee.endTime) || fee.endTime | ||
| 236 | + }, | ||
| 237 | + _viewCarFeeConfig(fee) { | ||
| 238 | + // 查看费用项配置逻辑 | ||
| 239 | + console.log(fee) | ||
| 240 | + }, | ||
| 241 | + _viewCarFee(fee) { | ||
| 242 | + // 查看费用详情逻辑 | ||
| 243 | + console.log(fee) | ||
| 244 | + | ||
| 245 | + }, | ||
| 246 | + _splitPayFee(fee) { | ||
| 247 | + this.$refs.splitFee.open(fee) | ||
| 248 | + }, | ||
| 249 | + _getAttrValue(attrs, specCd) { | ||
| 250 | + const attr = attrs.find(item => item.specCd === specCd) | ||
| 251 | + return attr ? attr.value : '' | ||
| 252 | + }, | ||
| 253 | + } | ||
| 254 | +} | ||
| 255 | +</script> | ||
| 256 | + | ||
| 257 | +<style scoped> | ||
| 258 | +.hand { | ||
| 259 | + cursor: pointer; | ||
| 260 | +} | ||
| 261 | +</style> | ||
| 0 | \ No newline at end of file | 262 | \ No newline at end of file |
src/views/work/repairSettingLang.js
0 → 100644
| 1 | +export const messages = { | ||
| 2 | + en: { | ||
| 3 | + repairSetting: { | ||
| 4 | + queryCondition: 'Query Condition', | ||
| 5 | + repairTypeNamePlaceholder: 'Please enter type name', | ||
| 6 | + repairWayPlaceholder: 'Please select dispatch method', | ||
| 7 | + repairSettingTypePlaceholder: 'Please select repair setting type', | ||
| 8 | + publicAreaPlaceholder: 'Please select area', | ||
| 9 | + returnVisitFlagPlaceholder: 'Please select whether to follow up', | ||
| 10 | + search: 'Search', | ||
| 11 | + reset: 'Reset', | ||
| 12 | + repairSettingTitle: 'Repair Settings', | ||
| 13 | + documentation: 'Documentation', | ||
| 14 | + add: 'Add', | ||
| 15 | + typeName: 'Type Name', | ||
| 16 | + repairSettingType: 'Repair Setting Type', | ||
| 17 | + dispatchMethod: 'Dispatch Method', | ||
| 18 | + area: 'Area', | ||
| 19 | + ownerDisplay: 'Owner Display', | ||
| 20 | + notificationMethod: 'Notification Method', | ||
| 21 | + returnVisit: 'Return Visit', | ||
| 22 | + processingTime: 'Processing Time (hours)', | ||
| 23 | + timeoutWarning: 'Timeout Warning (minutes)', | ||
| 24 | + createTime: 'Create Time', | ||
| 25 | + operation: 'Operation', | ||
| 26 | + edit: 'Edit', | ||
| 27 | + bindRepairMaster: 'Bind Repair Master', | ||
| 28 | + delete: 'Delete', | ||
| 29 | + explanation: 'Explanation', | ||
| 30 | + save: 'Save', | ||
| 31 | + cancel: 'Cancel', | ||
| 32 | + confirmDeleteTitle: 'Please confirm your operation!', | ||
| 33 | + confirmDeleteContent: 'Are you sure to delete this repair setting?', | ||
| 34 | + cancelDelete: 'Cancel', | ||
| 35 | + confirmDelete: 'Confirm Delete', | ||
| 36 | + addTitle: 'Add Repair Setting', | ||
| 37 | + editTitle: 'Edit Repair Setting', | ||
| 38 | + settingType: 'Setting Type', | ||
| 39 | + publicArea: 'Public Area', | ||
| 40 | + ownerDisplayPlaceholder: 'Whether to display in owner app', | ||
| 41 | + notificationMethodPlaceholder: 'Please select notification method', | ||
| 42 | + returnVisitSetting: 'Return Visit Setting', | ||
| 43 | + remarkPlaceholder: 'Optional, please enter remarks', | ||
| 44 | + required: 'Required', | ||
| 45 | + cleaningOrder: 'Cleaning Order', | ||
| 46 | + repairOrder: 'Repair Order', | ||
| 47 | + grabOrder: 'Grab Order', | ||
| 48 | + assign: 'Assign', | ||
| 49 | + polling: 'Polling', | ||
| 50 | + nonHouse: 'Non-House', | ||
| 51 | + house: 'House', | ||
| 52 | + yes: 'Yes', | ||
| 53 | + no: 'No', | ||
| 54 | + sms: 'SMS', | ||
| 55 | + wechat: 'WeChat', | ||
| 56 | + wechatWorkLicense: 'WeChat + Employee License', | ||
| 57 | + noFollowUp: 'No Follow Up', | ||
| 58 | + followUpAfterEvaluation: 'Follow Up After Evaluation', | ||
| 59 | + followUp: 'Follow Up', | ||
| 60 | + dispatchExplanation: 'Dispatch Explanation:', | ||
| 61 | + dispatchPoint1: '1. Grab Order: Employees (masters under the repair type) grab orders independently, suitable for scenarios where the property gives commissions per order', | ||
| 62 | + dispatchPoint2: '2. Assign: Specifically assigned by customer service to employees (masters under the repair type)', | ||
| 63 | + dispatchPoint3: '3. Polling: System periodically assigns orders to employees (masters under the repair type)', | ||
| 64 | + areaExplanation: 'Area Explanation:', | ||
| 65 | + areaPoint1: 'Community, building, unit are non-house areas; houses are house areas', | ||
| 66 | + areaPoint2: 'Note: For owner house repairs, a house area type must be added for normal repair', | ||
| 67 | + processingTimeUnit: 'Hours', | ||
| 68 | + timeoutWarningUnit: 'Minutes' | ||
| 69 | + } | ||
| 70 | + }, | ||
| 71 | + zh: { | ||
| 72 | + repairSetting: { | ||
| 73 | + queryCondition: '查询条件', | ||
| 74 | + repairTypeNamePlaceholder: '请输入类型名称', | ||
| 75 | + repairWayPlaceholder: '请选择派单方式', | ||
| 76 | + repairSettingTypePlaceholder: '请选择报修设置类型', | ||
| 77 | + publicAreaPlaceholder: '请选择区域', | ||
| 78 | + returnVisitFlagPlaceholder: '请选择是否回访', | ||
| 79 | + search: '查询', | ||
| 80 | + reset: '重置', | ||
| 81 | + repairSettingTitle: '报修设置', | ||
| 82 | + documentation: '文档', | ||
| 83 | + add: '添加', | ||
| 84 | + typeName: '类型名称', | ||
| 85 | + repairSettingType: '报修设置类型', | ||
| 86 | + dispatchMethod: '派单方式', | ||
| 87 | + area: '区域', | ||
| 88 | + ownerDisplay: '业主端展示', | ||
| 89 | + notificationMethod: '通知方式', | ||
| 90 | + returnVisit: '是否回访', | ||
| 91 | + processingTime: '办理时长', | ||
| 92 | + timeoutWarning: '超时预警', | ||
| 93 | + createTime: '创建时间', | ||
| 94 | + operation: '操作', | ||
| 95 | + edit: '修改', | ||
| 96 | + bindRepairMaster: '绑定维修师傅', | ||
| 97 | + delete: '删除', | ||
| 98 | + explanation: '说明', | ||
| 99 | + save: '保存', | ||
| 100 | + cancel: '取消', | ||
| 101 | + confirmDeleteTitle: '请确认您的操作!', | ||
| 102 | + confirmDeleteContent: '确定删除报修设置', | ||
| 103 | + cancelDelete: '点错了', | ||
| 104 | + confirmDelete: '确认删除', | ||
| 105 | + addTitle: '添加报修设置', | ||
| 106 | + editTitle: '修改报修设置', | ||
| 107 | + settingType: '设置类型', | ||
| 108 | + publicArea: '公共区域', | ||
| 109 | + ownerDisplayPlaceholder: '必填,请选择是否在业主端展示', | ||
| 110 | + notificationMethodPlaceholder: '必填,请选择通知方式', | ||
| 111 | + returnVisitSetting: '回访设置', | ||
| 112 | + remarkPlaceholder: '选填,请填写说明', | ||
| 113 | + required: '必填', | ||
| 114 | + cleaningOrder: '保洁单', | ||
| 115 | + repairOrder: '维修单', | ||
| 116 | + grabOrder: '抢单', | ||
| 117 | + assign: '指派', | ||
| 118 | + polling: '轮训', | ||
| 119 | + nonHouse: '非房屋', | ||
| 120 | + house: '房屋', | ||
| 121 | + yes: '是', | ||
| 122 | + no: '否', | ||
| 123 | + sms: '短信', | ||
| 124 | + wechat: '微信', | ||
| 125 | + wechatWorkLicense: '微信+员工工牌', | ||
| 126 | + noFollowUp: '不回访', | ||
| 127 | + followUpAfterEvaluation: '已评价不回访', | ||
| 128 | + followUp: '回访', | ||
| 129 | + dispatchExplanation: '派单方式说明:', | ||
| 130 | + dispatchPoint1: '1、抢单:员工(报修类型下的师傅)自主抢单维修处理,比较实用于物业每单给维修是否提成的场景', | ||
| 131 | + dispatchPoint2: '2、指派:专门由客服派单员工(报修类型下的师傅)维修处理,一般物业的选择', | ||
| 132 | + dispatchPoint3: '3、轮训:由系统定时派单员工(报修类型下的师傅)维修处理', | ||
| 133 | + areaExplanation: '区域说明:', | ||
| 134 | + areaPoint1: '小区、楼栋、单元为非房屋类区域,房屋为房屋类区域', | ||
| 135 | + areaPoint2: '注意:一般业主房屋报修必须添加一个房屋类区域的类型才能正常报修', | ||
| 136 | + processingTimeUnit: '小时', | ||
| 137 | + timeoutWarningUnit: '分钟' | ||
| 138 | + } | ||
| 139 | + } | ||
| 140 | +} | ||
| 0 | \ No newline at end of file | 141 | \ No newline at end of file |
src/views/work/repairSettingList.vue
0 → 100644
| 1 | +<template> | ||
| 2 | + <div class="repair-setting-container"> | ||
| 3 | + <!-- 查询条件 --> | ||
| 4 | + <el-card class="search-card"> | ||
| 5 | + <div slot="header" class="flex justify-between"> | ||
| 6 | + <span>{{ $t('repairSetting.queryCondition') }}</span> | ||
| 7 | + </div> | ||
| 8 | + <el-row :gutter="20"> | ||
| 9 | + <el-col :span="5"> | ||
| 10 | + <el-input v-model="searchForm.repairTypeName" :placeholder="$t('repairSetting.repairTypeNamePlaceholder')" | ||
| 11 | + clearable /> | ||
| 12 | + </el-col> | ||
| 13 | + <el-col :span="5"> | ||
| 14 | + <el-select v-model="searchForm.repairWay" :placeholder="$t('repairSetting.repairWayPlaceholder')" | ||
| 15 | + style="width:100%"> | ||
| 16 | + <el-option :label="$t('common.all')" value=""></el-option> | ||
| 17 | + <el-option v-for="item in repairWays" :key="item.statusCd" :label="item.name" :value="item.statusCd" /> | ||
| 18 | + </el-select> | ||
| 19 | + </el-col> | ||
| 20 | + <el-col :span="5"> | ||
| 21 | + <el-select v-model="searchForm.repairSettingType" | ||
| 22 | + :placeholder="$t('repairSetting.repairSettingTypePlaceholder')" style="width:100%"> | ||
| 23 | + <el-option :label="$t('common.all')" value=""></el-option> | ||
| 24 | + <el-option v-for="item in repairSettingTypes" :key="item.statusCd" :label="item.name" | ||
| 25 | + :value="item.statusCd" /> | ||
| 26 | + </el-select> | ||
| 27 | + </el-col> | ||
| 28 | + <el-col :span="5"> | ||
| 29 | + <el-select v-model="searchForm.publicArea" :placeholder="$t('repairSetting.publicAreaPlaceholder')" | ||
| 30 | + style="width:100%"> | ||
| 31 | + <el-option :label="$t('common.all')" value=""></el-option> | ||
| 32 | + <el-option v-for="item in publicAreas" :key="item.statusCd" :label="item.name" :value="item.statusCd" /> | ||
| 33 | + </el-select> | ||
| 34 | + </el-col> | ||
| 35 | + <el-col :span="4"> | ||
| 36 | + <el-button type="primary" @click="handleSearch">{{ $t('repairSetting.search') }}</el-button> | ||
| 37 | + <el-button @click="handleReset">{{ $t('repairSetting.reset') }}</el-button> | ||
| 38 | + </el-col> | ||
| 39 | + </el-row> | ||
| 40 | + </el-card> | ||
| 41 | + | ||
| 42 | + <!-- 报修设置列表 --> | ||
| 43 | + <el-card class="list-card"> | ||
| 44 | + <div slot="header" class="flex justify-between"> | ||
| 45 | + <span>{{ $t('repairSetting.repairSettingTitle') }}</span> | ||
| 46 | + <div style="float: right"> | ||
| 47 | + <el-button type="text" @click="showDocumentation"> | ||
| 48 | + {{ $t('repairSetting.documentation') }} | ||
| 49 | + </el-button> | ||
| 50 | + <el-button type="primary" size="small" @click="openAddDialog"> | ||
| 51 | + {{ $t('repairSetting.add') }} | ||
| 52 | + </el-button> | ||
| 53 | + </div> | ||
| 54 | + </div> | ||
| 55 | + | ||
| 56 | + <el-table v-loading="loading" :data="tableData" border style="width: 100%"> | ||
| 57 | + <el-table-column prop="repairTypeName" :label="$t('repairSetting.typeName')" align="center" /> | ||
| 58 | + <el-table-column prop="repairSettingTypeName" :label="$t('repairSetting.repairSettingType')" align="center" /> | ||
| 59 | + <el-table-column prop="repairWayName" :label="$t('repairSetting.dispatchMethod')" align="center" /> | ||
| 60 | + <el-table-column prop="publicArea" :label="$t('repairSetting.area')" align="center"> | ||
| 61 | + <template slot-scope="scope"> | ||
| 62 | + {{ scope.row.publicArea === 'T' ? $t('repairSetting.nonHouse') : $t('repairSetting.house') }} | ||
| 63 | + </template> | ||
| 64 | + </el-table-column> | ||
| 65 | + <el-table-column prop="isShow" :label="$t('repairSetting.ownerDisplay')" align="center"> | ||
| 66 | + <template slot-scope="scope"> | ||
| 67 | + {{ scope.row.isShow === 'Y' ? $t('repairSetting.yes') : $t('repairSetting.no') }} | ||
| 68 | + </template> | ||
| 69 | + </el-table-column> | ||
| 70 | + <el-table-column prop="notifyWay" :label="$t('repairSetting.notificationMethod')" align="center"> | ||
| 71 | + <template slot-scope="scope"> | ||
| 72 | + <span v-if="scope.row.notifyWay === 'SMS'">{{ $t('repairSetting.sms') }}</span> | ||
| 73 | + <span v-else-if="scope.row.notifyWay === 'WORK_LICENSE'">{{ $t('repairSetting.wechatWorkLicense') }}</span> | ||
| 74 | + <span v-else>{{ $t('repairSetting.wechat') }}</span> | ||
| 75 | + </template> | ||
| 76 | + </el-table-column> | ||
| 77 | + <el-table-column prop="returnVisitFlagName" :label="$t('repairSetting.returnVisit')" align="center" /> | ||
| 78 | + <el-table-column prop="doTime" :label="$t('repairSetting.processingTime')" align="center"> | ||
| 79 | + <template slot-scope="scope"> | ||
| 80 | + {{ scope.row.doTime }}{{ $t('repairSetting.processingTimeUnit') }} | ||
| 81 | + </template> | ||
| 82 | + </el-table-column> | ||
| 83 | + <el-table-column prop="warningTime" :label="$t('repairSetting.timeoutWarning')" align="center"> | ||
| 84 | + <template slot-scope="scope"> | ||
| 85 | + {{ scope.row.warningTime }}{{ $t('repairSetting.timeoutWarningUnit') }} | ||
| 86 | + </template> | ||
| 87 | + </el-table-column> | ||
| 88 | + <el-table-column prop="createTime" :label="$t('repairSetting.createTime')" align="center" /> | ||
| 89 | + <el-table-column :label="$t('repairSetting.operation')" align="center" width="300"> | ||
| 90 | + <template slot-scope="scope"> | ||
| 91 | + <el-button size="mini" @click="openEditDialog(scope.row)"> | ||
| 92 | + {{ $t('repairSetting.edit') }} | ||
| 93 | + </el-button> | ||
| 94 | + <el-button size="mini" @click="bindRepairMaster(scope.row)"> | ||
| 95 | + {{ $t('repairSetting.bindRepairMaster') }} | ||
| 96 | + </el-button> | ||
| 97 | + <el-button size="mini" type="danger" @click="openDeleteDialog(scope.row)"> | ||
| 98 | + {{ $t('repairSetting.delete') }} | ||
| 99 | + </el-button> | ||
| 100 | + </template> | ||
| 101 | + </el-table-column> | ||
| 102 | + </el-table> | ||
| 103 | + | ||
| 104 | + <!-- 分页和说明 --> | ||
| 105 | + <el-row :gutter="20" class="margin-top-xs"> | ||
| 106 | + <el-col :span="18"> | ||
| 107 | + <div class="explanation-section"> | ||
| 108 | + <p><strong>{{ $t('repairSetting.dispatchExplanation') }}</strong></p> | ||
| 109 | + <p>{{ $t('repairSetting.dispatchPoint1') }}</p> | ||
| 110 | + <p>{{ $t('repairSetting.dispatchPoint2') }}</p> | ||
| 111 | + <p>{{ $t('repairSetting.dispatchPoint3') }}</p> | ||
| 112 | + <p><strong>{{ $t('repairSetting.areaExplanation') }}</strong></p> | ||
| 113 | + <p>{{ $t('repairSetting.areaPoint1') }}</p> | ||
| 114 | + <p>{{ $t('repairSetting.areaPoint2') }}</p> | ||
| 115 | + </div> | ||
| 116 | + </el-col> | ||
| 117 | + <el-col :span="6"> | ||
| 118 | + <el-pagination background :current-page.sync="pagination.current" :page-sizes="[10, 20, 30, 50]" | ||
| 119 | + :page-size="pagination.size" :total="pagination.total" layout="total, sizes, prev, pager, next, jumper" | ||
| 120 | + @size-change="handleSizeChange" @current-change="handleCurrentChange" /> | ||
| 121 | + </el-col> | ||
| 122 | + </el-row> | ||
| 123 | + </el-card> | ||
| 124 | + | ||
| 125 | + <!-- 子组件 --> | ||
| 126 | + <add-repair-setting ref="addDialog" @success="fetchData" /> | ||
| 127 | + <edit-repair-setting ref="editDialog" @success="fetchData" /> | ||
| 128 | + <delete-repair-setting ref="deleteDialog" @success="fetchData" /> | ||
| 129 | + </div> | ||
| 130 | +</template> | ||
| 131 | + | ||
| 132 | +<script> | ||
| 133 | +import { listRepairSettings } from '@/api/work/repairSettingApi' | ||
| 134 | +import AddRepairSetting from '@/components/work/AddRepairSetting' | ||
| 135 | +import EditRepairSetting from '@/components/work/EditRepairSetting' | ||
| 136 | +import DeleteRepairSetting from '@/components/work/DeleteRepairSetting' | ||
| 137 | +import {getDict} from '@/api/community/communityApi' | ||
| 138 | + | ||
| 139 | +export default { | ||
| 140 | + name: 'RepairSettingList', | ||
| 141 | + components: { | ||
| 142 | + AddRepairSetting, | ||
| 143 | + EditRepairSetting, | ||
| 144 | + DeleteRepairSetting | ||
| 145 | + }, | ||
| 146 | + data() { | ||
| 147 | + return { | ||
| 148 | + loading: false, | ||
| 149 | + searchForm: { | ||
| 150 | + repairTypeName: '', | ||
| 151 | + repairWay: '', | ||
| 152 | + repairSettingType: '', | ||
| 153 | + publicArea: '', | ||
| 154 | + returnVisitFlag: '' | ||
| 155 | + }, | ||
| 156 | + tableData: [], | ||
| 157 | + repairWays: [], | ||
| 158 | + repairSettingTypes: [], | ||
| 159 | + publicAreas: [], | ||
| 160 | + returnVisitFlags: [], | ||
| 161 | + pagination: { | ||
| 162 | + current: 1, | ||
| 163 | + size: 10, | ||
| 164 | + total: 0 | ||
| 165 | + } | ||
| 166 | + } | ||
| 167 | + }, | ||
| 168 | + created() { | ||
| 169 | + this.fetchData() | ||
| 170 | + this.loadDictData() | ||
| 171 | + }, | ||
| 172 | + methods: { | ||
| 173 | + async fetchData() { | ||
| 174 | + this.loading = true | ||
| 175 | + try { | ||
| 176 | + const params = { | ||
| 177 | + page: this.pagination.current, | ||
| 178 | + row: this.pagination.size, | ||
| 179 | + ...this.searchForm | ||
| 180 | + } | ||
| 181 | + | ||
| 182 | + const { data, records } = await listRepairSettings(params) | ||
| 183 | + this.tableData = data | ||
| 184 | + this.pagination.total = records | ||
| 185 | + } catch (error) { | ||
| 186 | + console.error('获取报修设置列表失败:', error) | ||
| 187 | + this.$message.error(this.$t('common.fetchError')) | ||
| 188 | + } finally { | ||
| 189 | + this.loading = false | ||
| 190 | + } | ||
| 191 | + }, | ||
| 192 | + | ||
| 193 | + async loadDictData() { | ||
| 194 | + try { | ||
| 195 | + this.repairWays = await getDict('r_repair_setting', 'repair_way') | ||
| 196 | + this.repairSettingTypes = await getDict('r_repair_setting', 'repair_setting_type') | ||
| 197 | + this.publicAreas = await getDict('r_repair_setting', 'public_area') | ||
| 198 | + this.returnVisitFlags = await getDict('r_repair_setting', 'return_visit_flag') | ||
| 199 | + } catch (error) { | ||
| 200 | + console.error('加载字典数据失败:', error) | ||
| 201 | + } | ||
| 202 | + }, | ||
| 203 | + | ||
| 204 | + handleSearch() { | ||
| 205 | + this.pagination.current = 1 | ||
| 206 | + this.fetchData() | ||
| 207 | + }, | ||
| 208 | + | ||
| 209 | + handleReset() { | ||
| 210 | + this.searchForm = { | ||
| 211 | + repairTypeName: '', | ||
| 212 | + repairWay: '', | ||
| 213 | + repairSettingType: '', | ||
| 214 | + publicArea: '', | ||
| 215 | + returnVisitFlag: '' | ||
| 216 | + } | ||
| 217 | + this.handleSearch() | ||
| 218 | + }, | ||
| 219 | + | ||
| 220 | + handleSizeChange(size) { | ||
| 221 | + this.pagination.size = size | ||
| 222 | + this.fetchData() | ||
| 223 | + }, | ||
| 224 | + | ||
| 225 | + handleCurrentChange(current) { | ||
| 226 | + this.pagination.current = current | ||
| 227 | + this.fetchData() | ||
| 228 | + }, | ||
| 229 | + | ||
| 230 | + openAddDialog() { | ||
| 231 | + this.$refs.addDialog.open() | ||
| 232 | + }, | ||
| 233 | + | ||
| 234 | + openEditDialog(row) { | ||
| 235 | + this.$refs.editDialog.open(row) | ||
| 236 | + }, | ||
| 237 | + | ||
| 238 | + openDeleteDialog(row) { | ||
| 239 | + this.$refs.deleteDialog.open(row) | ||
| 240 | + }, | ||
| 241 | + | ||
| 242 | + bindRepairMaster(row) { | ||
| 243 | + // 跳转到绑定维修师傅页面 | ||
| 244 | + this.$router.push({ | ||
| 245 | + path: '/views/work/repairTypeUser', | ||
| 246 | + query: { | ||
| 247 | + settingId: row.settingId, | ||
| 248 | + repairType: row.repairType, | ||
| 249 | + repairTypeName: row.repairTypeName | ||
| 250 | + } | ||
| 251 | + }) | ||
| 252 | + }, | ||
| 253 | + | ||
| 254 | + showDocumentation() { | ||
| 255 | + // 显示文档逻辑 | ||
| 256 | + console.log('Show documentation') | ||
| 257 | + } | ||
| 258 | + } | ||
| 259 | +} | ||
| 260 | +</script> | ||
| 261 | + | ||
| 262 | +<style lang="scss" scoped> | ||
| 263 | +.repair-setting-container { | ||
| 264 | + padding: 20px; | ||
| 265 | + | ||
| 266 | + .search-card { | ||
| 267 | + margin-bottom: 20px; | ||
| 268 | + } | ||
| 269 | + | ||
| 270 | + .list-card { | ||
| 271 | + margin-bottom: 20px; | ||
| 272 | + } | ||
| 273 | + | ||
| 274 | + .margin-top-xs { | ||
| 275 | + margin-top: 20px; | ||
| 276 | + } | ||
| 277 | + | ||
| 278 | + .explanation-section { | ||
| 279 | + background-color: #f8f9fa; | ||
| 280 | + padding: 15px; | ||
| 281 | + border-radius: 4px; | ||
| 282 | + font-size: 14px; | ||
| 283 | + line-height: 1.6; | ||
| 284 | + | ||
| 285 | + p { | ||
| 286 | + margin-bottom: 8px; | ||
| 287 | + } | ||
| 288 | + } | ||
| 289 | +} | ||
| 290 | +</style> | ||
| 0 | \ No newline at end of file | 291 | \ No newline at end of file |
src/views/work/repairTypeUserLang.js
0 → 100644
| 1 | +export const messages = { | ||
| 2 | + en: { | ||
| 3 | + repairTypeUser: { | ||
| 4 | + title: 'Repair Master', | ||
| 5 | + repairMasterId: 'Repair Master ID', | ||
| 6 | + masterName: 'Master Name', | ||
| 7 | + repairType: 'Repair Type', | ||
| 8 | + status: 'Status', | ||
| 9 | + description: 'Description', | ||
| 10 | + createTime: 'Create Time', | ||
| 11 | + operation: 'Operation', | ||
| 12 | + repairTypeRequired: 'Repair type is required' | ||
| 13 | + }, | ||
| 14 | + selectStaff: { | ||
| 15 | + title: 'Select Staff', | ||
| 16 | + orgInfo: 'Organization Information', | ||
| 17 | + staffInfo: 'Staff Information', | ||
| 18 | + selectStaffFirst: 'Please select a staff first' | ||
| 19 | + }, | ||
| 20 | + deleteRepairTypeUser: { | ||
| 21 | + title: 'Confirm Operation', | ||
| 22 | + confirmDelete: 'Are you sure to delete this repair master?' | ||
| 23 | + }, | ||
| 24 | + editRepairTypeUser: { | ||
| 25 | + title: 'Modify Repair Master', | ||
| 26 | + status: 'Status', | ||
| 27 | + description: 'Description', | ||
| 28 | + online: 'Online', | ||
| 29 | + offline: 'Offline', | ||
| 30 | + descriptionPlaceholder: 'Optional, please enter description', | ||
| 31 | + statusRequired: 'Status is required' | ||
| 32 | + } | ||
| 33 | + }, | ||
| 34 | + zh: { | ||
| 35 | + repairTypeUser: { | ||
| 36 | + title: '报修师傅', | ||
| 37 | + repairMasterId: '维修师傅ID', | ||
| 38 | + masterName: '师傅名称', | ||
| 39 | + repairType: '报修类型', | ||
| 40 | + status: '状态', | ||
| 41 | + description: '说明', | ||
| 42 | + createTime: '创建时间', | ||
| 43 | + operation: '操作', | ||
| 44 | + repairTypeRequired: '未包含报修类型' | ||
| 45 | + }, | ||
| 46 | + selectStaff: { | ||
| 47 | + title: '选择员工', | ||
| 48 | + orgInfo: '组织信息', | ||
| 49 | + staffInfo: '员工信息', | ||
| 50 | + selectStaffFirst: '请先选择员工' | ||
| 51 | + }, | ||
| 52 | + deleteRepairTypeUser: { | ||
| 53 | + title: '请确认您的操作', | ||
| 54 | + confirmDelete: '确定删除报修师傅?' | ||
| 55 | + }, | ||
| 56 | + editRepairTypeUser: { | ||
| 57 | + title: '变更报修师傅', | ||
| 58 | + status: '状态', | ||
| 59 | + description: '说明', | ||
| 60 | + online: '在线', | ||
| 61 | + offline: '离线', | ||
| 62 | + descriptionPlaceholder: '选填,请填写说明', | ||
| 63 | + statusRequired: '状态不能为空' | ||
| 64 | + } | ||
| 65 | + } | ||
| 66 | +} | ||
| 0 | \ No newline at end of file | 67 | \ No newline at end of file |
src/views/work/repairTypeUserList.vue
0 → 100644
| 1 | +<template> | ||
| 2 | + <div> | ||
| 3 | + <el-row> | ||
| 4 | + <el-col :span="24"> | ||
| 5 | + <el-card class="box-card"> | ||
| 6 | + <div slot="header" class="clearfix"> | ||
| 7 | + <h5>{{ $t('repairTypeUser.title') }}</h5> | ||
| 8 | + <div class="ibox-tools" style="top:10px;"> | ||
| 9 | + <el-button type="primary" size="small" @click="_goBack"> | ||
| 10 | + <i class="el-icon-close"></i>{{ $t('common.back') }} | ||
| 11 | + </el-button> | ||
| 12 | + <el-button type="primary" size="small" @click="_openAddRepairTypeUserModal"> | ||
| 13 | + <i class="el-icon-plus"></i>{{ $t('common.add') }} | ||
| 14 | + </el-button> | ||
| 15 | + </div> | ||
| 16 | + </div> | ||
| 17 | + <div class="ibox-content"> | ||
| 18 | + <el-table :data="repairTypeUserManageInfo.repairTypeUsers" style="width: 100%" border stripe> | ||
| 19 | + <el-table-column prop="staffId" :label="$t('repairTypeUser.repairMasterId')" align="center" /> | ||
| 20 | + <el-table-column prop="staffName" :label="$t('repairTypeUser.masterName')" align="center" /> | ||
| 21 | + <el-table-column prop="repairTypeName" :label="$t('repairTypeUser.repairType')" align="center" /> | ||
| 22 | + <el-table-column prop="stateName" :label="$t('repairTypeUser.status')" align="center" /> | ||
| 23 | + <el-table-column prop="remark" :label="$t('repairTypeUser.description')" align="center" /> | ||
| 24 | + <el-table-column prop="createTime" :label="$t('repairTypeUser.createTime')" align="center" /> | ||
| 25 | + <el-table-column :label="$t('common.operation')" align="center"> | ||
| 26 | + <template slot-scope="scope"> | ||
| 27 | + <el-button-group> | ||
| 28 | + <el-button size="mini" @click="_openDeleteTypeUserModel(scope.row)"> | ||
| 29 | + {{ $t('common.delete') }} | ||
| 30 | + </el-button> | ||
| 31 | + <el-button size="mini" @click="_openEditrepairTypeUserModel(scope.row)"> | ||
| 32 | + {{ $t('common.change') }} | ||
| 33 | + </el-button> | ||
| 34 | + </el-button-group> | ||
| 35 | + </template> | ||
| 36 | + </el-table-column> | ||
| 37 | + </el-table> | ||
| 38 | + <el-pagination :current-page="currentPage" :page-sizes="[10, 20, 30, 50]" :page-size="pageSize" | ||
| 39 | + layout="total, sizes, prev, pager, next, jumper" :total="repairTypeUserManageInfo.total" | ||
| 40 | + @size-change="handleSizeChange" @current-change="handleCurrentChange" /> | ||
| 41 | + </div> | ||
| 42 | + </el-card> | ||
| 43 | + </el-col> | ||
| 44 | + </el-row> | ||
| 45 | + | ||
| 46 | + <SelectStaff ref="selectStaff" /> | ||
| 47 | + <DeleteRepairTypeUser ref="deleteRepairTypeUser" @success="handleDeleteSuccess" /> | ||
| 48 | + <EditRepairTypeUser ref="editRepairTypeUser" @success="handleEditSuccess" /> | ||
| 49 | + </div> | ||
| 50 | +</template> | ||
| 51 | + | ||
| 52 | +<script> | ||
| 53 | +import { listRepairTypeUsers, saveRepairTypeUser } from '@/api/work/repairTypeUserApi' | ||
| 54 | +import { getCommunityId } from '@/api/community/communityApi' | ||
| 55 | +import SelectStaff from '@/components/work/SelectStaff' | ||
| 56 | +import DeleteRepairTypeUser from '@/components/work/DeleteRepairTypeUser' | ||
| 57 | +import EditRepairTypeUser from '@/components/work/EditRepairTypeUser' | ||
| 58 | + | ||
| 59 | +export default { | ||
| 60 | + name: 'RepairTypeUserList', | ||
| 61 | + components: { | ||
| 62 | + SelectStaff, | ||
| 63 | + DeleteRepairTypeUser, | ||
| 64 | + EditRepairTypeUser | ||
| 65 | + }, | ||
| 66 | + data() { | ||
| 67 | + return { | ||
| 68 | + repairTypeUserManageInfo: { | ||
| 69 | + repairTypeUsers: [], | ||
| 70 | + total: 0, | ||
| 71 | + records: 1, | ||
| 72 | + repairType: '', | ||
| 73 | + conditions: { | ||
| 74 | + repairTypeName: '', | ||
| 75 | + repairWay: '', | ||
| 76 | + repairType: '' | ||
| 77 | + } | ||
| 78 | + }, | ||
| 79 | + currentPage: 1, | ||
| 80 | + pageSize: 10 | ||
| 81 | + } | ||
| 82 | + }, | ||
| 83 | + created() { | ||
| 84 | + this.repairTypeUserManageInfo.repairType = this.$route.query.repairType | ||
| 85 | + this._listRepairTypeUsers(this.currentPage, this.pageSize) | ||
| 86 | + }, | ||
| 87 | + methods: { | ||
| 88 | + async _listRepairTypeUsers(page, size) { | ||
| 89 | + try { | ||
| 90 | + const communityId = await getCommunityId() | ||
| 91 | + const params = { | ||
| 92 | + page: page, | ||
| 93 | + row: size, | ||
| 94 | + communityId: communityId, | ||
| 95 | + repairType: this.repairTypeUserManageInfo.repairType | ||
| 96 | + } | ||
| 97 | + | ||
| 98 | + const response = await listRepairTypeUsers(params) | ||
| 99 | + if (response.code === 0) { | ||
| 100 | + this.repairTypeUserManageInfo.repairTypeUsers = response.data | ||
| 101 | + this.repairTypeUserManageInfo.total = response.total | ||
| 102 | + } else { | ||
| 103 | + this.$message.error(response.msg || this.$t('common.requestFailed')) | ||
| 104 | + } | ||
| 105 | + } catch (error) { | ||
| 106 | + console.error('Error fetching repair type users:', error) | ||
| 107 | + this.$message.error(this.$t('common.requestFailed')) | ||
| 108 | + } | ||
| 109 | + }, | ||
| 110 | + handleSizeChange(val) { | ||
| 111 | + this.pageSize = val | ||
| 112 | + this._listRepairTypeUsers(this.currentPage, val) | ||
| 113 | + }, | ||
| 114 | + handleCurrentChange(val) { | ||
| 115 | + this.currentPage = val | ||
| 116 | + this._listRepairTypeUsers(val, this.pageSize) | ||
| 117 | + }, | ||
| 118 | + _openAddRepairTypeUserModal() { | ||
| 119 | + this.$refs.selectStaff.open({ | ||
| 120 | + call: (staff) => { | ||
| 121 | + this.saveRepairTypeUserInfo(staff) | ||
| 122 | + } | ||
| 123 | + }) | ||
| 124 | + }, | ||
| 125 | + _openEditrepairTypeUserModel(row) { | ||
| 126 | + this.$refs.editRepairTypeUser.open(row) | ||
| 127 | + }, | ||
| 128 | + _openDeleteTypeUserModel(row) { | ||
| 129 | + this.$refs.deleteRepairTypeUser.open(row) | ||
| 130 | + }, | ||
| 131 | + _goBack() { | ||
| 132 | + this.$router.go(-1) | ||
| 133 | + }, | ||
| 134 | + async saveRepairTypeUserInfo(staff) { | ||
| 135 | + try { | ||
| 136 | + const communityId = await getCommunityId() | ||
| 137 | + const data = { | ||
| 138 | + communityId: communityId, | ||
| 139 | + staffId: staff.staffId, | ||
| 140 | + staffName: staff.staffName, | ||
| 141 | + repairType: this.repairTypeUserManageInfo.repairType | ||
| 142 | + } | ||
| 143 | + | ||
| 144 | + const response = await saveRepairTypeUser(data) | ||
| 145 | + if (response.code === 0) { | ||
| 146 | + this.$message.success(this.$t('common.saveSuccess')) | ||
| 147 | + this._listRepairTypeUsers(this.currentPage, this.pageSize) | ||
| 148 | + } else { | ||
| 149 | + this.$message.error(response.msg || this.$t('common.saveFailed')) | ||
| 150 | + } | ||
| 151 | + } catch (error) { | ||
| 152 | + console.error('Error saving repair type user:', error) | ||
| 153 | + this.$message.error(this.$t('common.saveFailed')) | ||
| 154 | + } | ||
| 155 | + }, | ||
| 156 | + handleDeleteSuccess() { | ||
| 157 | + this._listRepairTypeUsers(this.currentPage, this.pageSize) | ||
| 158 | + }, | ||
| 159 | + handleEditSuccess() { | ||
| 160 | + this._listRepairTypeUsers(this.currentPage, this.pageSize) | ||
| 161 | + } | ||
| 162 | + } | ||
| 163 | +} | ||
| 164 | +</script> | ||
| 165 | + | ||
| 166 | +<style scoped> | ||
| 167 | +.ibox-tools { | ||
| 168 | + position: absolute; | ||
| 169 | + right: 15px; | ||
| 170 | + top: 10px; | ||
| 171 | +} | ||
| 172 | + | ||
| 173 | +.clearfix { | ||
| 174 | + position: relative; | ||
| 175 | +} | ||
| 176 | +</style> | ||
| 0 | \ No newline at end of file | 177 | \ No newline at end of file |